47
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Kubernetes1.10 Cluster内DNSの挙動確認

Last updated at Posted at 2018-05-02

はじめに

Kubernetesの公式ページに、多くのチュートリアルが掲載されています。
Kubernetesの勉強の一環で、チュートリアルを消化していきます。
今回は Kubernetesクラスタ内部で使用するDNSを勉強していきます。

通常のServiceの名前解決

Kubernetesクラスタのすべてのサービスは、DNS名が割り当てられています。KubernetesがPodを作成した時に、Pod内部の /etc/resolv.conf に、ネームスペースとデフォルトドメインが含まれた search list が自動的に設定されます。

同一ネームスペース内で名前解決(PodtoService)

Service名が foo1 で Namespaceが bar のものを作成して、動作を確認します。

まず、Namsespace bar を作成します

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl create namespace bar
namespace "bar" created

kubensコマンドを使用して、bar ネームスペースへ切り替えます

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubens bar
Context "kubernetes-admin@kubernetes" modified.
Active namespace is "bar".
[root@sugi-kubernetes110-master01 ~(bar kubernetes-admin)]# 

CentOSのPodを作成するために、以下のマニフェストファイルを生成します。

cat <<'EOF' > /root/kube_yaml/dns/centos_pod.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: centos
spec:
  selector:
    matchLabels:
      app: centos
  replicas: 2
  template:
    metadata:
      labels:
        app: centos
    spec:
      containers:
      - name: centos
        image: centos
        command: [ "sleep", "3600" ]
EOF

CentOSのPodを作成します

kubectl create -f /root/kube_yaml/dns/centos_pod.yaml

Pod一覧を確認します

[root@sugi-kubernetes110-master01 ~(bar kubernetes-admin)]# kubectl get pod -o wide 
NAME                     READY     STATUS        RESTARTS   AGE       IP            NODE
centos-749b5dff6-hhhnr   1/1       Running       0          32s       10.244.1.26   sugi-kubernetes110-node01.localdomain
centos-749b5dff6-xwdfw   1/1       Running       0          32s       10.244.2.24   sugi-kubernetes110-node02.localdomain

次に Service foo1 を作成します

cat <<'EOF' > /root/kube_yaml/dns/foo1_service.yaml
apiVersion: v1
kind: Service
metadata:
  name: foo1
  labels:
    app: foo1
spec:
  ports:
  - protocol: TCP
    name: foo1portname
    port: 6379
    targetPort: 6380
  selector:
    app: foo1
EOF

Serviceを作成します

kubectl create -f /root/kube_yaml/dns/foo1_service.yaml

Service一覧を確認します

[root@sugi-kubernetes110-master01 ~(bar kubernetes-admin)]# kubectl get svc -o wide --all-namespaces
NAMESPACE     NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE       SELECTOR
bar           foo1         ClusterIP   10.109.77.128   <none>        6379/TCP        3m        app=foo1
default       kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP         3d        <none>
kube-system   kube-dns     ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP   3d        k8s-app=kube-dns

Serviceの詳細を確認します

[root@sugi-kubernetes110-master01 ~(bar kubernetes-admin)]# kubectl describe svc foo1 
Name:              foo1
Namespace:         bar
Labels:            app=foo1
Annotations:       <none>
Selector:          app=foo1
Type:              ClusterIP
IP:                10.109.77.128
Port:              foo1portname  6379/TCP
TargetPort:        6380/TCP
Endpoints:         <none>
Session Affinity:  None
Events:            <none>

CentOSのshellへログインします

kubectl exec -it centos-749b5dff6-hhhnr bash

nslookup及びdigをインストールします

yum install bind-utils

resolv.confを確認します
kube-dns サービスの ClusterIPを nameserverとして使用しています。
また、searchには、 namespace名.svc.デフォルトドメイン名 という形で定義されています。

[root@centos-749b5dff6-hhhnr /]# cat /etc/resolv.conf 
nameserver 10.96.0.10
search bar.svc.cluster.local svc.cluster.local cluster.local localdomain
options ndots:5

foo1 を nslookupすると、名前解決が出来ます
barネームスペースのfoo1サービスに紐づけされている ClusterIP が名前解決出来ます

