为何Kubernetes中exec就绪探针可行,httpGet方式却提示无此主机?
问题:为何exec方式的就绪探针能正常工作,httpGet方式却出现DNS解析失败?
现象复现
1. 可正常工作的exec方式探针Pod定义
apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: ready-if-service-ready name: ready-if-service-ready spec: containers: - image: nginx:1.16.1-alpine name: ready-if-service-ready resources: {} livenessProbe: exec: command: - 'true' readinessProbe: exec: command: - sh - -c - 'wget -T2 -O- http://service-am-i-ready:80' dnsPolicy: ClusterFirst restartPolicy: Always status: {}
2. 失效的httpGet方式探针Pod定义
apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: ready-if-service-ready name: ready-if-service-ready spec: containers: - image: nginx:1.16.1-alpine name: ready-if-service-ready resources: {} livenessProbe: exec: command: - 'true' readinessProbe: httpGet: # 仅修改了探针方式 host: service-am-i-ready path: / port: 80 scheme: HTTP dnsPolicy: ClusterFirst restartPolicy: Always status: {}
3. 错误信息
执行kubectl po describe ready-if-service-ready得到的警告:
Warning Unhealty 3m10s (x139 over 23m) kubelet Readiness probe failed: Get "http://service-am-i-ready:80/": dial tcp: lookup service-am-i-ready: no such host
Pod状态:
NAME READY STATUS RESTARTS AGE ready-if-service-ready 0/1 Running 0 27m
原因分析
两者的核心差异在于探针的执行环境完全不同:
- exec方式探针:所有命令在Pod的容器内部运行。容器配置了
ClusterFirstDNS策略,会调用Kubernetes集群的CoreDNS服务解析集群内部的Service域名,因此wget命令能正常识别service-am-i-ready并完成请求。 - httpGet方式探针:由节点上的kubelet进程直接发起HTTP请求,并非在Pod容器内执行。节点的DNS解析器默认没有配置Kubernetes Service域名的解析规则,无法识别
service-am-i-ready这类集群内部域名,最终导致DNS解析失败。
简言之,exec探针是“从Pod内部访问外部服务”,httpGet探针是“从节点层面访问外部服务”,两者的DNS环境完全不同,这才造成了看似相同的请求却出现截然不同的结果。
内容的提问来源于stack exchange,提问作者Moritz Wolff
相关产品推荐
相关产品推荐

