Qingular

控制平面故障排查

·CKAk8s练习

CKA 考试 Domain 5 — API Server、Scheduler、Controller Manager、etcd 故障排查

← 返回 CKA 练习目录 控制平面是 Kubernetes 集群的大脑。CKA 考试中控制平面组件的故障排查常见于静态 Pod 配置、etcd 健康检查和组件重启等场景。


1. 控制平面组件概览

组件功能部署方式
kube-apiserver所有 API 请求的入口静态 Pod(/etc/kubernetes/manifests/)
kube-schedulerPod 调度决策静态 Pod
kube-controller-manager控制器管理静态 Pod
etcd集群数据存储静态 Pod
# 查看控制平面 Pod
kubectl get pods -n kube-system

# 查看静态 Pod 配置目录
ls /etc/kubernetes/manifests/
# kube-apiserver.yaml
# kube-scheduler.yaml
# kube-controller-manager.yaml
# etcd.yaml

2. API Server 故障排查

API Server 是集群的核心组件,无法访问时集群将完全无法工作。

检查 API Server 状态

# 检查 API Server Pod
kubectl get pods -n kube-system | grep apiserver

# 查看 API Server 日志
kubectl logs -n kube-system kube-apiserver-<node-name>
kubectl logs -n kube-system kube-apiserver-<node-name> --tail=100

# 如果 API Server 完全不可用,在 master 节点使用 Docker/containerd
crictl ps | grep apiserver
crictl logs <container-id>

静态 Pod 配置修复

# 检查静态 Pod 配置文件
cat /etc/kubernetes/manifests/kube-apiserver.yaml

# 常见问题:错误的证书路径、错误的 etcd 地址、错误的 service-cluster-ip-range
# 修改配置后,kubelet 会自动重新创建静态 Pod
vi /etc/kubernetes/manifests/kube-apiserver.yaml

API Server 不可用时的排查步骤

# Step 1: SSH 到 master 节点
ssh <master-node>

# Step 2: 检查静态 Pod 配置文件是否存在
ls -la /etc/kubernetes/manifests/kube-apiserver.yaml

# Step 3: 检查 kubelet 是否运行
systemctl status kubelet

# Step 4: 检查容器运行时
crictl ps | grep apiserver

# Step 5: 查看 kubelet 日志定位问题
journalctl -u kubelet -n 50 --no-pager

3. Scheduler 问题排查

Pod 未被调度

# 查看未调度的 Pod
kubectl get pods --all-namespaces | grep Pending

# 查看调度失败原因
kubectl describe pod <pod-name>
# Events:
#   FailedScheduling  30s  default-scheduler  0/2 nodes are available

# 查看 Scheduler 日志
kubectl logs -n kube-system kube-scheduler-<master-name>

常见调度问题

问题原因解决
Pod Pending节点资源不足增加节点或调整资源请求
Pod Pending节点有污点添加 tolerations
Pod Pending节点选择器不匹配修改 nodeSelector
Pod 未调度到期望节点权重或亲和性配置错误检查 affinity 配置

Scheduler 配置检查

# 检查 Scheduler 配置文件
cat /etc/kubernetes/manifests/kube-scheduler.yaml

# 检查 Scheduler 启动参数
kubectl get pods -n kube-system kube-scheduler-<master-name> -o yaml

4. Controller Manager 问题排查

# 查看 Controller Manager 日志
kubectl logs -n kube-system kube-controller-manager-<master-name> --tail=50

# 检查 Controller Manager 配置
cat /etc/kubernetes/manifests/kube-controller-manager.yaml

# 检查控制循环是否正常
# 日志中应有:replicaset, deployment, node, serviceaccount 等控制器的正常输出

常见问题:

  • Node Controller 未正确标记节点状态
  • Deployment Controller 未创建 ReplicaSet
  • Service Account Controller 未创建 Token

5. etcd 成员健康检查

# 方法 1:使用 etcdctl
# 注意:etcdctl 需要设置端点、证书等环境变量

# 查看 etcd 端点健康状态
kubectl exec -it -n kube-system etcd-<master-name> -- \
  etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  endpoint health --cluster