[root@centos-749b5dff6-hhhnr /]# nslookup foo1
Server:         10.96.0.10
Address:        10.96.0.10#53

Name:   foo1.bar.svc.cluster.local
Address: 10.109.77.128

IPアドレスはわかりましたが、ClusterIPに紐づくポート番号が、上記では確認できません。
KubernetesのDNSでは、サービスのIPアドレスに紐づくポート番号を通知するため、SRV レコードを使用しています。

KubernetesでSRVレコードを使用するために、Serviceの定義を下記のように name と protocol フィールドの指定が必要です

略
spec:
  ports:
  - protocol: TCP
    name: foo1portname
    port: 6379
    targetPort: 6380
略

これに対してnslookupでsrvレコードを取得するには、以下のようにコマンドから対話形式で実行できます

[root@centos-749b5dff6-hhhnr /]# nslookup 
> set type=SRV
> _foo1portname._tcp.foo1
Server:         10.96.0.10
Address:        10.96.0.10#53

_foo1portname._tcp.foo1.bar.svc.cluster.local   service = 10 100 6379 foo1.bar.svc.cluster.local.
> exit
[root@centos-749b5dff6-hhhnr /]# 

名前解決の結果を確認すると、「ervice = 10 100 6379 foo1.bar.svc.cluster.local.」となっています。
数字の意味は下記の内容となっています。

  • 10 : プライオリティ
  • 100 : ウェイト
  • 6379 : ポート番号 (Serviceのportで指定した番号)

整理すると、Pod内のアプリケーションが別のPodにアクセスしたい場合、以下の2パターンが考えられます

  • ServiceのIPアドレスを知りたい場合 : 「サービス名」を使用してKubernetesのDNSに問い合わせすることで、IPアドレスを正引きすることが出来ます。
  • ServiceのIPアドレスと、ポート番号を知りたい場合 : 「サービス名」「ポート名」「プロトコル」を使用してKubernetesのDNSに問い合わせすることで、IPアドレスとポート番号を取得することが出来ます。

別のネームスペースから名前解決

quux という名前のネームスペースを作成

[root@sugi-kubernetes110-master01 ~(bar kubernetes-admin)]# kubectl create namespace quux
namespace "quux" created

ネームスペースの切り替え

[root@sugi-kubernetes110-master01 ~(bar kubernetes-admin)]# kubens quux
Context "kubernetes-admin@kubernetes" modified.
Active namespace is "quux".
[root@sugi-kubernetes110-master01 ~(quux kubernetes-admin)]# 

CentOSのPodを作成

cat <<'EOF' > /root/kube_yaml/dns/centos_pod.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: centos
spec:
  selector:
    matchLabels:
      app: centos
  replicas: 1
  template:
    metadata:
      labels:
        app: centos
    spec:
      containers:
      - name: centos
        image: centos
        command: [ "sleep", "3600" ]
EOF

Deploymentを作成

[root@sugi-kubernetes110-master01 ~(quux kubernetes-admin)]# kubectl create -f /root/kube_yaml/dns/centos_pod.yaml
deployment.apps "centos" created

確認

[root@sugi-kubernetes110-master01 ~(quux kubernetes-admin)]# kubectl get pods -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP            NODE
centos-749b5dff6-plkc8   1/1       Running   0          24s       10.244.2.25   sugi-kubernetes110-node02.localdomain

bashにログイン

[root@sugi-kubernetes110-master01 ~(quux kubernetes-admin)]# kubectl exec centos-749b5dff6-plkc8 -it bash
[root@centos-749b5dff6-plkc8 /]# 

bind-utilsをインストール

yum install -y bind-utils

resolv.confを確認します
quux ネームスペースなので、search lust には quux が含まれています

[root@centos-749b5dff6-plkc8 /]# cat /etc/resolv.conf 
nameserver 10.96.0.10
search quux.svc.cluster.local svc.cluster.local cluster.local localdomain
options ndots:5

barネームスペースの foo1 は、suffixを省略すると名前解決できません

[root@centos-749b5dff6-plkc8 /]# nslookup foo1   
Server:         10.96.0.10
Address:        10.96.0.10#53

