Kubernetes DNS 查找问题和 /etc/resolv.conf 文件中的 "invalid"
Kubernetes DNS lookup issue and "invalid" in the /etc/resolv.conf file
我已经使用 kubeadm
和 Flannel 网络驱动程序部署了一个由一个 master 和两个 worker 组成的 Kubernetes 集群(所以我将 --pod-network-cidr=10.244.0.0/16
标志传递给 kubeadm init
)。
这些节点使用 VPN 一起通信,因此:
- 主节点IP地址为10.0.0.170
- 工人 1 IP 地址为 10.0.0.247
- 工人 2 IP 地址为 10.0.0.35
当我创建一个新 pod 并尝试 ping google 时,出现以下错误:
/ # ping google.com
ping: bad address 'google.com'
我遵循了 Kubernetes DNS debugging resolution 文档页面中的说明:
$ kubectl exec -ti busybox -- nslookup kubernetes.default
Server: 10.96.0.10
Address 1: 10.96.0.10
nslookup: can't resolve 'kubernetes.default'
command terminated with exit code 1
先检查本地DNS配置
$ kubectl exec busybox cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local invalid
options ndots:5
检查 DNS pod 是否 运行
$ kubectl get pods --namespace=kube-system -l k8s-app=kube-dns
NAME READY STATUS RESTARTS AGE
coredns-5c98db65d4-cqzb7 1/1 Running 0 7d18h
coredns-5c98db65d4-xc5d7 1/1 Running 0 7d18h
检查 DNS pod 中的错误
$ for p in $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name); do kubectl logs --namespace=kube-system $p; done
.:53
2019-10-28T13:40:41.834Z [INFO] CoreDNS-1.3.1
2019-10-28T13:40:41.834Z [INFO] linux/amd64, go1.11.4, 6b56a9c
CoreDNS-1.3.1
linux/amd64, go1.11.4, 6b56a9c
2019-10-28T13:40:41.834Z [INFO] plugin/reload: Running configuration MD5 = 5d5369fbc12f985709b924e721217843
.:53
2019-10-28T13:40:42.870Z [INFO] CoreDNS-1.3.1
2019-10-28T13:40:42.870Z [INFO] linux/amd64, go1.11.4, 6b56a9c
CoreDNS-1.3.1
linux/amd64, go1.11.4, 6b56a9c
2019-10-28T13:40:42.870Z [INFO] plugin/reload: Running configuration MD5 = 5d5369fbc12f985709b924e721217843
DNS 服务启动了吗?
$ kubectl get svc --namespace=kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 7d18h
DNS 端点是否暴露?
$ kubectl get ep kube-dns --namespace=kube-system
NAME ENDPOINTS AGE
kube-dns 10.244.0.3:53,10.244.0.4:53,10.244.0.3:53 + 3 more... 7d18h
DNS 查询是否 received/processed?
我对 coredns ConfigMap 进行了更新,运行 再次使用 nslookup kubernetes.default
命令,结果如下:
$ for p in $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name); do kubectl logs --namespace=kube-system $p; done
.:53
2019-10-28T13:40:41.834Z [INFO] CoreDNS-1.3.1
2019-10-28T13:40:41.834Z [INFO] linux/amd64, go1.11.4, 6b56a9c
CoreDNS-1.3.1
linux/amd64, go1.11.4, 6b56a9c
2019-10-28T13:40:41.834Z [INFO] plugin/reload: Running configuration MD5 = 5d5369fbc12f985709b924e721217843
[INFO] Reloading
2019-11-05T08:12:12.511Z [INFO] plugin/reload: Running configuration MD5 = 906291470f7b1db8bef629bdd0056cad
[INFO] Reloading complete
2019-11-05T08:12:12.608Z [INFO] 127.0.0.1:55754 - 7434 "HINFO IN 4808438627636259158.5471394156194192600. udp 57 false 512" NXDOMAIN qr,rd,ra 132 0.095189791s
.:53
2019-10-28T13:40:42.870Z [INFO] CoreDNS-1.3.1
2019-10-28T13:40:42.870Z [INFO] linux/amd64, go1.11.4, 6b56a9c
CoreDNS-1.3.1
linux/amd64, go1.11.4, 6b56a9c
2019-10-28T13:40:42.870Z [INFO] plugin/reload: Running configuration MD5 = 5d5369fbc12f985709b924e721217843
[INFO] Reloading
2019-11-05T08:12:47.988Z [INFO] plugin/reload: Running configuration MD5 = 906291470f7b1db8bef629bdd0056cad
[INFO] Reloading complete
2019-11-05T08:12:48.004Z [INFO] 127.0.0.1:51911 - 60104 "HINFO IN 4077052818408395245.3902243105088660270. udp 57 false 512" NXDOMAIN qr,rd,ra 132 0.016522153s
看来 DNS pods 正在接收请求。
但我已经有这个错误了!
我第一次部署集群时发生了这个错误。
当时,我注意到 kubectl get nodes -o wide
将工作节点 public IP 地址显示为 "INTERNAL-IP" 而不是私有地址。
进一步观察,我发现在工作节点上,kubelet 缺少 --node-ip
标志,所以我添加了它并重新启动了 Kubelet,问题就消失了。然后我得出结论,缺少标志是原因,但似乎并非如此,因为 kubectl get nodes -o wide
命令显示工作人员的内部 IP 地址为 "INTERNAL-IP"。
现在
DNS 服务器 IP 地址 10.96.0.10 在我看来是错误的,我无法从 pod ping 通它。 DNS pods 的 IP 地址为 10.244.0.3 和 10.244.0.4,我也无法 ping 通。
我刚刚尝试删除 coredns pods,以便重新安排它们,现在它们的 IP 地址已更改,我可以从 pod ping 它们并且 kubectl exec -ti busybox -- nslookup kubernetes.default
有效:
$ kubectl exec -ti busybox -- nslookup kubernetes.default
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes.default
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
但是resolv.conf
文件里面还有"invalid":
$ kubectl exec busybox cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local invalid
options ndots:5
- 谁能解释一下发生了什么事?
- 如何从
resolv.conf
文件中解决此 "invalid"?
在CoreDNS ConfigMap中配置默认上游名称服务器是从节点继承的,即集群域之外的所有内容(.cluster.local)
因此 "invalid" 是在创建 Pod 期间从 Node 的 /etc/resolv.conf
文件复制的条目。
如果您手动修改节点上的 /etc/resolv.conf
,则具有 dnsPolicy: ClusterFirst
的每个 Pod 都将通过此修改继承 /etc/resolv.conf
。
因此,在将 --node-ip
标志添加到 kubelet 并重新启动 CoreDNS Pods 之后,您应该重新部署您的 busybox Pod,以便它可以从节点继承 /etc/resolv.conf
。
我已经使用 kubeadm
和 Flannel 网络驱动程序部署了一个由一个 master 和两个 worker 组成的 Kubernetes 集群(所以我将 --pod-network-cidr=10.244.0.0/16
标志传递给 kubeadm init
)。
这些节点使用 VPN 一起通信,因此:
- 主节点IP地址为10.0.0.170
- 工人 1 IP 地址为 10.0.0.247
- 工人 2 IP 地址为 10.0.0.35
当我创建一个新 pod 并尝试 ping google 时,出现以下错误:
/ # ping google.com
ping: bad address 'google.com'
我遵循了 Kubernetes DNS debugging resolution 文档页面中的说明:
$ kubectl exec -ti busybox -- nslookup kubernetes.default
Server: 10.96.0.10
Address 1: 10.96.0.10
nslookup: can't resolve 'kubernetes.default'
command terminated with exit code 1
先检查本地DNS配置
$ kubectl exec busybox cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local invalid
options ndots:5
检查 DNS pod 是否 运行
$ kubectl get pods --namespace=kube-system -l k8s-app=kube-dns
NAME READY STATUS RESTARTS AGE
coredns-5c98db65d4-cqzb7 1/1 Running 0 7d18h
coredns-5c98db65d4-xc5d7 1/1 Running 0 7d18h
检查 DNS pod 中的错误
$ for p in $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name); do kubectl logs --namespace=kube-system $p; done
.:53
2019-10-28T13:40:41.834Z [INFO] CoreDNS-1.3.1
2019-10-28T13:40:41.834Z [INFO] linux/amd64, go1.11.4, 6b56a9c
CoreDNS-1.3.1
linux/amd64, go1.11.4, 6b56a9c
2019-10-28T13:40:41.834Z [INFO] plugin/reload: Running configuration MD5 = 5d5369fbc12f985709b924e721217843
.:53
2019-10-28T13:40:42.870Z [INFO] CoreDNS-1.3.1
2019-10-28T13:40:42.870Z [INFO] linux/amd64, go1.11.4, 6b56a9c
CoreDNS-1.3.1
linux/amd64, go1.11.4, 6b56a9c
2019-10-28T13:40:42.870Z [INFO] plugin/reload: Running configuration MD5 = 5d5369fbc12f985709b924e721217843
DNS 服务启动了吗?
$ kubectl get svc --namespace=kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 7d18h
DNS 端点是否暴露?
$ kubectl get ep kube-dns --namespace=kube-system
NAME ENDPOINTS AGE
kube-dns 10.244.0.3:53,10.244.0.4:53,10.244.0.3:53 + 3 more... 7d18h
DNS 查询是否 received/processed?
我对 coredns ConfigMap 进行了更新,运行 再次使用 nslookup kubernetes.default
命令,结果如下:
$ for p in $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name); do kubectl logs --namespace=kube-system $p; done
.:53
2019-10-28T13:40:41.834Z [INFO] CoreDNS-1.3.1
2019-10-28T13:40:41.834Z [INFO] linux/amd64, go1.11.4, 6b56a9c
CoreDNS-1.3.1
linux/amd64, go1.11.4, 6b56a9c
2019-10-28T13:40:41.834Z [INFO] plugin/reload: Running configuration MD5 = 5d5369fbc12f985709b924e721217843
[INFO] Reloading
2019-11-05T08:12:12.511Z [INFO] plugin/reload: Running configuration MD5 = 906291470f7b1db8bef629bdd0056cad
[INFO] Reloading complete
2019-11-05T08:12:12.608Z [INFO] 127.0.0.1:55754 - 7434 "HINFO IN 4808438627636259158.5471394156194192600. udp 57 false 512" NXDOMAIN qr,rd,ra 132 0.095189791s
.:53
2019-10-28T13:40:42.870Z [INFO] CoreDNS-1.3.1
2019-10-28T13:40:42.870Z [INFO] linux/amd64, go1.11.4, 6b56a9c
CoreDNS-1.3.1
linux/amd64, go1.11.4, 6b56a9c
2019-10-28T13:40:42.870Z [INFO] plugin/reload: Running configuration MD5 = 5d5369fbc12f985709b924e721217843
[INFO] Reloading
2019-11-05T08:12:47.988Z [INFO] plugin/reload: Running configuration MD5 = 906291470f7b1db8bef629bdd0056cad
[INFO] Reloading complete
2019-11-05T08:12:48.004Z [INFO] 127.0.0.1:51911 - 60104 "HINFO IN 4077052818408395245.3902243105088660270. udp 57 false 512" NXDOMAIN qr,rd,ra 132 0.016522153s
看来 DNS pods 正在接收请求。
但我已经有这个错误了!
我第一次部署集群时发生了这个错误。
当时,我注意到 kubectl get nodes -o wide
将工作节点 public IP 地址显示为 "INTERNAL-IP" 而不是私有地址。
进一步观察,我发现在工作节点上,kubelet 缺少 --node-ip
标志,所以我添加了它并重新启动了 Kubelet,问题就消失了。然后我得出结论,缺少标志是原因,但似乎并非如此,因为 kubectl get nodes -o wide
命令显示工作人员的内部 IP 地址为 "INTERNAL-IP"。
现在
DNS 服务器 IP 地址 10.96.0.10 在我看来是错误的,我无法从 pod ping 通它。 DNS pods 的 IP 地址为 10.244.0.3 和 10.244.0.4,我也无法 ping 通。
我刚刚尝试删除 coredns pods,以便重新安排它们,现在它们的 IP 地址已更改,我可以从 pod ping 它们并且 kubectl exec -ti busybox -- nslookup kubernetes.default
有效:
$ kubectl exec -ti busybox -- nslookup kubernetes.default
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes.default
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
但是resolv.conf
文件里面还有"invalid":
$ kubectl exec busybox cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local invalid
options ndots:5
- 谁能解释一下发生了什么事?
- 如何从
resolv.conf
文件中解决此 "invalid"?
在CoreDNS ConfigMap中配置默认上游名称服务器是从节点继承的,即集群域之外的所有内容(.cluster.local)
因此 "invalid" 是在创建 Pod 期间从 Node 的 /etc/resolv.conf
文件复制的条目。
如果您手动修改节点上的 /etc/resolv.conf
,则具有 dnsPolicy: ClusterFirst
的每个 Pod 都将通过此修改继承 /etc/resolv.conf
。
因此,在将 --node-ip
标志添加到 kubelet 并重新启动 CoreDNS Pods 之后,您应该重新部署您的 busybox Pod,以便它可以从节点继承 /etc/resolv.conf
。