Slide 1

Slide 1 text

Kubernetesと 
 CoreDNSの関係について理解する 3 -shake SRE Tech Talk # 8 ( 2 0 2 3 / 1 2 / 1 8 ) @bells 1 7

Slide 2

Slide 2 text

▶ @bells 1 7 ▶ Software Engineer@ 3 -shake inc. ▶ kubernetes & kubernetes-csi member ▶ Kubernetes Internal Organizer ▶ Kubernetes Novice Tokyo Organizer ← New! ▶ #kubenews ▶ X(Twitter): @bells 1 7 _ ▶ GitHub: @bells 1 7

Slide 3

Slide 3 text

突然ですが 
 KubernetesのDNS周りがどんなふうに 
 設定されているかご存知ですか?

Slide 4

Slide 4 text

DNSを意識したときに気になるポイント ▶ PodからCoreDNSを使うようになる設定ってどこで⾏われてるの? ▶ CoreDNSはどのようにしてService/Podドメインの名前解決を⾏うの?

Slide 5

Slide 5 text

まずは動作を確認してみる

Slide 6

Slide 6 text

kind-con fi g.yaml kind: Cluster apiVersion: kind.x-k 8 s.io/v 1 alpha 4 nodes: - role: control-plane - role: worker - role: worker # クラスター起動コマンド $ kind create cluster \ --name kube-dns-example \ --con fi g kind-con fi g.yaml control-plane: 1 worker: 2 合計3台のノードを起動する

Slide 7

Slide 7 text

apiVersion: apps/v 1 kind: Deployment metadata: name: example spec: replicas: 2 selector: matchLabels: app: example template: metadata: labels: app: example spec: a ffi nity: podAntiA ff i nity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 podA ff i nityTerm: labelSelector: matchExpressions: - key: app operator: In values: - nginx topologyKey: "kubernetes.io/hostname" containers: - name: nginx image: nginx ports: - containerPort: 8 0 2台をpreferredDuringSchedulingIgnoredDuringExecutionで分散配置してるのでworkerノードに1台ずつ配置されるはず Deployment

Slide 8

Slide 8 text

apiVersion: v 1 kind: Service metadata: name: example spec: type: ClusterIP selector: app: example ports: - protocol: TCP port: 8 0 Service

Slide 9

Slide 9 text

$ kubectl exec -it $(kubectl get pod -l app=example -o=jsonpath='{.items[ 0 ].metadata.name}') -- bash # curl example.default.svc.cluster.local -o /dev/null -w '%{http_code}\n' -s 2 0 0 # cat /etc/resolv.conf search default.svc.cluster.local svc.cluster.local cluster.local nameserver 1 0 . 9 6 . 0 . 1 0 options ndots: 5 動作確認

Slide 10

Slide 10 text

$ kubectl exec -it $(kubectl get pod -l app=example -o=jsonpath='{.items[ 0 ].metadata.name}') -- bash # curl example.default.svc.cluster.local -o /dev/null -w '%{http_code}\n' -s # ←CoreDNSは どうやって名前解決してる? 2 0 0 # cat /etc/resolv.conf search default.svc.cluster.local svc.cluster.local cluster.local nameserver 1 0 . 9 6 .0.10 # ← このIPアドレスはどこで設定される? options ndots: 5 動作確認

Slide 11

Slide 11 text

ということで調べてみた

Slide 12

Slide 12 text

1 . resolve.confの設定

Slide 13

Slide 13 text

Podに設定されるresolve.confはCRIのdnsCon fi gによって設定される https://github.com/kubernetes/kubernetes/blob/v 1 . 2 8 . 4 /pkg/kubelet/kuberuntime/kuberuntime_sandbox.go#L 7 9 -L 1 5 8

Slide 14

Slide 14 text

sandboxContainerの resolve.confがPodの各コンテナに bind mountされる https://github.com/containerd/containerd/blob/v 1 . 7 . 9 /pkg/cri/server/container_create_linux.go

Slide 15

Slide 15 text

nameserverはClusterDNSから設定されるらしい https://github.com/kubernetes/kubernetes/blob/v 1 . 2 8 . 4 /pkg/kubelet/network/dns/dns.go#L 3 8 4 -L 4 4 8

Slide 16

Slide 16 text

$ kubectl -n kube-system get cm kubelet-con fi g -o yaml apiVersion: v 1 kind: Con fi gMap metadata: name: kubelet-con fi g namespace: kube-system data: kubelet: | apiVersion: kubelet.con fi g.k 8 s.io/v 1 beta 1 ... cgroupDriver: systems cgroupRoot: /kubelet clusterDNS: - 1 0 . 9 6 . 0 . 1 0 clusterDomain: cluster.local … kubelet-con fi gを⾒るとclusterDNSが10.96.0.10に設定されてるのがわかる これがresolve.confの”nameserver 1 0 . 9 6 . 0 . 1 0 ”に設定されている

Slide 17

Slide 17 text

kubeadmの場合デフォルトのClusterDNSが10.96.0.10に設定されている

Slide 18

Slide 18 text

この10.96.0.10がデフォルトになってるのがわかる https://github.com/kubernetes/kubernetes/blob/v 1 . 2 8 . 4 /cmd/kubeadm/app/componentcon fi gs/kubelet.go#L 1 1 2 -L 2 1 3