** server can't find foo1: NXDOMAIN

foo1.bar と付与することで、名前解決が出来ます。

[root@centos-749b5dff6-plkc8 /]# nslookup foo1.bar
Server:         10.96.0.10
Address:        10.96.0.10#53

Name:   foo1.bar.svc.cluster.local
Address: 10.109.77.128

同等に、SRVレコードも取得できます

[root@centos-749b5dff6-plkc8 /]# nslookup 
> set type=SRV
> _foo1portname._tcp.foo1.bar
Server:         10.96.0.10
Address:        10.96.0.10#53

_foo1portname._tcp.foo1.bar.svc.cluster.local   service = 10 100 6379 foo1.bar.svc.cluster.local.

異なるネームスペースのServiceとアクセスが出来るかは別の設定に依存します。
ネットワークプラグインによって、NetworkPolicyで分離されていれば通信ができません。
なお、私が検証している環境は、Flannelを使用しています。これは現在NetworkPolixyは実装されていないので、別のネームスペース間でも接続が出来ます。

Headlessサービスの名前解決

Headlessサービスとは、Serviceを利用したLoadbalanceが不要な時に使用します。Serviceを作成するときに、spec.clusterIP を none にすると作成することが出来ます。
Headlessサービスを使用すると、KuberenetesのLoadbalanceサービスを使用せずに、独自に実装した方法でサービスディスカバリーを行う事が出来ます。

Headlessサービスでは、kube-proxyは何も介さず、ロードバランスもプロキシも稼働しません。
このときDNSがどのように割り当てられるかは、ServiceのSelector定義に依存します。

selectorsあり

Serviceのselectorを有りにすると、Podからサービスの名前解決を行った際に、Serviceに属している全てのPodのIPアドレスを名前解決する方式となります。
通常のサービスは、上の項目でも検証した通り、Serviceに紐づくClusterIPが名前解決されます。
Headlessは特殊な方式なので、通常は使用しないと思います。

どういう時に使用することが有るか考えると以下のパターンが考えられるでしょうか。

  • ClusterIPサービスのロードバランスに偏りがあり、クライアント側で任意にロードバランスしたい
  • Kubernetesのポリシーには違反するが、複数あるPodのうち1個のみ使用してアクセスしたい

selectorsありでHeadlessサービスを作成すると、endpoints controllerは、Endpointオブジェクトを作成し、DNSレコードを変更します。

Headless selectorありの動作を確認するために、以下のDeploymentとServiceを作成します。

cat <<'EOF' > /root/kube_yaml/dns/nginx-deployment.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 80
EOF

Deploymentを作成します

kubectl apply -f /root/kube_yaml/dns/nginx-deployment.yaml

Serviceを作成するために、以下にマニフェストファイルを作成します

cat <<'EOF' > /root/kube_yaml/dns/nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx
spec:
  ports:
  - protocol: TCP
    name: nginx-service-portname
    port: 15315
    targetPort: 80
  clusterIP: None
  selector:
    app: nginx
EOF

Serviceを作成します

kubectl apply -f /root/kube_yaml/dns/nginx-service.yaml

一覧を確認します

[root@sugi-kubernetes110-master01 dns(bar kubernetes-admin)]# kubectl get svc -o wide
NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)     AGE       SELECTOR
nginx-service   ClusterIP   None         <none>        15315/TCP   7s        app=nginx

詳細を確認します

