K8s新手必看:Calico和CoreDNS卡在Pending状态的5种排查姿势(附实操命令)
Kubernetes集群中Calico与CoreDNS组件Pending状态深度排查指南
刚接触Kubernetes的运维工程师在搭建集群时,经常会遇到calico-kube-controllers和coredns这两个核心组件卡在Pending状态的情况。这种问题看似简单,但背后可能隐藏着多种复杂的故障原因。本文将采用系统化的故障树分析方法,带您逐层深入排查,并提供可直接执行的解决方案。
1. 资源不足:最基础的排查起点
当执行kubectl get pods -n kube-system发现calico-kube-controllers和coredns处于Pending状态时,第一个需要检查的就是节点资源是否充足。资源不足是新手最容易忽视的问题之一。
诊断步骤:
# 查看节点资源分配情况
kubectl describe nodes
在输出中重点关注以下字段:
Allocatable:节点可分配资源总量Allocated:已分配资源量Conditions:节点健康状况
典型问题场景:
- 节点内存不足(特别是小于2GB的小型测试环境)
- CPU核心数过少(单核节点运行多个系统组件时容易出现瓶颈)
- 未正确配置kubelet的资源预留参数
解决方案:
# 临时解决方案:清理不必要的Pod释放资源
kubectl get pods --all-namespaces | grep -Ev 'Running|Completed' | awk '{print $1,$2}' | xargs -L1 kubectl delete pod -n
# 长期解决方案:调整节点资源配置
# 对于kubeadm部署的集群,可以修改kubelet配置
sudo vi /etc/default/kubelet
KUBELET_EXTRA_ARGS="--system-reserved=cpu=500m,memory=500Mi --kube-reserved=cpu=500m,memory=500Mi"
提示:在资源受限的环境中,可以考虑使用轻量级的CoreDNS配置,减少内存占用。修改coredns的ConfigMap,移除不必要的插件。
2. 网络策略问题:Calico特有的故障场景
Calico作为Kubernetes最流行的网络插件之一,其配置问题经常导致组件无法正常运行。当calico-node正常运行但calico-kube-controllers仍处于Pending状态时,需要特别关注网络策略。
诊断流程:
# 检查Calico核心组件状态
kubectl get pods -n kube-system -l k8s-app=calico-node
# 查看calico-kube-controllers的详细事件
kubectl describe pod -n kube-system -l k8s-app=calico-kube-controllers
常见问题模式:
- 节点污点(taint)导致Pod无法调度(特别是control-plane节点的
node-role.kubernetes.io/control-plane:NoSchedule污点) - 网络策略阻止了控制平面通信
- IP地址池配置错误
解决方案示例:
# 如果是因为节点污点导致的问题,可以添加容忍度或移除污点
# 方法一:修改calico-kube-controllers的Deployment添加容忍度
kubectl edit deployment -n kube-system calico-kube-controllers
# 在spec.template.spec下添加:
tolerations:
- key: "node-role.kubernetes.io/control-plane"
operator: "Exists"
effect: "NoSchedule"
# 方法二:移除节点污点(不推荐生产环境使用)
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
3. 镜像拉取失败:被忽视的常见问题
在国内环境部署Kubernetes集群时,镜像拉取失败是导致组件Pending的常见原因。由于calico-kube-controllers和coredns使用的镜像默认来自国外仓库,很容易出现拉取超时或失败的情况。
诊断方法:
# 查看Pod的详细事件,寻找镜像拉取相关的错误
kubectl describe pod -n kube-system <pod-name>
# 手动尝试拉取镜像进行验证
docker pull calico/kube-controllers:v3.24.1
docker pull coredns/coredns:1.9.3
解决方案:
# 方案一:预先拉取镜像并重新打标签
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.9.3
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.9.3 coredns/coredns:1.9.3
# 方案二:修改Deployment的镜像拉取策略
kubectl edit deployment -n kube-system calico-kube-controllers
# 将imagePullPolicy从Always改为IfNotPresent
注意:对于生产环境,建议搭建私有镜像仓库或使用可靠的国内镜像源,避免依赖不可控的外部资源。
4. CNI插件未就绪:集群网络初始化的关键阶段
在集群初始化过程中,CNI插件的安装和配置是一个关键步骤。如果CNI插件未能正确初始化,即使calico-node Pod显示为Running状态,网络功能可能仍未完全就绪。
深度排查步骤:
# 检查kubelet日志,寻找CNI相关的错误
journalctl -u kubelet -f | grep -i cni
# 验证CNI配置文件是否存在
ls /etc/cni/net.d/
# 检查calico-node容器的日志
kubectl logs -n kube-system -l k8s-app=calico-node
典型故障现象:
/etc/cni/net.d/目录为空或配置不正确- calico-node日志中出现"Failed to create Calico client"等错误
- kubelet不断报告"NetworkPluginNotReady"
解决方案:
# 重新安装Calico CNI插件
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
# 重启kubelet服务使配置生效
systemctl restart kubelet
# 检查CNI插件状态
kubectl get pods -n kube-system -l k8s-app=calico-node
5. 存储配置问题:容易被忽略的故障点
虽然calico-kube-controllers和coredns通常不需要持久化存储,但如果集群中配置了默认的StorageClass或者Pod中错误地引用了PVC,也可能导致Pod卡在Pending状态。
排查命令:
# 检查集群中的StorageClass配置
kubectl get storageclass
# 查看PersistentVolumeClaim状态
kubectl get pvc -n kube-system
# 检查Pod中是否错误引用了存储卷
kubectl describe pod -n kube-system <pod-name> | grep -A10 Volumes
解决方案:
# 如果确实不需要存储,可以修改Deployment移除相关配置
kubectl edit deployment -n kube-system calico-kube-controllers
# 删除volumes和volumeMounts相关配置
# 如果确实需要存储,确保StorageClass配置正确
# 示例:创建本地存储类
cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
EOF
6. 高级排查:当常规方法都失效时
如果经过上述排查仍未解决问题,就需要采用更高级的调试手段。这时候需要综合多种信息进行交叉验证。
系统化排查流程:
-
检查集群事件:
kubectl get events --all-namespaces --sort-by='.metadata.creationTimestamp' -
验证节点网络连通性:
# 在节点上执行 ping <其他节点IP> curl -I https://docs.projectcalico.org -
检查kube-proxy状态:
kubectl logs -n kube-system -l k8s-app=kube-proxy -
验证API Server健康状态:
curl -k https://localhost:6443/healthz -
检查etcd集群健康状态:
kubectl exec -n kube-system etcd-<节点名> -- etcdctl endpoint health
复杂场景解决方案:
# 完全重置Calico安装(谨慎操作)
kubectl delete -f https://docs.projectcalico.org/manifests/calico.yaml
# 清理残留资源
ip link delete calico_interface
rm -rf /var/lib/calico
# 重新安装
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
7. 预防措施与最佳实践
为了避免calico-kube-controllers和coredns频繁出现Pending状态,建议采取以下预防措施:
集群部署阶段:
- 确保节点满足最低资源要求(至少2核CPU、4GB内存)
- 预先拉取所有必需的容器镜像
- 使用经过验证的Kubernetes版本和Calico版本组合
配置优化建议:
# coredns的资源配置示例(Corefile配置片段)
ready {
# 减少健康检查间隔
interval 5s
}
# calico-kube-controllers的资源请求示例
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
监控与告警:
- 为calico-kube-controllers和coredns设置Prometheus监控
- 配置Alertmanager规则,当Pod长时间处于Pending状态时触发告警
- 定期检查集群事件日志,及时发现潜在问题
更多推荐
所有评论(0)