K8s集群健康检查异常:深入解析connection refused问题与修复策略
1. 问题现象与初步诊断刚部署完Kubernetes集群时很多工程师都会遇到这个经典问题执行kubectl get cs命令后controller-manager和scheduler组件显示Unhealthy状态具体报错信息类似这样NAME STATUS MESSAGE ERROR controller-manager Unhealthy Get http://127.0.0.1:10252/healthz: dial tcp 127.0.0.1:10252: connect: connection refused scheduler Unhealthy Get http://127.0.0.1:10251/healthz: dial tcp 127.0.0.1:10251: connect: connection refused etcd-0 Healthy {health:true}这个现象特别容易出现在使用kubeadm部署的集群中。我第一次遇到时也吓了一跳以为集群安装失败了。但实际测试发现虽然状态显示异常但基本功能似乎不受影响。这到底是怎么回事关键诊断步骤检查端口监听情况netstat -tunlp | grep 1025查看组件日志journalctl -u kubelet -f验证配置文件路径ls -l /etc/kubernetes/manifests/2. 根本原因解析经过多次实践和分析发现问题根源在于Kubernetes的安全机制演进。从v1.12版本开始社区为了增强安全性默认禁用了controller-manager和scheduler的非安全端口10251和10252。具体来说在/etc/kubernetes/manifests/目录下的YAML配置中这两个组件的启动参数都设置了--port0这个参数会关闭HTTP端口的监听但健康检查逻辑仍然尝试通过旧端口进行探测这就好比你家门锁换了但快递员还往旧邮箱投递通知单自然会出现查无此箱的错误。这种设计本意是好的但健康检查机制没有同步更新导致了状态误报。3. 详细修复步骤3.1 修改scheduler配置首先处理kube-scheduler的配置vim /etc/kubernetes/manifests/kube-scheduler.yaml找到command部分中的- --port0参数在前面添加#注释掉这行。修改后的片段示例command: - kube-scheduler - --authentication-kubeconfig/etc/kubernetes/scheduler.conf - --authorization-kubeconfig/etc/kubernetes/scheduler.conf - --bind-address127.0.0.1 - --kubeconfig/etc/kubernetes/scheduler.conf - --leader-electtrue # - --port0 # 关键修改点3.2 修改controller-manager配置同样方法处理kube-controller-managervim /etc/kubernetes/manifests/kube-controller-manager.yaml找到并注释掉- --port0。注意这个文件参数较多建议搜索定位command: - kube-controller-manager - --allocate-node-cidrstrue # ...其他参数... # - --port0 # 关键修改点 - --requestheader-client-ca-file/etc/kubernetes/pki/front-proxy-ca.crt # ...后续参数...3.3 多Master节点处理如果集群有多个Master节点需要在每个节点重复上述操作。我曾在生产环境漏改了一个节点导致HA检测异常这个坑大家一定要注意。3.4 重启kubelet服务修改完成后不需要直接重启组件只需重启kubelet即可systemctl restart kubelet因为kubelet会监控manifest目录的变化自动重建对应的Pod。4. 验证与效果检查等待约1分钟后执行以下检查查看组件状态kubectl get cs正常输出应显示所有组件HealthyNAME STATUS MESSAGE ERROR scheduler Healthy ok controller-manager Healthy ok etcd-0 Healthy {health:true}确认端口监听netstat -tunlp | grep -E 10251|10252应该能看到类似输出tcp6 0 0 :::10251 :::* LISTEN 12345/kube-scheduler tcp6 0 0 :::10252 :::* LISTEN 12346/kube-controller5. 安全考量与替代方案虽然上述方法能解决问题但从安全角度需要考虑以下几点端口暴露风险10251/10252是HTTP端口没有认证机制版本兼容性Kubernetes新版本可能完全移除这些端口替代方案使用--bind-address127.0.0.1限制本地访问配置网络策略限制访问源完全过渡到HTTPS健康检查端口(10257/10259)生产环境中我建议同时做以下加固# 在scheduler配置中添加 - --bind-address127.0.0.1 - --secure-port10259 - --tls-cert-file/path/to/cert - --tls-private-key-file/path/to/key # 在controller-manager配置中添加 - --bind-address127.0.0.1 - --secure-port10257 - --tls-cert-file/path/to/cert - --tls-private-key-file/path/to/key6. 常见问题排查即使按照上述步骤操作偶尔还会遇到异常情况。这里分享几个排查技巧场景1修改后状态仍为Unhealthy检查YAML文件格式确保注释符号#前有空格查看kubelet日志journalctl -u kubelet -n 50 -f确认文件保存后inode变化ls -li /etc/kubernetes/manifests/场景2端口仍然未监听检查组件日志kubectl logs -n kube-system pod-name确认没有其他参数覆盖端口设置检查防火墙规则iptables -L -n -v场景3短暂恢复后又异常可能是kubelet配置了自动恢复检查/var/lib/kubelet/config.yaml中的静态Pod配置确认磁盘没有写满导致配置回滚7. 版本差异与长期方案不同Kubernetes版本处理方式有所差异版本范围处理方式备注1.12无需修改端口默认开启1.12-1.18注释port0过渡方案1.19使用--secure-port推荐方案从v1.19开始官方文档已明确建议完全禁用非安全端口使用10257(controller-manager)和10259(scheduler)作为健康检查端口配置正确的证书和授权典型的现代配置示例# scheduler示例 livenessProbe: httpGet: path: /healthz port: 10259 scheme: HTTPS initialDelaySeconds: 10 periodSeconds: 10 # controller-manager示例 livenessProbe: httpGet: path: /healthz port: 10257 scheme: HTTPS failureThreshold: 8这种配置既满足健康检查需求又符合安全最佳实践。我在生产环境采用这种方案后再没出现过connection refused问题。