[root@sugi-kubernetes110-master01 dns(bar kubernetes-admin)]# kubectl describe svc nginx-service 
Name:              nginx-service
Namespace:         bar
Labels:            app=nginx
Annotations:       kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"nginx"},"name":"nginx-service","namespace":"bar"},"spec":{"clusterIP"...
Selector:          app=nginx
Type:              ClusterIP
IP:                None
Port:              nginx-service-portname  15315/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.27:80,10.244.2.26:80
Session Affinity:  None
Events:            <none>

以下のendpoint一覧を確認します
Serviceと連携して、自動的に作成されています

[root@sugi-kubernetes110-master01 dns(bar kubernetes-admin)]# kubectl get endpoints 
NAME            ENDPOINTS                       AGE
nginx-service   10.244.1.27:80,10.244.2.26:80   1m

endpointで使用されているIPアドレスは、Podに自動付与されているIPアドレスとなっている

[root@sugi-kubernetes110-master01 dns(bar kubernetes-admin)]# kubectl get pods -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP            NODE
nginx-5c9845d857-5tvlt   1/1       Running   0          9m        10.244.1.27   sugi-kubernetes110-node01.localdomain
nginx-5c9845d857-vlgl2   1/1       Running   0          9m        10.244.2.26   sugi-kubernetes110-node02.localdomain

nslookupを実行するために、CentOSのPodを作成し、bashにログインします

kubectl create -f /root/kube_yaml/dns/centos_pod.yaml
kubectl exec centos-749b5dff6-bpcrb -it bash

nslookupをインストールします

yum install -y bind-utils

nslookupでHeadlessServiceの名前解決を実施すると全てのPodのIPアドレスがreturnされていることを確認できます。

[root@centos-749b5dff6-bpcrb /]# nslookup nginx-service
Server:         10.96.0.10
Address:        10.96.0.10#53

Name:   nginx-service.bar.svc.cluster.local
Address: 10.244.1.27
Name:   nginx-service.bar.svc.cluster.local
Address: 10.244.2.26

selectorsなし (ServiceType : ExternalNameの別の名称)

selectorなしでHeadlessサービスを作成すると、Endpointオブジェクトは作成されません。DNSのCNAMEとして、ServiceのExternalNameが登録されます。

動作を確認するため以下のマニフェストファイルを作成します

cat <<'EOF' > /root/kube_yaml/dns/nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-headless-noselector
  labels:
    app: nginx
spec:
  type: ExternalName
  externalName: 10.132.253.39
EOF

Serviceの作成

kubectl apply -f /root/kube_yaml/dns/nginx-service.yaml

Serviceの一覧確認

[root@sugi-kubernetes110-master01 ~(bar kubernetes-admin)]# kubectl get svc
NAME                        TYPE           CLUSTER-IP   EXTERNAL-IP     PORT(S)     AGE
nginx-headless-noselector   ExternalName   <none>       10.132.253.39   <none>      5s
nginx-service               ClusterIP      None         <none>          15315/TCP   53m

詳細を確認

[root@sugi-kubernetes110-master01 ~(bar kubernetes-admin)]# kubectl describe svc nginx-headless-noselector 
Name:              nginx-headless-noselector
Namespace:         bar
Labels:            app=nginx
Annotations:       kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"nginx"},"name":"nginx-headless-noselector","namespace":"bar"},"spec":...
Selector:          <none>
Type:              ExternalName
IP:                
External Name:     10.132.253.39
Session Affinity:  None
Events:            <none>

podからserviceの名前解決を実施すると、上記のExternalIPの名前解決が出来ます
IPアドレスを指定すると、Aレコードが返ってきます

[root@centos-749b5dff6-bpcrb /]# nslookup nginx-headless-noselector 
Server:         10.96.0.10
Address:        10.96.0.10#53

Name:   nginx-headless-noselector.bar.svc.cluster.local
Address: 10.132.253.39

別のパターン
IPアドレスの代わりに、hostnameを指定

cat <<'EOF' > /root/kube_yaml/dns/nginx-service-name.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-headless-noselector
  labels:
    app: nginx
spec:
  type: ExternalName
  externalName: www.google.co.jp
EOF

apply

kubectl apply -f /root/kube_yaml/dns/nginx-service-name.yaml

nslookupすると、CNAMEレコードとして 「www.google.co.jp」が返ってきて、それを名前解決しています

[root@centos-749b5dff6-bpcrb /]# nslookup nginx-headless-noselector 
Server:         10.96.0.10
Address:        10.96.0.10#53

Non-authoritative answer:
nginx-headless-noselector.bar.svc.cluster.local canonical name = www.google.co.jp.
Name:   www.google.co.jp
Address: 172.217.27.67

digの結果

[root@centos-749b5dff6-bpcrb /]# dig nginx-headless-noselector.bar.svc.cluster.local

; <<>> DiG 9.9.4-RedHat-9.9.4-51.el7_4.2 <<>> nginx-headless-noselector.bar.svc.cluster.local
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53443
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;nginx-headless-noselector.bar.svc.cluster.local. IN A