# 查看 etcd 成员列表
kubectl exec -it -n kube-system etcd-<master-name> -- \
  etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  member list

# 检查 etcd 日志
kubectl logs -n kube-system etcd-<master-name> --tail=100

健康检查输出示例:

https://192.168.1.10:2379 is healthy: successfully committed proposal: took = 2.345ms
https://192.168.1.11:2379 is healthy: successfully committed proposal: took = 3.012ms
https://192.168.1.12:2379 is healthy: successfully committed proposal: took = 1.987ms

6. etcd 数据目录满处理

# 检查 etcd 数据目录大小
du -sh /var/lib/etcd/

# 检查磁盘空间
df -h

# 压缩 etcd 数据(释放空间但不减少数据目录大小)
kubectl exec -it -n kube-system etcd-<master-name> -- \
  etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  compaction $(etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  endpoint status --write-out=json | jq -r '.[].Status.header.revision')

# 碎片整理(实际释放磁盘空间)
kubectl exec -it -n kube-system etcd-<master-name> -- \
  etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  defrag

# 清理 etcd 历史 compact 后的数据
# etcd 服务器会自动清理,或触发 manual compaction

7. 控制平面组件重启

# 方法 1:删除 Pod(静态 Pod 会被 kubelet 重新创建)
kubectl delete pod -n kube-system kube-apiserver-<master-name>
kubectl delete pod -n kube-system kube-scheduler-<master-name>
kubectl delete pod -n kube-system kube-controller-manager-<master-name>
kubectl delete pod -n kube-system etcd-<master-name>

# 方法 2:移动静态 Pod 配置文件(临时移除)
mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/
sleep 30
mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/

# 方法 3:修改静态 Pod 配置触发重启
# kubelet 会检测到文件变化并重新创建容器
vi /etc/kubernetes/manifests/kube-apiserver.yaml

注意:控制平面组件是静态 Pod,kubectl delete 不会真正删除它们,kubelet 会从 /etc/kubernetes/manifests/ 自动恢复。


8. 通用排查命令速查

# 查看所有控制平面组件状态
kubectl get pods -n kube-system

# 查看组件日志(最新 50 行)
kubectl logs -n kube-system <pod-name> --tail=50

# 查看组件事件
kubectl get events -n kube-system --sort-by='.lastTimestamp'

# 查看控制平面组件配置
kubectl get pods -n kube-system <pod-name> -o yaml

# 在 master 节点检查静态 Pod 目录
ls -la /etc/kubernetes/manifests/

9. 考试要点

  • 控制平面组件是静态 Pod,配置在 /etc/kubernetes/manifests/
  • kubectl delete 静态 Pod 不会删除它,kubelet 会自动重建
  • etcd 健康检查使用 etcdctl endpoint health
  • etcd 端点通常为 https://127.0.0.1:2379
  • etcd 证书路径:/etc/kubernetes/pki/etcd/
  • API Server 不可用时检查静态 Pod 配置和 kubelet 日志
  • CKA 考试中常见:错误的证书路径、错误的 etcd 端点地址

🧪 完整操作实例:排查 API Server 故障

场景描述

API Server 响应异常,kubectl 命令无法正常工作,从检查控制平面 Pod 状态、静态 Pod 配置、etcd 健康检查到完全恢复的排查过程。

前置条件

  • 一个有 Master 节点的集群
  • Master 节点的 SSH 访问权限
  • Master 节点上有 kubeadm 工具

操作步骤

Step 1: 发现 API Server 异常

kubectl get nodes
# The connection to the server <master-ip>:6443 was refused - did you specify the right host or port?
# API Server 完全不可用

Step 2: SSH 到 Master 节点并检查控制平面 Pod

ssh master-node

# 使用 containerd 直接查看容器状态(因为 kubectl 不可用)
crictl ps | grep apiserver
# 如果没有输出,说明 API Server 容器未运行

# 检查所有 kube-system 容器
crictl ps -a | grep -E "apiserver|scheduler|controller|etcd"
# CONTAINER ID    IMAGE    CREATED     STATUS      NAME
# ...             ...      10m ago     Exited      kube-apiserver

