3
2

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 3 years have passed since last update.

[Kubernetes]クラスタ内DNSの動作を確認する

Last updated at Posted at 2020-04-04

#はじめに
前回ClusterIPの動作を確認しました。
その際、動作確認用のPodにはClusterIPのIPアドレスを設定していました。しかし、Kubernetesで実現するマイクロサービスでは、頻繁にリソースを追加削除します。各リソースにはKubernetesが自動でIPアドレスを割り当てますので、IPアドレスはデプロイの度に変わります。そのため、アプリケーション内ではIPアドレスではなく、DNS名を使用するのが望ましいでしょう。
そこで今回は、クラスタ内でのDNSの動作を確認したいと思います。

#クラスタ内のDNS
マニュアルには以下のような記載があります。クラスタ内では、kubernetesがDNSのサービスを提供しています。

KubernetesのDNSはクラスター上でDNS PodとServiceをスケジュールし、DNSの名前解決をするために各コンテナに対してDNS ServiceのIPを使うようにKubeletを設定します。
kubernetes.io

提供されるサービスは以下の2つがあります。

  • Aレコード
  • SRVレコード

##Aレコード
Serviceには、「[サービス名].[ネームスペース名].svc.cluster.local」という形式のDNS Aレコードが割り当てられています。
前回作成したClusterIPを例にすると、「cluster-ip.default.svc.cluster.local」になります。

###動作確認
前回の環境で、動作確認用のPodに指定したClusterIPのIPアドレスをFQDNに書き換えました。
これで同様に動作確認してみたいと思います。

test_pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: centos
      image: centos:latest
      command:
      - sh
      - -c
      args:
      - for i in 1 2 3 4 5 ; do curl -s http://cluster-ip.default.svc.cluster.local:8080 ; sleep 5; done ;exit 0

このマニフェストをapplyして、30秒ほど待ってlogを確認します。

$ kubectl apply -f test_pod.yaml
pod/test-pod created
$ kubectl logs test-pod | grep pod
pod1
pod2
pod2
pod1
pod2

IPアドレスを指定した時と同様にClusterIPに対してリクエストが送られていますね。

なお、今回は正式なFQDNを指定しましたが、Podとサービスが同じネームスペースの場合には、[サービス名]だけでも名前解決ができます。
これは、デプロイされるコンテナの/etc/resolve.confにsearchから始まる一行があるため、[サービス名]だけ、ネームスペースが異なる場合には、「[サービス名].[ネームスペース名]」だけでも名前解決ができます。

$ kubectl exec -it test-pod /bin/bash
[root@test-pod /]# cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

##SRVレコード
SRVレコードは、一言で言うとポート番号を含めたDNSです(と私は理解しました)。SRVレコードは以下の形式になります。

[_Serviceのポート名].[_ポートのプロトコル].[サービス名].[ネームスペース名].svc.cluster.local

前回作成したClusterIPの詳細を確認します。

$ kubectl describe svc cluster-ip
Name:              cluster-ip
Namespace:         default
Labels:            <none>
Annotations:       kubectl.kubernetes.io/last-applied-configuration:
                     {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"cluster-ip","namespace":"default"},"spec":{"ports":[{"name":"clus...
Selector:          app=nginx-dep
Type:              ClusterIP
IP:                10.101.47.213
Port:              cluster-port  8080/TCP
TargetPort:        80/TCP
Endpoints:         192.168.69.234:80,192.168.79.98:80
Session Affinity:  None
Events:            <none>

上記の結果から、このClusterIPのSVRレコードは、以下になります。

_cluster-port._TCP.cluster-ip.default.svc.cluster.local

###動作確認
動作確認用のPodとして、以下のマニフェストのPodをデプロイします。

test_pod2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: centos
      image: centos:latest
      command:
      - sh
      - -c
      args:
      - tail -f /dev/null
$ kubectl apply -f test_pod2.yaml
pod/test-pod created

Podにログインします。

$ kubectl exec -it test-pod /bin/bash
[root@test-pod /]#

デフォルトでは、nslookupやdigコマンドがないため、インストールします。

[root@test-pod /]# yum install -y bind-utils
Failed to set locale, defaulting to C.UTF-8
CentOS-8 - AppStream                                                                                                                                                           1.7 MB/s | 6.6 MB     00:03
CentOS-8 - Base                                                                                                                                                                1.8 MB/s | 5.0 MB     00:02
CentOS-8 - Extras                                                                                                                                                              6.1 kB/s | 4.9 kB     00:00
Dependencies resolved.
・・・
Installed:
  bind-utils-32:9.11.4-26.P2.el8.x86_64  bind-libs-32:9.11.4-26.P2.el8.x86_64  bind-libs-lite-32:9.11.4-26.P2.el8.x86_64  bind-license-32:9.11.4-26.P2.el8.noarch  python3-bind-32:9.11.4-26.P2.el8.noarch
  python3-ply-3.9-7.el8.noarch

Complete!

nslookupとdigで確認します。

[root@test-pod /]]# nslookup -type=srv _cluster-port._TCP.cluster-ip.default.svc.cluster.local
Server:         10.96.0.10
Address:        10.96.0.10#53

_cluster-port._TCP.cluster-ip.default.svc.cluster.local service = 0 100 8080 cluster-ip.default.svc.cluster.local.

[root@test-pod /]# dig _cluster-port._TCP.cluster-ip.default.svc.cluster.local SRV

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el8 <<>> _cluster-port._TCP.cluster-ip.default.svc.cluster.local SRV
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8930
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 2
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 3127dac7c4b7e34a (echoed)
;; QUESTION SECTION:
;_cluster-port._TCP.cluster-ip.default.svc.cluster.local. IN SRV

;; ANSWER SECTION:
_cluster-port._TCP.cluster-ip.default.svc.cluster.local. 30 IN SRV 0 100 8080 cluster-ip.default.svc.cluster.local.

;; ADDITIONAL SECTION:
cluster-ip.default.svc.cluster.local. 30 IN A   10.101.47.213

;; Query time: 1 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Sat Apr 04 12:37:15 UTC 2020
;; MSG SIZE  rcvd: 259

どちらの結果でも、cluster-ipサービスのポート「8080」とホスト名「cluster-ip.default.svc.cluster.local」が解決できていますね。

#まとめ
KubernetesではIPアドレスは自動で割り当てられるため、IPアドレスではなくDNS名を指定して各リソース間で通信をするのが望ましいです。マイクロサービスを開発するには、今回確認したDNSの設定と動作を理解しておく必要がありますね。

#補足
ClusterIPに割り当てられるIPアドレスをユーザーが指定することができます。指定する場合は、「spec.clusterIP」フィールドに指定するIPアドレスを記載します。
指定できるIPアドレスは、APIサーバに設定されている「service-cluster-ip-range」内のアドレスである必要があります。

$ kubectl -n kube-system describe pod/kube-apiserver-k8s-master | grep range
      --service-cluster-ip-range=10.96.0.0/12

ユーザー所有のIPアドレスを選択する
kubernetes.io

3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?