;; ANSWER SECTION:
nginx-headless-noselector.bar.svc.cluster.local. 20 IN CNAME www.google.co.jp.
www.google.co.jp.       20      IN      A       172.217.27.67

;; Query time: 1 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Wed May 02 15:01:32 UTC 2018
;; MSG SIZE  rcvd: 122

Podの名前解決

Aレコードの自動登録

Podは次の形式でDNSのAレコードが自動的に構成されています

pod-ip-address.my-namespace.pod.cluster.local

例えば、barネームスペースに以下の3種類のPodが存在する場合、

[root@sugi-kubernetes110-master01 ~(bar kubernetes-admin)]# kubectl get pods -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP            NODE
centos-749b5dff6-bpcrb   1/1       Running   0          57m       10.244.1.28   sugi-kubernetes110-node01.localdomain
nginx-5c9845d857-5tvlt   1/1       Running   0          1h        10.244.1.27   sugi-kubernetes110-node01.localdomain
nginx-5c9845d857-vlgl2   1/1       Running   0          1h        10.244.2.26   sugi-kubernetes110-node02.localdomain

「10-244-1-28.bar.pod.cluster.local.」で名前解決ができます
(search list に含まれていないsuffixなので注意)

[root@centos-749b5dff6-bpcrb /]# nslookup 10-244-1-28.bar.pod.cluster.local.
Server:         10.96.0.10
Address:        10.96.0.10#53

Name:   10-244-1-28.bar.pod.cluster.local
Address: 10.244.1.28

PodのDNSポリシー

PodのDNSポリシーは、Pod単位で設定を行うことが出来ます。現在、Kubernetesでは以下のポリシーが選択可能です。
マニフェストファイル内でdnsPolicyフィールドで指定を行うことが出来ます。

  • default (※) : kube-dnsで解決出来ない名前解決の場合、Podが稼働しているNodeに設定している、DNSサーバ(upstream nameserverと表現されている)を使用して名前解決を行います。次の「ClusterFirst」では、stub-domainやupstreamDNSサーバを個別に指定することが出来ますが、defaultポリシーでは設定をすることが出来ません。

  • ClusterFirst : kube-dnsで解決出来ない名前解決の場合、Podが稼働しているNodeに設定している、DNSサーバ(upstream nameserverと表現されている)を使用して名前解決を行います。Cluster管理者は、stub-domainやupstreamDNSサーバを個別に指定することができます。https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#impacts-on-pods

  • ClusterFirstWithHostNet : hostNetworkで稼働しているPodは、「ClusterFirstWithHostNet」をDNSポリシーとして指定する必要があります。

  • None : Kubernetes version 1.9 で追加された機能です。KubernetesのDNS自動設定を無視することが出来ます dnsConfig による設定のみ行う事が出来ます。https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pods-dns-config

※ defaultは、デフォルトDNSポリシーではありません。DNSポリシーを指定しない場合、 "ClusterFirst"が選択されます。

次のマニフェストファイルは、DNSポリシーを"ClusterFirstWithHostNet"と指定したものです。spec.hostNetworkをtrueにしています。

cat <<'EOF' > /root/kube_yaml/dns/busybox-hostnw.yaml
apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
  containers:
  - image: busybox
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always
  hostNetwork: true
  dnsPolicy: ClusterFirstWithHostNet
EOF

作成

kubectl apply -f /root/kube_yaml/dns/busybox-hostnw.yaml

確認します。busyboxのIPが、nodeのIPとなっています

[root@sugi-kubernetes110-master01 dns(bar kubernetes-admin)]# kubectl get pods -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP                NODE
busybox                  1/1       Running   0          10s       192.168.120.223   sugi-kubernetes110-node01.localdomain
centos-749b5dff6-bpcrb   1/1       Running   2          2h        10.244.1.28       sugi-kubernetes110-node01.localdomain
nginx-5c9845d857-5tvlt   1/1       Running   0          2h        10.244.1.27       sugi-kubernetes110-node01.localdomain
nginx-5c9845d857-vlgl2   1/1       Running   0          2h        10.244.2.26       sugi-kubernetes110-node02.localdomain

