如果失败,那么你的 Pod 和 Service 可能位于不同的命名空间中, 请尝试使用限定命名空间的名称(同样在 Pod 内运行):
nslookup hostnames.default Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local Name: hostnames.default Address 1: 10.0.1.175 hostnames.default.svc.cluster.local如果成功,那么需要调整你的应用,使用跨命名空间的名称去访问它, 或者在相同的命名空间中运行应用和 Service。如果仍然失败,请尝试一个完全限定的名称:
nslookup hostnames.default.svc.cluster.local Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local Name: hostnames.default.svc.cluster.local Address 1: 10.0.1.175 hostnames.default.svc.cluster.local注意这里的后缀:"default.svc.cluster.local"。"default" 是我们正在操作的命名空间。 "svc" 表示这是一个 Service。"cluster.local" 是你的集群域,在你自己的集群中可能会有所不同。
你也可以在集群中的节点上尝试此操作:
说明: 10.0.0.10 是集群的 DNS 服务 IP,你的可能有所不同。
nslookup hostnames.default.svc.cluster.local 10.0.0.10 Server: 10.0.0.10 Address: 10.0.0.10#53 Name: hostnames.default.svc.cluster.local Address: 10.0.1.175如果你能够使用完全限定的名称查找,但不能使用相对名称,则需要检查你 Pod 中的 /etc/resolv.conf 文件是否正确。在 Pod 中运行以下命令:
cat /etc/resolv.conf你应该可以看到类似这样的输出:
nameserver 10.0.0.10 search default.svc.cluster.local svc.cluster.local cluster.local example.com options ndots:5nameserver 行必须指示你的集群的 DNS Service, 它是通过 --cluster-dns 标志传递到 kubelet 的。
search 行必须包含一个适当的后缀,以便查找 Service 名称。 在本例中,它查找本地命名空间(default.svc.cluster.local)中的服务和 所有命名空间(svc.cluster.local)中的服务,最后在集群(cluster.local)中查找 服务的名称。根据你自己的安装情况,可能会有额外的记录(最多 6 条)。 集群后缀是通过 --cluster-domain 标志传递给 kubelet 的。 本文中,我们假定后缀是 “cluster.local”。 你的集群配置可能不同,这种情况下,你应该在上面的所有命令中更改它。
options 行必须设置足够高的 ndots,以便 DNS 客户端库考虑搜索路径。 在默认情况下,Kubernetes 将这个值设置为 5,这个值足够高,足以覆盖它生成的所有 DNS 名称。
是否存在 Service 能通过 DNS 名称访问?如果上面的方式仍然失败,DNS 查找不到你需要的 Service ,你可以后退一步, 看看还有什么其它东西没有正常工作。 Kubernetes 主 Service 应该一直是工作的。在 Pod 中运行如下命令:
nslookup kubernetes.default Server: 10.0.0.10 Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local Name: kubernetes.default Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local如果失败,你可能需要转到本文的 kube-proxy 节, 或者甚至回到文档的顶部重新开始,但不是调试你自己的 Service ,而是调试 DNS Service。
Service 能够通过 IP 访问么?假设你已经确认 DNS 工作正常,那么接下来要测试的是你的 Service 能否通过它的 IP 正常访问。 从集群中的一个 Pod,尝试访问 Service 的 IP(从上面的 kubectl get 命令获取)。
for i in $(seq 1 3); do wget -qO- 10.0.1.175:80 done输出应该类似这样:
hostnames-632524106-bbpiw hostnames-632524106-ly40y hostnames-632524106-tlaok如果 Service 状态是正常的,你应该得到正确的响应。如果没有,有很多可能出错的地方,请继续阅读。
Service 的配置是否正确?这听起来可能很愚蠢,但你应该两次甚至三次检查你的 Service 配置是否正确,并且与你的 Pod 匹配。 查看你的 Service 配置并验证它:
kubectl get service hostnames -o json { "kind": "Service", "apiVersion": "v1", "metadata": { "name": "hostnames", "namespace": "default", "uid": "428c8b6c-24bc-11e5-936d-42010af0a9bc", "resourceVersion": "347189", "creationTimestamp": "2015-07-07T15:24:29Z", "labels": { "app": "hostnames" } }, "spec": { "ports": [ { "name": "default", "protocol": "TCP", "port": 80, "targetPort": 9376, "nodePort": 0 } ], "selector": { "app": "hostnames" }, "clusterIP": "10.0.1.175", "type": "ClusterIP", "sessionAffinity": "None" }, "status": { "loadBalancer": {} } } 你想要访问的 Service 端口是否在 spec.ports[] 中列出? targetPort 对你的 Pod 来说正确吗(许多 Pod 使用与 Service 不同的端口)? 如果你想使用数值型端口,那么它的类型是一个数值(9376)还是字符串 “9376”? 如果你想使用名称型端口,那么你的 Pod 是否暴露了一个同名端口? 端口的 protocol 和 Pod 的是否对应? Service 有 Endpoints 吗?如果你已经走到了这一步,你已经确认你的 Service 被正确定义,并能通过 DNS 解析。 现在,让我们检查一下,你运行的 Pod 确实是被 Service 选中的。