在 Kubernetes 日常运维中,管理员通常习惯在 Master 节点上使用 kubectl 命令管理集群。然而,当尝试在其他节点或集群外部执行 kubectl 时,经常会遇到连接失败的报错。这种问题的根源,绝大多数情况下都指向了 kubeconfig 配置文件。
许多 kubectl 使用问题,本质上源于对其工作原理不够清晰。本文将深入解析 kubectl 的工作机制,并通过两个高频的实战案例,帮助你理解为何“不在集群内”也能操作集群。
案例一:在其他 Kubernetes 节点上执行 kubectl 失败
问题现象
在非首个 Master 节点的其他节点上执行基础命令:
kubectl get nodes
通常会返回类似以下的错误信息:
The connection to the server localhost:8080 was refused - did you specify the right host or port?
此时,许多人的第一反应是检查 API Server 服务状态、节点网络连通性等。但这恰恰是常见的排错误区。
问题本质与快速解决方案
kubectl 本质上是一个 Kubernetes API 的客户端工具。它的核心工作是:依据 kubeconfig 文件的配置,向 API Server 的端点(通常是 6443 端口)发起 HTTP(S) 请求。
当 kubectl 无法找到任何有效的 kubeconfig 配置时,它会回退到一个早已废弃的默认行为(源于 Kubernetes 早期单机无认证版本):尝试访问 http://localhost:8080。因此,你看到的“连接被拒绝”错误,实际上是客户端没有找到正确配置,而非服务端问题。
解决此问题的方法非常简单:从可以正常执行 kubectl 的 Master 节点,将配置文件复制到目标节点。
# 1. 在目标节点创建配置目录
ssh root@k8s-node1 mkdir -p /root/.kube
# 2. 复制 kubeconfig 文件
scp /root/.kube/config root@k8s-node1:/root/.kube/config
# 3. 设置正确的文件权限
ssh root@k8s-node1 chmod 600 /root/.kube/config
完成以上步骤后,即可在目标节点正常执行 kubectl get nodes 等命令。
案例二:在 Kubernetes 集群外部执行 kubectl
这个场景在生产环境中更为常见,也更容易产生误解。例如,在单独的 Jenkins 服务器或 Harbor 仓库服务器上管理集群。
一个普遍的疑问是:“这台机器并非 Kubernetes 节点,kubectl 怎么可能工作?” 事实上,kubectl 的权限完全由 kubeconfig 文件控制,与其是否运行 kubelet、是否在集群网络内部无关。只要满足以下两个条件即可:
- 能够通过网络访问到 API Server(通常需要开通对 6443 端点的网络访问)。
kubeconfig 文件中包含的证书或 Token 是有效且具备相应权限的。
下面演示在集群外的一台机器(例如 Harbor 服务器)上配置 kubectl。
步骤一:安装 kubectl 客户端
# 下载最新稳定版本的 kubectl
curl -LO https://dl.k8s.io/release/stable.txt
curl -LO https://dl.k8s.io/release/$(cat stable.txt)/bin/linux/amd64/kubectl
# 赋予执行权限并移动到 PATH
chmod +x kubectl
mv kubectl /usr/local/bin/
步骤二:拷贝并配置 kubeconfig
从集群的 Master 节点复制配置文件到当前机器:
# 创建配置目录
ssh root@10.0.0.207 mkdir -p /root/.kube
# 复制配置文件
scp /root/.kube/config root@10.0.0.207:/root/.kube/config
# 设置权限
ssh root@10.0.0.207 chmod 600 /root/.kube/config
步骤三:验证集群管理能力
在集群外的这台机器上执行:
kubectl get nodes
如果配置正确,你将能看到完整的集群节点列表。这证明这台完全不属于 Kubernetes 集群的机器已经具备了管理集群的能力。
深入理解:kubectl 如何查找配置文件
kubectl 在启动时会按照以下顺序查找 kubeconfig 配置:
- 最高优先级:使用
--kubeconfig 参数显式指定配置文件路径。
- 环境变量:查找
KUBECONFIG 环境变量指向的路径。
- 默认路径:如果以上均未设置,则读取用户家目录下的
~/.kube/config 文件。
如果上述三个位置均未找到有效配置,kubectl 就会回退到尝试连接 http://localhost:8080,这也是导致大部分连接失败问题的根本原因。
核心结论:kubectl 能否正常工作,不取决于它是否运行在集群节点上,只取决于它是否能加载到正确的 kubeconfig 配置文件。
生产环境建议:出于安全考虑,应避免在多个节点长期保存 kubeconfig 文件。仅在进行临时调试或特定运维操作时按需分发,并在使用完毕后及时清理。