shを起動してログインします

kubectl exec busybox -it sh

コンテナ内のNWは、host側のNWが見えています

/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq qlen 1000
    link/ether 00:50:56:98:70:ab brd ff:ff:ff:ff:ff:ff
    inet 192.168.120.223/24 brd 192.168.120.255 scope global ens192
       valid_lft forever preferred_lft forever
    inet6 fe80::f59f:2d01:78d0:bcb9/64 scope link 
       valid_lft forever preferred_lft forever
    inet6 fe80::98a0:413d:6b71:8fbd/64 scope link tentative flags 08 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue 
    link/ether 02:42:3e:8b:64:af brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever
4: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue 
    link/ether 62:c4:05:0d:c1:d3 brd ff:ff:ff:ff:ff:ff
    inet 10.244.1.0/32 scope global flannel.1
       valid_lft forever preferred_lft forever
    inet6 fe80::60c4:5ff:fe0d:c1d3/64 scope link 
       valid_lft forever preferred_lft forever
5: cni0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue qlen 1000
    link/ether 0a:58:0a:f4:01:01 brd ff:ff:ff:ff:ff:ff
    inet 10.244.1.1/24 scope global cni0
       valid_lft forever preferred_lft forever
    inet6 fe80::9ca5:24ff:fe55:9672/64 scope link 
       valid_lft forever preferred_lft forever
31: vetha1c264dc@docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 
    link/ether 1e:a2:df:06:57:ba brd ff:ff:ff:ff:ff:ff
    inet6 fe80::1ca2:dfff:fe06:57ba/64 scope link 
       valid_lft forever preferred_lft forever
32: veth224aaf36@docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 
    link/ether a2:17:d4:7c:55:ea brd ff:ff:ff:ff:ff:ff
    inet6 fe80::a017:d4ff:fe7c:55ea/64 scope link 
       valid_lft forever preferred_lft forever

resolv.confの確認

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

nslookupも通常のPodと同様に見えています

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

Name:      foo1
Address 1: 10.107.131.250 foo1.bar.svc.cluster.local

PodのDNS Config

Kubernetes v1.9 から、PodのDNS設定をコントロールすることが出来ます。Kubernetes 1.10 からは default で機能が有効になっていますが、1.9 では、 kubelete の 引数に --feature-gates=CustomPodDNS=true,...を与えてプロセスを起動する必要があります。

Deploymentのマニフェストファイルを作成します

cat <<'EOF' > /root/kube_yaml/dns/dnsconfig_centos_pod.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: dnsconfig-centos
spec:
  selector:
    matchLabels:
      app: dnsconfig-centos
  replicas: 1
  template:
    metadata:
      labels:
        app: dnsconfig-centos
    spec:
      containers:
      - name: dnsconfig-centos
        image: centos
        command: [ "sleep", "3600" ]
      dnsPolicy: "None"
      dnsConfig:
        nameservers:
          - 1.2.3.4
        searches:
          - ns1.svc.cluster.local
          - my.dns.search.suffix
        options:
          - name: ndots
            value: "2"
          - name: edns0
EOF

Deploymentを作成

kubectl apply -f /root/kube_yaml/dns/dnsconfig_centos_pod.yaml

bashを起動

kubectl exec dnsconfig-centos-d9c4f576f-k9kj8 -it bash

以下のようにPodのresolv.configが設定されています
もちろん、下記の設定ではクラスタ内の名前解決もできませんし、外部の名前解決も出来ません。

[root@dnsconfig-centos-d9c4f576f-k9kj8 /]# cat /etc/resolv.conf 
nameserver 1.2.3.4
search ns1.svc.cluster.local my.dns.search.suffix
options ndots:2 edns0

参考URL

Kubernetes "サービス"の概要についての自習ノート
https://qiita.com/MahoTakara/items/d18d8f9b36416353066c

Kubernetes Blog
https://kubernetes.io/blog/2017/04/configuring-private-dns-zones-upstream-nameservers-kubernetes

stub-domain, upstreamDNS
https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#impacts-on-pods

DNS Config
https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pods-dns-config

47
33
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
47
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?