Step 3: 检查静态 Pod 配置文件

ls -la /etc/kubernetes/manifests/
# total 16
# -rw------- 1 root root 2153 May 27 09:00 kube-apiserver.yaml
# -rw------- 1 root root 2000 May 27 09:00 kube-controller-manager.yaml
# -rw------- 1 root root 1585 May 27 09:00 kube-scheduler.yaml
# -rw------- 1 root root 1466 May 27 09:00 etcd.yaml

# 检查 API Server 配置(查找常见配置错误)
cat /etc/kubernetes/manifests/kube-apiserver.yaml
# 重点关注:
# - --etcd-servers: 地址是否正确
# - --tls-cert-file / --tls-private-key-file: 证书路径是否存在
# - --service-cluster-ip-range: 是否合法

Step 4: 查看 kubelet 日志获取 API Server 启动错误

sudo journalctl -u kubelet -n 50 --no-pager
# May 27 10:00:00 master-node kubelet[1234]: E1001 10:00:00.123456    1234 kubelet.go:1234] "Error syncing pod, skipping" err="failed to \"StartContainer\" for \"kube-apiserver\" with CrashLoopBackOff: ..."
# May 27 10:00:01 master-node kubelet[1234]: E1001 10:00:01.123456    1234 kubelet.go:5678] "Unable to read config path" err="path does not exist, ignoring" path="/etc/kubernetes/manifests/kube-apiserver.yaml"

如果输出显示配置路径不存在,说明配置文件被误删除或移动。

Step 5: 检查证书是否过期

# 检查 API Server 证书
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates
# notBefore=May 27 09:00:00 2025 GMT
# notAfter=May 27 09:00:00 2026 GMT
# → 证书已过期!

# 检查所有证书有效期
sudo kubeadm certs check-expiration
# [check-expiration] Checking expiration for all certificates ...
# apiserver.crt          May 27 09:00:00 2026    to   May 27 09:00:00 2026    <过期
# apiserver-kubelet-client.crt  ...

Step 6: 修复证书并重启组件

# 更新所有证书
sudo kubeadm certs renew all
# certificate renewal succeeded

# 验证证书已更新
sudo kubeadm certs check-expiration
# apiserver.crt          May 27 09:00:00 2026    to   May 27 10:30:00 2027    ← 已延长

# 重启 kubelet 使新证书生效
sudo systemctl restart kubelet

# 等待静态 Pod 自动重建
sleep 30

Step 7: 验证 etcd 健康状态

# 使用 etcdctl 检查 etcd 端点健康
kubectl exec -it -n kube-system etcd-master-node -- \
  etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  endpoint health
# https://127.0.0.1:2379 is healthy: successfully committed proposal: took = 2.345ms

Step 8: 验证集群恢复正常

# 从 Master 节点验证
kubectl get nodes
# NAME           STATUS   ROLES           AGE   VERSION
# master-node    Ready    control-plane   10d   v1.28.0
# worker-node1   Ready    <none>          10d   v1.28.0

kubectl get pods -n kube-system | grep apiserver
# kube-apiserver-master-node   1/1     Running   0          2m

验证结果

# 确认 API Server 正常运行
kubectl get componentstatuses
# NAME                 STATUS    MESSAGE             ERROR
# controller-manager   Healthy   ok
# scheduler            Healthy   ok
# etcd-0               Healthy   {"health":"true"}

# 验证证书有效
echo | openssl s_client -connect localhost:6443 2>/dev/null | openssl x509 -noout -dates

考试提示

  • API Server 不可用时,直接 SSH 到 Master 节点,使用 crictldocker 查看容器状态
  • 控制平面组件是静态 Pod,配置文件在 /etc/kubernetes/manifests/
  • 证书过期是常见考点,使用 kubeadm certs renew all 更新
  • 修复后 systemctl restart kubelet 触发静态 Pod 重建
  • etcd 健康检查使用 etcdctl endpoint health,证书路径要牢记

官方文档