DNSについて

DNS for Services and Podsに説明が書いてあるけど、試してみないと今一つわからなかったのでメモを残しておく。

Pod + Service

まずは、普通にendpointとなるPod2つと普通のサービスの構成で色々試してみる。環境はminikube。 マニフェストファイルは下記。

$ cat pod-srv.yaml
apiVersion: v1                                                                  
kind: Service                                                                   
metadata:                                                                       
  name: my-service                                                              
spec:                                                                           
  selector:                                                                     
    name: busybox                                                               
  ports:                                                                        
  - name: foo                                                                   
    port: 1234                                                                  
    targetPort: 5678                                                            
---                                                                             
apiVersion: v1                                                                  
kind: Pod                                                                       
metadata:                                                                       
  name: busybox1                                                                
  labels:                                                                       
    name: busybox                                                               
spec:                                                                                                                           
  containers:                                                                   
  - name: busybox                                                               
    image: busybox                                                              
    command:                                                                    
    - sleep                                                                     
    - "3600"                                                                    
---                                                                             
apiVersion: v1                                                                  
kind: Pod                                                                       
metadata:                                                                       
  name: busybox2                                                                
  labels:                                                                       
    name: busybox                                                               
spec:                                                                                                                                
  containers:                                                                   
  - name: busybox                                                               
    image: busybox                                                              
    command:                                                                    
    - sleep                                                                     
    - "3600"        

このマニフェストでデプロイ。

$ kubectl apply -f stateless-normal-srv.yaml
service "my-service" created
pod "busybox1" created
pod "busybox2" created

名前解決してみるために、適当なPodを作る。

$ kubectl run -it --rm --restart=NEVER --image=centos dns-test -- /bin/sh
If you don't see a command prompt, try pressing enter.
# yum install -y bind-utils

まずはサービス名を名前解決。

# nslookup my-service
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      my-service
Address 1: 10.111.178.2 my-service.default.svc.cluster.local

Aレコードは10.111.178.2 my-service.default.svc.cluster.localでしょう。

次にSRVを確認してみる。 ドキュメントによると、SRVレコードは_<named-port._<protocol>.my-serviceなので、次のコマンドを実行。

# nslookup -q=SRV _foo._tcp.my-service
Server:     10.96.0.10
Address:    10.96.0.10#53

_foo._tcp.my-service.default.svc.cluster.local  service = 10 100 1234 my-service.default.svc.cluster.local.

service = <Priority> <Weight> <Port> <Target>のはずなので、Portが1234でマニフェスト通りとなってることが確認出来る。

Pod + Headless Service

次はHeadless Serviceにして同じことを確認してみる。マニフェストは下記。

$ cat pod-headless-srv.yaml
apiVersion: v1                                                                  
kind: Service                                                                   
metadata:                                                                       
  name: my-service                                                              
spec:                                                                           
  selector:                                                                     
    name: busybox                                                               
  clusterIP: None                                                               
  ports:                                                                        
  - name: foo                                                                   
    port: 1234                                                                  
    targetPort: 5678                                                            
---                                                                             
apiVersion: v1                                                                  
kind: Pod                                                                       
metadata:                                                                       
  name: busybox1                                                                
  labels:                                                                       
    name: busybox                                                               
spec:                                                                           
  containers:                                                                   
  - name: busybox                                                               
    image: busybox                                                              
    command:                                                                    
    - sleep                                                                     
    - "3600"                                                                    
---                                                                             
apiVersion: v1                                                                  
kind: Pod                                                                       
metadata:                                                                       
  name: busybox2                                                                
  labels:                                                                       
    name: busybox                                                               
spec:                                                                           
  containers:                                                                   
  - name: busybox                                                               
    image: busybox                                                              
    command:                                                                    
    - sleep                                                                     
    - "3600"                                                                    

このマニフェストをデプロイして、先程作成したCentOSのコンテナで名前解決してみる。

# nslookup my-service
Server:     10.96.0.10
Address:    10.96.0.10#53

Name:   my-service.default.svc.cluster.local
Address: 172.17.0.4
Name:   my-service.default.svc.cluster.local
Address: 172.17.0.5

先程とは異なり、サービス名で名前解決すると、サービスのendpointとなっているPodのIPが返ってくる。これらがAレコードとして登録されているはず。 次に先程と同様にSRVレコードを確認してみる。

# nslookup -q=SRV _foo._tcp.my-service
Server:     10.96.0.10
Address:    10.96.0.10#53

_foo._tcp.my-service.default.svc.cluster.local  service = 10 50 5678 3237653666313939.my-service.default.svc.cluster.local.
_foo._tcp.my-service.default.svc.cluster.local  service = 10 50 5678 3139376166613530.my-service.default.svc.cluster.local.

各Podに適当なサブドメインが割り当てられてる。kube-dnsが勝手に付ける模様。そして、PortもServiceのPortではなく、Serviceで定義したtargetPortの値になってますね。まあ、これはPodのFQDNが各々返ってきてるので当然ですね。

ついでにPodのFQDNで名前解決してみる。

# nslookup 3237653666313939.my-service.default.svc.cluster.local
Server:     10.96.0.10
Address:    10.96.0.10#53

Name:   3237653666313939.my-service.default.svc.cluster.local
Address: 172.17.0.4

# nslookup 3139376166613530.my-service.default.svc.cluster.local
Server:     10.96.0.10
Address:    10.96.0.10#53

Name:   3139376166613530.my-service.default.svc.cluster.local
Address: 172.17.0.5

ちゃんとPodのIPが返ってきますね。