Kubernetes Service 调试完全指南:从约定到排障
Kubernetes Service 调试完全指南从约定到排障一、核心约定命令运行位置说明在 Kubernetes 调试中命令运行环境至关重要本文采用以下统一约定运行环境命令格式示例说明Pod 内部upod$ COMMAND需进入 Pod 交互式终端或通过kubectl exec执行Node 节点unode$ COMMAND直接在 Kubernetes 集群节点上运行任意环境含 kubectl$ kubectl ARGS拥有集群凭证和 kubectl 工具即可执行二、前置准备部署测试资源1. 启动交互式调试 Pod$ kubectl run -it --rm --restartNever busybox --imagebusybox sh # 若已有运行中 Pod可直接执行命令替换占位符 $ kubectl exec -NAME -c CONTAINER-NAME; #### 2. 部署测试 Deployment 创建 3 个副本的 hostnames 应用用于模拟服务后端 bash $ kubectl run hostnames --imagek8s.gcr.io/serve_hostname --labelsapphostnames --port9376 --replicas3 # 验证 Pod 状态需全部为 Running $ kubectl get pods -l apphostnames3. 创建对应 Service暴露 Deployment 为 ClusterIP 类型 Service端口 80 映射到 Pod 9376$ kubectl expose deployment hostnames --port80 --target-port9376 # 验证 Service 状态 $ kubectl get svc hostnames三、分层调试Service 故障排查步骤1. 基础检查Service 是否存在这是最易遗漏的第一步不存在的 Service 会直接导致访问失败# 检查 Service 是否存在 $ kubectl get svc hostnames # 失败表现Pod 内访问提示地址错误 upod$ wget -qO- hostnames wget: bad address hostname2. DNS 验证Service 能否通过名称解析Kubernetes 依赖 DNS 实现 Service 名称访问需分场景验证同命名空间解析upod$ nslookup hostnames # 成功结果返回 Service ClusterIP如 10.0.1.175跨命名空间解析指定命名空间upod$ nslookup hostnames.default # default 为目标命名空间完全限定名解析最高优先级upod$ nslookup hostnames.default.svc.cluster.localDNS 配置检查Pod 内/etc/resolv.conf需包含集群 DNS 和正确搜索域upod$ cat /etc/resolv.conf # 关键配置要求 # 1. nameserver 指向集群 DNS如 10.0.0.10 # 2. search 包含 c.cluster.local # 3. options ndots:5默认配置确保搜索域生效3. 连通性测试Service IP 能否访问DNS 正常后直接通过 Service ClusterIP 验证服务可用性# 在 Node 节点执行 curl替换为实际 ClusterIP unode$ curl 10.0.1.175:80 # 成功结果循环返回 3 个 Pod 的主机名负载均衡效果 hostnames-0uton hostnames-yp2kp hostnames-bvc054. 配置校验Service 与 Pod 匹配是否正确Service 通过标签选择器关联 Pod配置不匹配会导致无后端可用# 查看 Service 详细配置重点检查 spec.selector 和 ports $ kubectl get service hostnames -o json关键校验项spec.selector需与 Pod 标签如apphostnames完全一致ports.port与targetPortService 端口和 Pod 暴露端口匹配协议一致性TCP/UDP 需与 Pod 保持一致5. Endpoints 检查Service 是否关联到 PodEndpoints 是 Service 与 Pod 的桥梁无 Endpoints 则服务无后端# 查看 Service 关联的 Endpoints应包含 3 个 Pod IP:端口 $ kubectl get endpoints hostnames # 成功结果 NAME ENDPOINTS hostnames 10.244.0.5:9376,10.244.0.6:9376,10.244.0.7:9376失败处理若 Endpoints 为空检查 Service 标签选择器与 Pod 标签是否一致。6. Pod 本身检查后端服务是否正常绕过 Service 直接访问 Pod IP验证后端应用可用性# 替换为 Endpoints 中的 Pod IP 和端口9376 upod$ wget -qO- 10.244.0.5:9376 # 成功结果返回对应 Pod 的主机名额外检查Pod 状态无频繁重启、日志无报错$ kubectl get pods -l apphostnames # 查看 RESTARTS 列 $ kubectl logs OD-NAME # 排查应用日志7. kube-proxy 检查服务代理是否正常kube-proxy 负责维护 Service 转发规则是集群网络的核心组件检查 kube-proxy 运行状态unode$ ps auxw | grep kube-proxy # 成功结果显示 kube-proxy 进程及参数检查 iptables 规则kube-proxy 生成unode$ iptables-save | grep hostnames # 成功结果包含 KUBE-SERVICES、KUBE-SVC-*、KUBE-SEP-* 相关规则日志排查查看 kube-proxy 日志需根据节点 OS 调整路径# 示例CentOS/RHEL unode$ journalctl -u kube-proxy # 示例Ubuntu unode$ cat /var/log/kube-proxy.log8. 特殊场景Pod 无法访问自身 Service IP若 Pod 访问自身所在 Service 失败需检查hairpin-mode配置# 检查 kubelet 的 hairpin-mode 参数 unode$ ps auxw | grep kubelet | grep hairpin-mode # 有效配置hairpin-veth 或 promiscuous-bridge验证配置生效# 若为 hairpin-veth 模式 unode$ for intf in /sys/devices/virtual/net/cbr0/brif/*; do cat $intf/hairpin_mode; done # 成功结果所有输出为 1 # 若为 promiscuous-bridge 模式 unode$ ifconfig cbr0 | grep PROMISC # 成功结果包含 PROMISC 标识