核心 K8s Runbook:apiserver / etcd / kubelet / containerd / HAProxy
这篇只讲 K8s 核心,不讲 CNI、存储、监控。你需要能回答:
- 这些组件分别干什么。
- 怎么安装。
- 怎么看它们是否正常。
- 出故障先查哪里。
1. 组件作用
| 组件 | 跑在哪里 | 作用 |
|---|---|---|
kube-apiserver | 3 个 control plane | K8s API 入口,kubectl 和控制器都访问它 |
etcd | 3 个 control plane | K8s 数据库,保存所有对象和状态 |
kube-scheduler | 3 个 control plane | 决定 Pod 放到哪个节点 |
kube-controller-manager | 3 个 control plane | 不断把实际状态调成期望状态 |
kubelet | 每台节点 | 节点代理,负责启动 Pod、上报节点状态 |
containerd | 每台节点 | 容器运行时,真正拉镜像、启动容器 |
HAProxy | 每台节点 | 本机 apiserver 高可用入口 127.0.0.1:16443 |
kubectl 的路径:
kubectl -> kubeconfig -> https://k8s-api:16443
-> /etc/hosts 解析到 127.0.0.1
-> 本机 HAProxy
-> 3 个 apiserver 中健康的一个
-> etcd
2. 查看核心组件
在 cp-1 执行:
kubectl get nodes -o wide
kubectl get pods -n kube-system -o wide | grep -E \
'kube-apiserver|kube-controller-manager|kube-scheduler|etcd'
kubectl get componentstatuses
节点侧:
systemctl status kubelet --no-pager
systemctl status containerd --no-pager
systemctl status haproxy --no-pager
journalctl -u kubelet --since "10 min ago" --no-pager | tail -100
journalctl -u containerd --since "10 min ago" --no-pager | tail -100
journalctl -u haproxy --since "10 min ago" --no-pager | tail -100
为什么既看 Pod 又看 systemd:control plane 组件是 static Pod,由 kubelet 管;kubelet/containerd/HAProxy 是 systemd 服务,由操作系统管。
3. 验证 apiserver 入口
getent hosts k8s-api
ss -tlnp | grep 16443
curl -k https://127.0.0.1:16443/readyz
kubectl get --raw='/readyz?verbose'
期望:
getent hosts k8s-api返回127.0.0.1。- HAProxy 监听
127.0.0.1:16443。 /readyz返回ok。
如果 kubectl 报:
lookup k8s-api on 127.0.0.53:53: server misbehaving
先修 /etc/hosts,不要先重启集群。见 Day 0 Runbook 的 k8s-api 故障。
4. containerd 查看和调试
crictl info
crictl ps -a | head
crictl images | head
ctr -n k8s.io images ls | head
df -h /var/lib/containerd
du -sh /var/lib/containerd/* 2>/dev/null
常见问题:
| 现象 | 先看 | 常见原因 |
|---|---|---|
Pod 卡 ImagePullBackOff | kubectl describe pod、crictl pull | 镜像地址错、私有仓库认证错、containerd 没配 HTTP registry |
| kubelet 报 runtime not ready | crictl info、journalctl -u containerd | containerd 没启动、CRI socket 错 |
| 节点磁盘满 | df -h /var/lib/containerd | 镜像缓存太多、容器日志太大 |
清理镜像前先确认业务不需要:
crictl images
crictl rmi --prune
5. kubelet 查看和调试
systemctl status kubelet --no-pager
journalctl -u kubelet --since "30 min ago" --no-pager | tail -200
cat /var/lib/kubelet/config.yaml | sed -n '1,120p'
cat /var/lib/kubelet/kubeadm-flags.env
kubelet 常见错误:
| 日志关键字 | 含义 | 排查方向 |
|---|---|---|
Unable to register node | kubelet 连不上 apiserver | k8s-api、HAProxy、证书 |
container runtime is down | 连不上 containerd | systemd、CRI socket |
NetworkPluginNotReady | CNI 没好 | Cilium |
MountVolume | 卷挂载失败 | Longhorn / PVC |
InvalidDiskCapacity | 容器运行时或磁盘探测异常 | containerd、磁盘 |
6. etcd 查看和备份
etcd 是 K8s 数据库。误删 etcd 数据目录等于删整个集群状态。
查看 Pod:
kubectl get pod -n kube-system -l component=etcd -o wide
在 cp-1 上用 etcdctl:
export ETCDCTL_API=3
export ETCDCTL_CACERT=/etc/kubernetes/pki/etcd/ca.crt
export ETCDCTL_CERT=/etc/kubernetes/pki/etcd/server.crt
export ETCDCTL_KEY=/etc/kubernetes/pki/etcd/server.key
etcdctl --endpoints=https://127.0.0.1:2379 endpoint status -w table
etcdctl --endpoints=https://127.0.0.1:2379 member list -w table
备份:
mkdir -p /backup/etcd
etcdctl --endpoints=https://127.0.0.1:2379 \
snapshot save /backup/etcd/etcd-$(date +%Y%m%d-%H%M%S).db
etcdctl snapshot status /backup/etcd/*.db -w table
为什么必须备份:K8s 所有 Deployment、Secret、PVC 绑定、RBAC 都在 etcd。没有 snapshot,控制面坏到 quorum 丢失时只能重建集群。
7. 节点 NotReady 排查树
kubectl get nodes
-> NotReady
-> kubectl describe node <node>
-> journalctl -u kubelet
-> lookup k8s-api 失败: 修 /etc/hosts
-> runtime not ready: 查 containerd
-> NetworkPluginNotReady: 查 Cilium
-> disk pressure: 查磁盘和 containerd
-> memory pressure: 查 top / pods requests
实用命令:
kubectl describe node k8s-cp-1
kubectl top node
kubectl get pods -A -o wide | grep k8s-cp-1
ssh root@154.201.73.31 'df -h; free -h; top -b -n1 | head -30'