はじめに
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