🔥

coredns deployment を読み解く (WIP)

2022/04/29に公開

以下のコマンドの結果を取り合えず貼り付けて読み解くだけ。

$ kubectl get deploy coredns -n kube-system -o yaml

がんばる。いったん飽きたのでここまで。

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "2"
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"addonmanager.kubernetes.io/mode":"Reconcile","k8s-app":"kube-dns","kubernetes.io/cluster-service":"true","kubernetes.io/name":"CoreDNS","version":"v20"},"name":"coredns","namespace":"kube-system"},"spec":{"paused":false,"revisionHistoryLimit":2,"selector":{"matchLabels":{"k8s-app":"kube-dns","version":"v20"}},"strategy":{"rollingUpdate":{"maxUnavailable":1},"type":"RollingUpdate"},"template":{"metadata":{"annotations":{"prometheus.io/port":"9153"},"labels":{"k8s-app":"kube-dns","kubernetes.io/cluster-service":"true","version":"v20"}},"spec":{"affinity":{"nodeAffinity":{"preferredDuringSchedulingIgnoredDuringExecution":[{"preference":{"matchExpressions":[{"key":"kubernetes.azure.com/mode","operator":"In","values":["system"]}]},"weight":100}]},"podAntiAffinity":{"preferredDuringSchedulingIgnoredDuringExecution":[{"podAffinityTerm":{"labelSelector":{"matchExpressions":[{"key":"k8s-app","operator":"In","values":["kube-dns"]}]},"topologyKey":"failure-domain.beta.kubernetes.io/zone"},"weight":10},{"podAffinityTerm":{"labelSelector":{"matchExpressions":[{"key":"k8s-app","operator":"In","values":["kube-dns"]}]},"topologyKey":"kubernetes.io/hostname"},"weight":5}]}},"containers":[{"args":["-conf","/etc/coredns/Corefile"],"image":"mcr.microsoft.com/oss/kubernetes/coredns:v1.8.6","imagePullPolicy":"IfNotPresent","livenessProbe":{"failureThreshold":5,"httpGet":{"path":"/health","port":8080,"scheme":"HTTP"},"initialDelaySeconds":60,"successThreshold":1,"timeoutSeconds":5},"name":"coredns","ports":[{"containerPort":53,"name":"dns","protocol":"UDP"},{"containerPort":53,"name":"dns-tcp","protocol":"TCP"},{"containerPort":9153,"name":"metrics","protocol":"TCP"}],"readinessProbe":{"httpGet":{"path":"/ready","port":8181,"scheme":"HTTP"}},"resources":{"limits":{"cpu":3,"memory":"500Mi"},"requests":{"cpu":"100m","memory":"70Mi"}},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"add":["NET_BIND_SERVICE"],"drop":["all"]},"procMount":"Default","readOnlyRootFilesystem":true},"volumeMounts":[{"mountPath":"/etc/coredns","name":"config-volume","readOnly":true},{"mountPath":"/etc/coredns/custom","name":"custom-config-volume","readOnly":true},{"mountPath":"/tmp","name":"tmp"}]}],"dnsPolicy":"Default","nodeSelector":{"beta.kubernetes.io/os":"linux"},"priorityClassName":"system-node-critical","serviceAccountName":"coredns","tolerations":[{"effect":"NoSchedule","key":"node-role.kubernetes.io/master"},{"key":"CriticalAddonsOnly","operator":"Exists"},{"effect":"NoExecute","key":"node.kubernetes.io/unreachable","operator":"Exists","tolerationSeconds":30},{"effect":"NoExecute","key":"node.kubernetes.io/not-ready","operator":"Exists","tolerationSeconds":30}],"volumes":[{"configMap":{"items":[{"key":"Corefile","path":"Corefile"}],"name":"coredns"},"name":"config-volume"},{"configMap":{"name":"coredns-custom","optional":true},"name":"custom-config-volume"},{"emptyDir":{},"name":"tmp"}]}}}}
  creationTimestamp: "2022-04-17T06:14:44Z"
  generation: 3
  labels:
    addonmanager.kubernetes.io/mode: Reconcile
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: CoreDNS
    version: v20
  name: coredns
  namespace: kube-system
  resourceVersion: "2229743"
  uid: xxxxxxxx-xxxx-xxxx-xxxx-cd9d6d2e8a84

いったん休憩

