date
related_level
slug
type
relate_date
summary
status
tags
category
last_updated
Dec 8, 2025 02:34 PM
是否已更新
orginal_page
是否推荐
kubernetes Pod 故障排查思路
排查常用指令
kubectl describe
kubectl logs--previous查看前一次 pod 的日志
sudo systemctl status kubelet
ps aux | grep etcd- 外部 etcd
- 排障思路:从用户端开始排查
如果是 web 服务可以看看连接是否正常
- DNS 解析是否正常
- CoreDNS 是否正常
- 用户层连接是否正常
- 证书/TLS 是否配置正确
- 入口控制器(Ingress/Gateway/Service Mesh)是否配置正常
- 网络策略是否配置正常
- Service 是否正常匹配 Pod
- 网络层连接是否正常
- CNI 插件是否正常
- 是否能正常访问 Pod 对应节点
- kube-proxy 是否正常运行
pod 是否在正常运行
- 底层镜像是否正确配置,运行 command 和 args 是否正常
- 私有镜像是否正确配置 secrets
- pod 声明的容器探针是否正常配置
- initialDelaySeconds 是否足够容器正常启动
- pod 依赖的存储, configmap, secrets 等资源是否正确配置
- 是否正确挂载
- pod RBAC 权限(serviceAccount, role, rolebinding)是否正常
pod 调度是否正常(一直处于 Pending)
- pod 资源请求和限制是否正常
- 调度节点的资源是否充足
- LimitRange 和 ResourceQuota 是否配置正确
- pod 的节点调度策略是否正常
- 是否存在 nodeSelector
- toleration 是否匹配节点 taint
- 亲和性(affinity)和拓扑约束(TopologySpreadConstraints)是否满足
- kube-controller-manager 和 kube-scheduler 是否正常运行
调度节点是否正常
- 节点状态是否正常
- 非 NoSchedule 或 NoExecute
- 对应节点的 kubelet 是否正常运行
- 控制平面的 kube-apiserver 是否正常运行
- 集群内或者外部配置的 etcd 是否正常运行
- 节点计算资源和存储资源是否足够
- 节点底层系统是否正常配置
- sysctl 内核参数
- 内核模块
- SELinux 或 AppArmor
kubernetes 集群控制节点故障排查
集群配置文件位置
- kubeconfig
$HOME/.kube/config
- 静态 Pod 配置文件,一般含 kubectl 组件
/etc/kubernetes/manifests- 默认路径
cat /var/lib/kubelet/config.yaml | grep staticPodPath- 可能会被更改
- kubelet 组件配置
/var/lib/kubelet/config.yaml
- 集群外 etcd
/etc/etcd
- CRI 文件目录
/etc/containerd/config.toml
- CNI 文件目录
/etc/cni/net.d//opt/cni/bin/
集群证书位置
/etc/kubernetes/pki/etcd- 如果为内部 etcd
- 外部 etcd 集群根据具体配置
/etc/etcd/pki
/etc/kubernetes/pki
/var/lib/kubelet/pki
- 排查常用指令
crictl pods列出所有 Podcrictl ps -a列出所有容器crictl images列出容器镜像crictl exec -i在容器内运行特定指令crictl logs查看容器日志kubectl debug node/<nodename> -it --image=ubuntu- 节点根文件系统挂载在 Pod 的
/host路径 cat /host/var/log/kubelet.log- 该 Pod 默认没有特权,需要
--profile=sysadmin - 或者添加 securityContext
- 清理调试 Pod
kubectl delete pod node-debugger-<nodename>-<suffix>
crictl 常用调试命令
kubectl debug node 调试节点,当无法 SSH 连接到节点时
kubectl config 检查当前 kubeconfig 配置
kubectl config get-context- 当前上下文
kubectl config view --minify- 仅显示当前上下文配置
kubectl get nodes检查 kube-apiserver 是否正常crictl ps | grep kube-apiserve- 检查容器
ss -tulnp | grep 6443- 检查端口
curl -k https://127.0.0.1:6443/healthz- 检查是否正常运行
ls /etc/kubernetes/manifest | grep apiserver- 检查配置
crictl logs $CONTAINER_ID- 检查容器日志
journalctl -u kubelet- 检查 kubelet 日志
tail /var/log/kube-apiserver.log- 检查 kube-apiserver
cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep -A20 "command:"- 检查启动参数
openssl x509 -in <cert-file> -noout -text | grep -E "Issuer|Subject|Not After"- 检查证书是否过期,issuer 和 CN 是否正确
无响应或连接,检查 kube-apiserver 是否在运行以及配置是否正常
返回 Connection refused 可能是启动参数异常或者证书配置异常
检查 kubernetes 集群网络
检查 kubernete DNS 配置并调试 DNS
创建一个简单的 Pod 作为测试环境
kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml
- 验证安装情况
kubectl get pods -n default dnsutils
- 处于 running 状态后可以执行
nslookup kubectl -n default exec -i -t dnsutils -- nslookup kubernetes.defaultkubectl -n default exec -i -t dnsutils -- ping -c 4 kubernetes.default
Coredns 服务开启 DNS 查询记录日志
kubectl -n kube-system edit configmap coredns
- 添加
log项
kubectl logs -n kube-system -l k8s-app=kube-dns- 查看服务运行日志
检查 DNS 配置
查看 resolv.conf 文件的内容
kubectl exec -ti dnsutils -- cat /etc/resolv.conf
官方样例,search 域可能根据云供应商变化
检查 DNS 服务和 CoreDNS Pod 运行情况
kubectl get svc --namespace=kube-system- 查看
kube-dns是否运行
kubectl get pods --namespace=kube-system -l k8s-app=kube-dns- 查看对应 DNS pods 是否运行
kubectl logs --namespace=kube-system -l k8s-app=kube-dns- 查看服务运行日志
检查 DNS 端点公开情况
kubectl get endpointslices -l k8s.io/service-name=hostnames- 检查 pod 对应 endpointslices
- 假设应用具有以下 label
k8s.io/service-name: hostnames
检查 CoreDNS RBAC 权限
- CoreDNS 必须能够列出 service 和 endpoint 相关的资源来正确解析服务名称
kubectl describe clusterrole system:coredns -n kube-system
预期输出结果
- 缺失权限时编辑 ClusterRole 来添加
kubectl edit clusterrole system:coredns -n kube-system
部分 DNS 已知问题
部分 Linux 发行版如 Ubuntu 本地 DNS 解析器 systemd-resolved 覆盖 /etc/resolv.conf 内容,可能导致在上游服务器中解析域名产生转发环
- 可以手动指定 kubelet 的
--resolv-conf标志为正确的resolv.conf systemd-resolved对应路径为/run/systemd/resolve/resolv.conf
- 也可以禁用本地 DNS 解析器 stub
resolvectl status | grep resolv.confresolv.conf mode: stub代表当前配置了127.0.0.53为域名服务器vim /etc/systemd/resolved.conf#DNSStubListener=yes取消注释并改为DNSStubListener=no即可禁用systemctl restart systemd-resolved
如何禁用 nameserver 127.0.0.53
Linux 的 libc 默认将 DNS nameserver 记录限制为 3, 而 Kubernetes 需要使用 1 条 nameserver 记录
- 如果本地的安装已经使用了 3 个
nameserver,那么其中有些条目将会丢失
- 可以手动指定 kubelet 的
--resolv-conf标志为正确的resolv.conf systemd-resolved对应路径为/run/systemd/resolve/resolv.conf
- 也可以运行
dnsmasq,以提供更多nameserver条目
使用 Alpine 3.17 或更早版本作为你的基础镜像,DNS 可能会由于 Alpine 的设计问题而无法工作
- 将镜像升级到 Alpine 3.18 或更高版本
- 删除
kubectl delete -f ~/.config/k3s/dnsutils.yaml
kubernete 集群备份和恢复
kubectl 备份所有资源配置
kubectl get all --all-namespaces -o yaml > all-deploy-services.yaml- 但仍仅适用于少数资源组
存储集群数据的外部 etcd 备份和恢复
参考资料
- https://techdocs.broadcom.com/us/en/vmware-tanzu/bitnami-secure-images/bitnami-secure-images/services/bsi-doc/apps-tutorials-backup-restore-data-etcd-kubernetes-index.html
- 集群内的 etcd 且没有使用 hostpath 挂载主机目录
- 挂载了参考集群外的 etcd 即可
- 注意,etcd 的各种证书和凭据必须保持一致
分为内部 etcd 和外部 etcd
- 外部只需要直接修改 etcd 数据目录指向恢复后的数据目录即可
- 内部要区分是否挂载 hostpath 或持久卷作为数据目录
- 挂载了 hostpath 则参考外部 etcd 处理方法,修改挂载目录
- 如果挂载了持久卷考虑使用 Velero 备份持久卷并恢复
通过查看 kubectl-apiserver 配置项可以找到 etcd 的配置方式
vim /etc/kubernetes/manifests/kube-apiserver.yaml
假设已设置 etcdctl 环境变量
kubectl port-forward --namespace default svc/etcd 2379:2379 &- 如果是内部 etcd
mkdir -p /data/backup /var/lib/etcd-from-backup/data/backup用于 etcd 备份数据/var/lib/etcd-from-backup用于存放恢复后的数据
sudo etcdctl snapshot save /data/backup/etcd-backup-$(date +%Y%m%d-%H%M%S).db- 备份到
/data/backup
sudo etcdctl snapshot status /data/backup/<backup-db-filename>.db -w table- 验证备份 db
sudo etcdctl snapshot restore /data/backup/<backup-db-filename>.db --data-dir /var/lib/etcd-from-backup- 恢复备份文件到
/var/lib/etcd-from-backup - 需要注意文件夹权限
- 修改 etcd 服务以使用新的数据目录并重启
- 可能需要删除重启控制平面对应 pod
使用 velero 工具备份 k8s 集群
- Author:白鸟3
- URL:https://blog.kun2peng.top/operation/k8s_troubleshooting
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
