Administrator
Administrator
发布于 2026-10-28 / 1 阅读
0
0

Kubernetes 故障排查(01):kubectl 连不上集群:先分清连接、证书与身份问题

面向初级运维,使用 Linux 节点和稳定 Kubernetes API。命令按 Bash 编写。本文为教学故障场景,日志及结果为示意,不冒充生产实测;执行前确认 context、命名空间和权限。

一、遭遇情况:昨天还能用,今天 get pods 就报错

运维人员登录跳板机,执行 kubectl get pods,却收到连接拒绝、超时,或者 x509 错误。有人准备重启控制面,还有人建议加 --insecure-skip-tls-verify。

本篇案例设定为:当前 context 指向已经下线的测试集群地址。集群本身未必损坏,是客户端选择的目标错了。排查必须从目标开始,否则可能在正常集群上做一轮无关操作。

二、原因分析:一次 kubectl 请求要经过几层

客户端先从 kubeconfig 选择 context,再找到 API Server 地址与认证方式,建立网络和 TLS 连接,完成身份认证,最后判断是否有权限访问目标资源。

kubectl 请求失败的分层路径

典型现象 第一排查方向
connection refused 地址、端口、服务监听与中间转发
i/o timeout、请求超时 路由、防火墙、代理、入口响应
x509、证书过期或名称不匹配 信任链、时间、地址与证书
Unauthorized 凭据、令牌、认证插件
Forbidden 当前身份的授权,见第 2 篇

错误包含 localhost:8080 时,也要检查是否根本没加载到有效配置,不能直接认定控制面真的应该监听这个地址。

三、排查思路:先查配置,再查通路

1. 明确 context 和服务地址

kubectl config current-context
kubectl config get-contexts
kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}{"\n"}'
printf '%s\n' "${KUBECONFIG:-using-default-kubeconfig}"
kubectl version --client

context 关联集群、身份和默认命名空间。KUBECONFIG 可能合并多个文件;命令里的 --kubeconfig 和 --context 又会改变选择。不要仅因为 SSH 主机没换,就认定操作目标没换。

不用 --raw 导出完整凭据去公开求助,也不要把管理员 kubeconfig 当作普通日志附件。只读故障也可能因为访问了错误集群而误判。

2. 带有限超时访问 API

kubectl --request-timeout=5s get --raw=/version
kubectl --request-timeout=5s get namespaces
date -Is

/version 成功不代表拥有业务资源权限;读取 namespaces 被拒绝,也不代表整个 API 不可达。按实际返回区分网络、身份和授权,不要把不同请求合成一句“集群不通”。

确认地址后,可以从这台客户端机器检查目标域名解析和端口路径。遇到证书错误,应比较系统时间、配置的 server 域名和证书有效期,按集群提供方流程更新凭据,不应关闭验证来掩盖问题。

四、实践:用独立配置观察错误,避免改坏现有配置

这个实验只创建一个本地临时 kubeconfig,不修改真实集群,也不读取真实凭据。要求本机有 kubectl,且本机 TCP 9 端口未提供对应 API 服务:

lab_dir=$(mktemp -d /tmp/kt01.XXXXXX)
kubectl --kubeconfig "$lab_dir/config" config set-cluster unreachable --server=https://127.0.0.1:9
kubectl --kubeconfig "$lab_dir/config" config set-context demo --cluster=unreachable
kubectl --kubeconfig "$lab_dir/config" config use-context demo
kubectl --kubeconfig "$lab_dir/config" --request-timeout=3s get pods

最后一条预期连接失败。接着读取这个独立文件的 server:

kubectl --kubeconfig "$lab_dir/config" config view --minify -o jsonpath='{.clusters[0].cluster.server}{"\n"}'
kubectl config current-context

可以看到故障目标是本机 9 端口,原来的默认 context 没被这组命令切换。实验说明:先确认目标,比立刻去服务器重启组件更重要。

五、修复实践:按证据修正对应层

如果只是选错 context,先核对运维文档中的集群身份,再用已有且确认正确的 context 发起只读请求,例如 kubectl --context 正确名称 get pods -n 正确命名空间。确认后再决定是否切换默认 context。

若配置地址已经过期,从集群管理员或云平台获取新的受控配置;若认证插件失效,修复插件或刷新登录;若 TLS 证书本身过期,区分客户端凭据和控制面证书,由对应管理流程处理。

只有证据表明多个客户端访问同一正确地址都失败,才进一步检查入口与控制面。单个跳板机失败时,不宜先重启所有控制面组件。

六、验证与总结

验证时确认三件事:访问的是预期集群;目标命名空间的只读操作成功;原始报错没有继续出现。能列出 namespaces 不等于有权发布应用,后续操作仍要按资源权限判断。

本系列其他实验使用 ktXX 专用命名空间、练习对象和 ClusterIP 服务。执行变更前仍应先确认 context;受准入策略约束时采用组织批准的镜像与安全配置,不要为了复现去关闭集群策略。实验对象不应与真实业务重名。

先目标、再网络与信任、再身份和权限,是后面所有排查的入口。把错误所在层找清楚,才能避免拿一个客户端问题去折腾整个集群。

官方参考

系列目录

  1. kubectl 连不上集群:先分清连接、证书与身份问题
  2. Forbidden:会登录集群,为什么还是不能看 Pod 日志
  3. Pod 一直 Pending:先看调度事件,不先猜资源不足
  4. ImagePullBackOff:从节点视角排查镜像拉取失败
  5. CreateContainerConfigError:容器还没启动,先检查配置引用
  6. CrashLoopBackOff:先看上一次退出,不先删 Pod
  7. OOMKilled 与 137:区分容器内存限制、节点压力和驱逐
  8. Pod Running 却 0/1 Ready:探针失败为什么不一定重启
  9. Service 访问失败:先查后端选择,再查端口和数据路径
  10. DNS 解析失败:先查命名空间和查询结果,不先重装 CoreDNS
  11. 连接超时却不是 DNS:NetworkPolicy 如何定位到来源和方向
  12. Ingress 返回 404、502 或 503:先找到响应来自哪一层
  13. PVC 一直 Pending:存储类、绑定时机和使用方要一起看
  14. 节点 NotReady:从 Node 条件追到 kubelet、运行时与 CNI
  15. Pod 显示 Evicted:别把节点驱逐当作普通容器重启
  16. Deployment 发布卡住:从 ProgressDeadlineExceeded 到可验证回滚

系列目录 · 下一篇


评论