Slide 19

Slide 19 text

この10.96.0.10を同様にCoreDNSのServiceに設定してデプロイしてる https://github.com/kubernetes/kubernetes/blob/v 1 . 2 8 . 4 /cmd/kubeadm/app/phases/addons/dns/dns.go#L 1 0 5 -L 1 6 2

Slide 20

Slide 20 text

$ kubectl -n kube-system get svc kube-dns -o yaml apiVersion: v 1 kind: Service metadata: name: kube-dns namespace: kube-system spec: clusterIP: 1 0 . 9 6 . 0 . 1 0 clusterIPs: - 1 0 . 9 6 . 0 . 1 0 internalTra ff i cPolicy: Cluster ipFamilies: - IPv 4 ipFamilyPolicy: SingleStack ports: - name: dns port: 5 3 protocol: UDP targetPort: 5 3 - name: dns-tcp port: 5 3 protocol: TCP targetPort: 5 3 - name: metrics port: 9 1 5 3 protocol: TCP targetPort: 9 1 5 3 selector: k 8 s-app: kube-dns sessionA ff i nity: None type: ClusterIP 最終的にこんな感じでServiceが設定されている

Slide 21

Slide 21 text

これでCoreDNSのデプロイ~nameserverに 
 IPアドレスを設定されるまでの流れが理解できた

Slide 22

Slide 22 text

2 . CoreDNSによるService/Podの名前解決

Slide 23

Slide 23 text

CoreDNSによるService/Podの名前解決はKubernetesプラグインによって実現 https://github.com/coredns/coredns/tree/v 1 . 1 1 . 1 /plugin/kubernetes

Slide 24

Slide 24 text

Kubernetes DNS-Based Service Discovery Speci fi cationに沿って実装されているよう https://github.com/kubernetes/dns/blob/ 1 . 2 2 . 2 8 /docs/speci fi cation.md

Slide 25

Slide 25 text

このあたりでドメインに対するリクエストに応じてService/Podに対する名前解決を⾏っている https://github.com/coredns/coredns/blob/v 1 . 1 1 . 1 /plugin/kubernetes/kubernetes.go#L 3 1 4 -L 3 1 9

Slide 26

Slide 26 text

CoreDNSプラグインから直接KubernetesのServiceなどを取得して名前解決の処理を⾏う https://github.com/coredns/coredns/blob/v 1 . 1 1 . 1 /plugin/kubernetes/kubernetes.go#L 4 6 8 -L 4 9 7

Slide 27

Slide 27 text

$ kubectl -n kube-system get cm coredns -o yaml kind: Con fi gMap metadata: name: coredns namespace: kube-system apiVersion: v 1 data: Core fi le: | .: 5 3 { errors health { lameduck 5 s } ready kubernetes cluster.local in-addr.arpa ip 6 .arpa { pods insecure fallthrough in-addr.arpa ip 6 .arpa ttl 3 0 } prometheus : 9 1 5 3 forward . /etc/resolv.conf { max_concurrent 1 0 0 0 } cache 3 0 loop reload loadbalance } ちなみにCoreDNSの設定はこんな感じになっている “kubernetes cluster-local ~” の部分がKubernetesプラグインの引数になっている

Slide 28

Slide 28 text

ということでDNSにリクエストに対してKubernetes側 
 から直接データを取り出して処理していることがわかった

Slide 29

Slide 29 text

まとめ

Slide 30

Slide 30 text

KubernetesがService/Podの名前解決する全体像はこんな感じ

Slide 31

Slide 31 text

参考資料 ▶ https://github.com/kubernetes/kubernetes/tree/v 1 . 2 8 . 4 ▶ https://github.com/coredns/coredns/tree/v 1 . 1 1 . 1 ▶ https://github.com/coredns/example ▶ https://github.com/coredns/coredns/blob/v 1 . 1 1 . 1 /plugin/kubernetes/README.md ▶ https://github.com/kubernetes/dns/blob/ 1 . 2 2 . 2 8 /docs/speci fi cation.md ▶ https://github.com/kubernetes/cri-api/blob/v 0 . 2 8 . 4 /pkg/apis/runtime/v 1 /api.proto ▶ https://coredns.io/ 2 0 1 7 / 0 3 / 0 1 /how-to-add-plugins-to-coredns/ ▶ https://coredns.io/ 2 0 1 6 / 1 2 / 1 9 /writing-plugins-for-coredns/ ▶ https://github.com/coredns/example ▶ https://github.com/coredns/coredns/blob/v 1 . 1 1 . 1 /plugin.md

Slide 32

Slide 32 text

画像引⽤元 ▶ https://github.com/kubernetes/community/tree/master/icons ▶ https://github.com/kubernetes/kubernetes/tree/master/logo ▶ https://github.com/cncf/artwork/tree/master/projects/kubernetes ▶ https://github.com/kubernetes/kubeadm/tree/main/logos

Slide 33

Slide 33 text

Thanks / Question? ▶ @bells 1 7 ▶ Slide: https://speakerdeck.com/bells 1 7 ▶ @bells 1 7 _