kubernetes v1.18:Pods 的 DNS 解析记录
kubernetes v1.18: DNS resolution records for Pods
问题是针对 kubernetes 中的 pods DNS 解析。来自官方文档的声明(从右上角的下拉列表中选择 v1.18):
https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pods
Pods.
A/AAAA records
Any pods created by a Deployment or DaemonSet have the following DNS resolution available:
pod-ip-address.deployment-name.my-namespace.svc.cluster-domain.example.
这是我的 kubernetes 环境:
master $ kubectl version
Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.0", GitCommit:"9e991415386e4cf155a24b1da15becaa390438d8", GitTreeState:"clean", BuildDate:"2020-03-25T14:58:59Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.0", GitCommit:"9e991415386e4cf155a24b1da15becaa390438d8", GitTreeState:"clean", BuildDate:"2020-03-25T14:50:46Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"}
在我使用 kubectl create deploy nginx --image=nginx
创建一个简单的部署之后,我在 test
命名空间中创建了一个 busybox pod 来像这样执行 nslookup:
kubectl create ns test
cat <<EOF | kubectl apply -n test -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox1
labels:
name: busybox
spec:
containers:
- image: busybox:1.28
command:
- sleep
- "3600"
name: busybox
EOF
然后我nslookup
这样,根据官方文档pod-ip-address.deployment-name.my-namespace.svc.cluster-domain.example
:
master $ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-f89759699-h8cj9 1/1 Running 0 12m 10.244.1.4 node01 <none> <none>
master $ kubectl get deploy -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx 1/1 1 1 17m nginx nginx app=nginx
master $ kubectl exec -it busybox1 -n test -- nslookup 10.244.1.4.nginx.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
nslookup: can't resolve '10.244.1.4.nginx.default.svc.cluster.local'
command terminated with exit code 1
master $ kubectl exec -it busybox1 -n test -- nslookup 10-244-1-4.nginx.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
nslookup: can't resolve '10-244-1-4.nginx.default.svc.cluster.local'
command terminated with exit code 1
问题 1:
为什么 nslookup 查找名称失败?是不是我做错了什么?
当我继续探索 pods 的 dns 名称时,我这样做了:
master $ kubectl exec -it busybox1 -n test -- nslookup 10-244-1-4.default.pod.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: 10-244-1-4.default.pod.cluster.local
Address 1: 10.244.1.4
master $ kubectl exec -it busybox1 -n test -- nslookup 10-244-1-4.test.pod.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: 10-244-1-4.test.pod.cluster.local
Address 1: 10.244.1.4
问题二:
为什么10.244.1.4的pod在default namespace里nslookup 10-244-1-4.test.pod.cluster.local
也成功了?
对于问题1,可能是文档不准确。如果我为部署创建 ClusterIP 服务:
kubectl expose deploy nginx --name=front-end --port=80
然后我可以看到这个名字:
kubectl exec -it busybox1 -n test -- nslookup 10-244-1-4.front-end.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: 10-244-1-4.front-end.default.svc.cluster.local
Address 1: 10.244.1.4 10-244-1-4.front-end.default.svc.cluster.local
关于你的第一个问题,据我所知你的假设是正确的,文档似乎不准确。 pods 的 A/AAAA 参考是文档 (1.18) 中的新内容。为此,我强烈建议您提出一个问题 here,以便开发人员可以更深入地研究它。
我建议您在这方面参考 1.17 documentation,因为它反映了实际情况。
在1.17中我们可以看到这个注释:
Note: Because A or AAAA records are not created for Pod names, hostname
is required for the Pod’s A or AAAA record to be created. A Pod with no hostname
but with subdomain
will only create the A or AAAA record for the headless service (default-subdomain.my-namespace.svc.cluster-domain.example
), pointing to the Pod’s IP address. Also, Pod needs to become ready in order to have a record unless publishNotReadyAddresses=True
is set on the Service.
据我所知,这在 1.18 上仍然是正确的,尽管文档是这么说的。
关于问题二的方向相同,您也可以提出一个问题,但我个人看不出有任何使用基于 IP 的 DNS 名称的实际原因。这些名称供 kubernetes 内部使用,使用它不会给您带来任何优势。
最佳方案是在 Kubernetes 上使用 service based dns names。它被证明是非常可靠的。
问题是针对 kubernetes 中的 pods DNS 解析。来自官方文档的声明(从右上角的下拉列表中选择 v1.18): https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pods
Pods.
A/AAAA records
Any pods created by a Deployment or DaemonSet have the following DNS resolution available:
pod-ip-address.deployment-name.my-namespace.svc.cluster-domain.example.
这是我的 kubernetes 环境:
master $ kubectl version
Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.0", GitCommit:"9e991415386e4cf155a24b1da15becaa390438d8", GitTreeState:"clean", BuildDate:"2020-03-25T14:58:59Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.0", GitCommit:"9e991415386e4cf155a24b1da15becaa390438d8", GitTreeState:"clean", BuildDate:"2020-03-25T14:50:46Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"}
在我使用 kubectl create deploy nginx --image=nginx
创建一个简单的部署之后,我在 test
命名空间中创建了一个 busybox pod 来像这样执行 nslookup:
kubectl create ns test
cat <<EOF | kubectl apply -n test -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox1
labels:
name: busybox
spec:
containers:
- image: busybox:1.28
command:
- sleep
- "3600"
name: busybox
EOF
然后我nslookup
这样,根据官方文档pod-ip-address.deployment-name.my-namespace.svc.cluster-domain.example
:
master $ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-f89759699-h8cj9 1/1 Running 0 12m 10.244.1.4 node01 <none> <none>
master $ kubectl get deploy -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx 1/1 1 1 17m nginx nginx app=nginx
master $ kubectl exec -it busybox1 -n test -- nslookup 10.244.1.4.nginx.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
nslookup: can't resolve '10.244.1.4.nginx.default.svc.cluster.local'
command terminated with exit code 1
master $ kubectl exec -it busybox1 -n test -- nslookup 10-244-1-4.nginx.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
nslookup: can't resolve '10-244-1-4.nginx.default.svc.cluster.local'
command terminated with exit code 1
问题 1:
为什么 nslookup 查找名称失败?是不是我做错了什么?
当我继续探索 pods 的 dns 名称时,我这样做了:
master $ kubectl exec -it busybox1 -n test -- nslookup 10-244-1-4.default.pod.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: 10-244-1-4.default.pod.cluster.local
Address 1: 10.244.1.4
master $ kubectl exec -it busybox1 -n test -- nslookup 10-244-1-4.test.pod.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: 10-244-1-4.test.pod.cluster.local
Address 1: 10.244.1.4
问题二:
为什么10.244.1.4的pod在default namespace里nslookup 10-244-1-4.test.pod.cluster.local
也成功了?
对于问题1,可能是文档不准确。如果我为部署创建 ClusterIP 服务:
kubectl expose deploy nginx --name=front-end --port=80
然后我可以看到这个名字:
kubectl exec -it busybox1 -n test -- nslookup 10-244-1-4.front-end.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: 10-244-1-4.front-end.default.svc.cluster.local
Address 1: 10.244.1.4 10-244-1-4.front-end.default.svc.cluster.local
关于你的第一个问题,据我所知你的假设是正确的,文档似乎不准确。 pods 的 A/AAAA 参考是文档 (1.18) 中的新内容。为此,我强烈建议您提出一个问题 here,以便开发人员可以更深入地研究它。
我建议您在这方面参考 1.17 documentation,因为它反映了实际情况。
在1.17中我们可以看到这个注释:
Note: Because A or AAAA records are not created for Pod names,
hostname
is required for the Pod’s A or AAAA record to be created. A Pod with nohostname
but withsubdomain
will only create the A or AAAA record for the headless service (default-subdomain.my-namespace.svc.cluster-domain.example
), pointing to the Pod’s IP address. Also, Pod needs to become ready in order to have a record unlesspublishNotReadyAddresses=True
is set on the Service.
据我所知,这在 1.18 上仍然是正确的,尽管文档是这么说的。
关于问题二的方向相同,您也可以提出一个问题,但我个人看不出有任何使用基于 IP 的 DNS 名称的实际原因。这些名称供 kubernetes 内部使用,使用它不会给您带来任何优势。
最佳方案是在 Kubernetes 上使用 service based dns names。它被证明是非常可靠的。