tanke25616429のアウトプット

IT技術の基本を勉強したことをアウトプットします。Linux、Kubernetes、クラウド中心です。百番煎じくらいだけど誰かの役に立てばそれはそれでうれしい。

KubernetesのServiceにおけるDNS動作の確認方法

背景・目的

Kubernetesではserviceリソースをpodやdeploymentから作成すると、そのKubernetesクラスタ内のコンテナから名前解決ができるようになる。名前解決ができることの確認方法を整理する。

準備:podとserviceの作成

まず、適当なpodを作成する。podのIPが10.244.1.6と割り振られていることがわかる(この値は後で使う)。serviceはデフォルト(タイプはClusterIPとなる)で、ポートは適当に80番で公開することとする。

master $ kubectl run nginx-pod --image=nginx
pod/nginx-pod created
master $ kubectl get pod -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
nginx-pod   1/1     Running   0          8s    10.244.1.6   node01   <none>           <none>
master $ kubectl expose pod nginx-pod --name=nginx-svc --port=80
service/nginx-svc exposed
master $ kubectl describe svc nginx-svc
Name:              nginx-svc
Namespace:         default
Labels:            run=nginx-pod
Annotations:       <none>
Selector:          run=nginx-pod
Type:              ClusterIP
IP:                10.107.129.2
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.6:80
Session Affinity:  None
Events:            <none>

serviceの名前解決の確認

確認のためのクライアントとしてbusyboxのコンテナを作成し、そのコンテナの中からnslookupを使って名前解決を試みる。

master $ kubectl run test --image=busybox:1.28 -it -- sh
If you don't see a command prompt, try pressing enter.
/ # nslookup nginx-svc
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      nginx-svc
Address 1: 10.107.129.2 nginx-svc.default.svc.cluster.local

DNSに渡すクエリとしてサービス名のnginx-svcだけ渡せば名前解決ができる。DNSサーバのアドレスが10.96.0.10となっていることがわかる。これが何ものかは別記事で触れる。

なぜ、サービス名だけでよいのかは/etc/resolv.confを確認するとわかる。search default.svc.cluster.local svc.cluster.local cluster.localと書かれており、補完が効くようになっている。

/ # cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

よって、名前を途中まで入れても同様に名前解決ができる。以下では試していないが、nginx-svc.default.svc.cluster.localとフルで入れても問題ない。

/ # nslookup nginx-svc.default
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      nginx-svc.default
Address 1: 10.107.129.2 nginx-svc.default.svc.cluster.local
/ # nslookup nginx-svc.default.svc
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      nginx-svc.default.svc
Address 1: 10.107.129.2 nginx-svc.default.svc.cluster.local

podの名前解決

pod作成時に付与されたIPアドレスがX.Y.Z.Wだとすると、X-Y-Z-W.default.podでpodに対し名前解決ができる*1。今回はpodのIPが10.244.1.6なので、10-244-1-6.default.podをクエリとして投げると、podのIPが返ってきていることがわかる。

/ # nslookup 10-244-1-6.default.pod
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      10-244-1-6.default.pod
Address 1: 10.244.1.6 10-244-1-6.nginx-svc.default.svc.cluster.local

↑の一番下の行を見ると、10-244-1-6.nginx-svc.default.svc.cluster.localがフルの名前であるようである。実際、10-244-1-6.nginx-svc等、/etc/resolv.confsearchで補完できる投げ方ならば同様に名前解決が可能である。

/ # nslookup 10-244-1-6.nginx-svc
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      10-244-1-6.nginx-svc
Address 1: 10.244.1.6 10-244-1-6.nginx-svc.default.svc.cluster.local

補完できない形で名前解決を試みても失敗する。以下、なんとなくできそうだができない例である。

/ # nslookup 10-244-1-6
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-6'
/ # nslookup nginx-pod.nginx-svc
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

nslookup: can't resolve 'nginx-pod.nginx-svc'

逆引き

IPアドレスから逆引きすることもできる。

/ # nslookup 10.244.1.6
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      10.244.1.6
Address 1: 10.244.1.6 10-244-1-6.nginx-svc.default.svc.cluster.local
/ # nslookup 10.107.129.2
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      10.107.129.2
Address 1: 10.107.129.2 nginx-svc.default.svc.cluster.local

*1:ただ、これではDNSにクエリを投げる時点で、X-Y-Z-Wという文字列がわかっており、ほぼ名前解決できる状態になっているためIPアドレスを知ることが目的ではないように思われる。