spec:
  progressDeadlineSeconds: 600
  # デプロイが失敗したと判断するまでの時間
  replicas: 2
  # レプリカの数
  revisionHistoryLimit: 2
  # Deployment は履歴を持ってるらしい。これを 0 にすると rollback できなくなる。詳細は下の方に
  selector:
  # label との関連で selector は大事、key-valut の形式
    matchLabels:
      k8s-app: kube-dns
      version: v20
  strategy:
    rollingUpdate:
    # ローリングアップデートかけるときの戦略。この場合だと最大 125% の数の pod まで増えてアップデートされる。ただ最大でも 1 pod しか減らない (今回は replica 2 なので 1 つは最低でも確保される)
      maxSurge: 25%
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
    # 動きに直接影響を与えるものでもないが selector などとの関連で重要な label など
      annotations:
        prometheus.io/port: "9153"
      creationTimestamp: null
      labels:
        k8s-app: kube-dns
        kubernetes.io/cluster-service: "true"
        version: v20
    spec:
      affinity:
        nodeAffinity:
        # どの node に配置するかなどの設定。ここでは kubernetes.azure.com/mode が system と設定されているもの、らしい
        # 確かに、`kubectl get nodes -o yaml` の `.metadata.labels` に `kubernetes.azure.com/mode: system` って書いてある
          preferredDuringSchedulingIgnoredDuringExecution:
          - preference:
              matchExpressions:
              - key: kubernetes.azure.com/mode
                operator: In
                values:
                - system
            weight: 100
        podAntiAffinity:
        # こっちは pod をどう配置するかの設定。anti-affinity なので、同じ pod を配置しないようにしてるっぽい
          preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              labelSelector:
              # coredns は k8s-app=kube-dns が設定されているので、これが含まれている node を外したいはず
                matchExpressions:
                - key: k8s-app
                  operator: In
                  values:
                  - kube-dns
              topologyKey: failure-domain.beta.kubernetes.io/zone
            weight: 10
          - podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: k8s-app
                  operator: In
                  values:
                  - kube-dns
              topologyKey: kubernetes.io/hostname
            weight: 5
      containers:
      - args:
        - -conf
        - /etc/coredns/Corefile
        # pod を起動するときのオプション
        image: mcr.microsoft.com/oss/kubernetes/coredns:v1.8.6
        # image は MCR (Microsoft Container Registry) から持ってくる
        imagePullPolicy: IfNotPresent
        # `IfNotPresent` のほかには `Always` と `Never` がある。`IfNotPresent` は妥当な選択肢と思われる。`Always` でも差分を確認して毎回は取りにいかないものもあるらしい
        # cf.) https://kubernetes.io/ja/docs/concepts/configuration/overview/#%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8
        livenessProbe:
        # 生きてるか死んでるかを確認するための probe
          failureThreshold: 5
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 5
        name: coredns
        ports:
        # expose する port はどれか。ここでは DNS の udp/53 と tdp/53 と、9153/tcp っぽい。
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
        - containerPort: 9153
          name: metrics
          protocol: TCP
        readinessProbe:
        # pod が立ち上がった後に ready かどうかを確認するための probe
          failureThreshold: 3
          httpGet:
            path: /ready
            port: 8181
            scheme: HTTP
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources:
        # どれくらいのリソースが欲しいかの設定
          limits:
            cpu: "3"
            memory: 500Mi
          requests:
            cpu: 100m
            memory: 70Mi
        securityContext:
          allowPrivilegeEscalation: false
          # これ true にするといろいろできちゃう pod が生まれる
          capabilities:
            add:
            - NET_BIND_SERVICE
            drop:
            - all
          procMount: Default
          readOnlyRootFilesystem: true
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        # ボリュームをマウントするかどうか。ここでは後ろのほうに定義してある ConfigMap がマウントされてる
        - mountPath: /etc/coredns
          name: config-volume
          readOnly: true
        - mountPath: /etc/coredns/custom
          name: custom-config-volume
          readOnly: true
        - mountPath: /tmp
          name: tmp
      dnsPolicy: Default
      nodeSelector:
        beta.kubernetes.io/os: linux
        # linux のノードじゃないと coredns は動かないので
      priorityClassName: system-node-critical
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      serviceAccount: coredns
      serviceAccountName: coredns
      terminationGracePeriodSeconds: 30
      # coredns を落とすときに 30 秒待つんだろう、たぶん
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
      - key: CriticalAddonsOnly
        operator: Exists
      - effect: NoExecute
        key: node.kubernetes.io/unreachable
        operator: Exists
        tolerationSeconds: 30
      - effect: NoExecute
        key: node.kubernetes.io/not-ready
        operator: Exists
        tolerationSeconds: 30
      volumes:
      # ここでマウントする ConfigMap が定義してある
      - configMap:
      # ConfigMapは、 機密性のないデータをキーと値のペアで保存するために使用されるAPIオブジェクトです。cf.) https://kubernetes.io/ja/docs/concepts/configuration/configmap/
          defaultMode: 420
          items:
          - key: Corefile
            path: Corefile
          name: coredns
        name: config-volume
      - configMap:
          defaultMode: 420
          name: coredns-custom
          optional: true
        name: custom-config-volume
      - emptyDir: {}
      # emptyDirボリュームはPodがノードに割り当てられたときに最初に作成され、そのPodがそのノードで実行されている限り存在します。cf.) https://kubernetes.io/ja/docs/concepts/storage/volumes/#emptydir
        name: tmp
Microsoft (有志)

Discussion