設定自訂 kube-dns 部署作業

本文說明如何替換預設的 GKE 管理 kube-dns,改用自己的部署作業,在 Google Kubernetes Engine (GKE) Standard 叢集中自訂 DNS 設定。這樣一來,您就能進一步控管叢集的 DNS 供應商。例如,您可以:

  • 微調 DNS 元件的 CPU 和記憶體資源。
  • 使用特定 kube-dns 映像檔版本。
  • 部署符合 Kubernetes DNS 規格的替代 DNS 供應商,例如 CoreDNS。

本文僅適用於 Standard 叢集;在 Autopilot 叢集中,DNS 設定由 Google 管理。如要深入瞭解 GKE 中的 DNS 供應商,請參閱「關於服務探索」和「kube-dns」。

注意:如果您執行自訂 DNS 部署作業,必須負責後續維護。包括確保 kube-dns 和自動調整規模容器映像檔已更新至最新版本和安全性修補程式。如要找出最新建議的映像檔,請檢查 GKE 叢集 kube-system 命名空間中的預設 kube-dns 部署作業。

本文適用於 GKE 使用者,包括開發人員、管理員和架構師。如要進一步瞭解 Google Cloud中的常見角色和範例工作,請參閱「常見的 GKE Enterprise 使用者角色和工作」。

本文假設您已詳讀以下文章:

設定自訂 kube-dns 部署作業

本節說明如何以自己的部署作業取代 GKE 管理的 kube-dns

建立及部署自訂資訊清單

  1. 將下列 Deployment 資訊清單儲存為 custom-kube-dns.yaml。這個資訊清單使用 kube-dns

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: DNS_DEPLOYMENT_NAME
      namespace: kube-system
      labels:
        k8s-app: kube-dns
      annotations:
        deployment.kubernetes.io/revision: "1"
    spec:
      selector:
        matchLabels:
          k8s-app: kube-dns
      strategy:
        rollingUpdate:
          maxSurge: 10%
          maxUnavailable: 0
        type: RollingUpdate
      template:
        metadata:
          creationTimestamp: null
          labels:
            k8s-app: kube-dns
        spec:
          containers:
          - name: kubedns
            image: registry.k8s.io/dns/k8s-dns-kube-dns:1.22.28
            resources:
              limits:
                memory: '170Mi'
              requests:
                cpu: 100m
                memory: '70Mi'
            livenessProbe:
              httpGet:
                path: /healthcheck/kubedns
                port: 10054
                scheme: HTTP
              initialDelaySeconds: 60
              timeoutSeconds: 5
              successThreshold: 1
              failureThreshold: 5
            readinessProbe:
              httpGet:
                path: /readiness
                port: 8081
                scheme: HTTP
              initialDelaySeconds: 3
              timeoutSeconds: 5
            args:
            - --domain=cluster.local.
            - --dns-port=10053
            - --config-dir=/kube-dns-config
            - --v=2
            env:
            - name: PROMETHEUS_PORT
              value: "10055"
            ports:
            - containerPort: 10053
              name: dns-local
              protocol: UDP
            - containerPort: 10053
              name: dns-tcp-local
              protocol: TCP
            - containerPort: 10055
              name: metrics
              protocol: TCP
            volumeMounts:
            - name: kube-dns-config
              mountPath: /kube-dns-config
            securityContext:
              allowPrivilegeEscalation: false
              readOnlyRootFilesystem: true
              runAsUser: 1001
              runAsGroup: 1001
          - name: dnsmasq
            image: registry.k8s.io/dns/k8s-dns-dnsmasq-nanny:1.22.28
            livenessProbe:
              httpGet:
                path: /healthcheck/dnsmasq
                port: 10054
                scheme: HTTP
              initialDelaySeconds: 60
              timeoutSeconds: 5
              successThreshold: 1
              failureThreshold: 5
            args:
            - -v=2
            - -logtostderr
            - -configDir=/etc/k8s/dns/dnsmasq-nanny
            - -restartDnsmasq=true
            - --
            - -k
            - --cache-size=1000
            - --no-negcache
            - --dns-forward-max=1500
            - --log-facility=-
            - --server=/cluster.local/127.0.0.1#10053
            - --server=/in-addr.arpa/127.0.0.1#10053
            - --server=/ip6.arpa/127.0.0.1#10053
            ports:
            - containerPort: 53
              name: dns
              protocol: UDP
            - containerPort: 53
              name: dns-tcp
              protocol: TCP
            resources:
              requests:
                cpu: 150m
                memory: 20Mi
            volumeMounts:
            - name: kube-dns-config
              mountPath: /etc/k8s/dns/dnsmasq-nanny
            securityContext:
              capabilities:
                drop:
                - all
                add:
                - NET_BIND_SERVICE
                - SETGID
          - name: sidecar
            image: registry.k8s.io/dns/k8s-dns-sidecar:1.22.28
            livenessProbe:
              httpGet:
                path: /metrics
                port: 10054
                scheme: HTTP
              initialDelaySeconds: 60
              timeoutSeconds: 5
              successThreshold: 1
              failureThreshold: 5
            args:
            - --v=2
            - --logtostderr
            - --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.cluster.local,5,SRV
            - --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.cluster.local,5,SRV
            ports:
            - containerPort: 10054
              name: metrics
              protocol: TCP
            resources:
              requests:
                memory: 20Mi
                cpu: 10m
            securityContext:
              allowPrivilegeEscalation: false
              readOnlyRootFilesystem: true
              runAsUser: 1001
              runAsGroup: 1001
          dnsPolicy: Default
          restartPolicy: Always
          schedulerName: default-scheduler
          securityContext: {}
          serviceAccount: kube-dns
          serviceAccountName: kube-dns
          terminationGracePeriodSeconds: 30
          tolerations:
          - key: CriticalAddonsOnly
            operator: Exists
          volumes:
          - configMap:
              defaultMode: 420
              name: kube-dns
              optional: true
            name: kube-dns-config
    

    DNS_DEPLOYMENT_NAME 替換為自訂 DNS 部署作業的名稱。

  2. 將資訊清單套用至叢集:

    kubectl create -f custom-kube-dns.yaml
    

縮減 GKE 管理的 kube-dns

為避免發生衝突,請將 GKE 管理的 kube-dnskube-dns-autoscaler Deployment 縮放至零個副本,藉此停用這些 Deployment:

kubectl scale deployment --replicas=0 kube-dns-autoscaler kube-dns --namespace=kube-system

設定自訂自動調度器

預設 kube-dns-autoscaler 只會擴充 GKE 管理的 kube-dns Deployment。如果自訂 DNS 供應商需要自動調度資源,您必須部署獨立的自動調度器,並授予該調度器修改自訂 DNS 部署作業的權限。

  1. 建立下列資訊清單,並儲存為 custom-dns-autoscaler.yaml

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: custom-dns-autoscaler
      namespace: kube-system
    data:
      linear: |-
        {
          "coresPerReplica": 256,
          "nodesPerReplica": 16,
          "preventSinglePointFailure": true
        }
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: system:custom-dns-autoscaler
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: system:custom-dns-autoscaler
    subjects:
    - kind: ServiceAccount
      name: kube-dns-autoscaler
      namespace: kube-system
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: system:custom-dns-autoscaler
    rules:
    - apiGroups:
      - ""
      resources:
      - nodes
      verbs:
      - list
      - watch
    - apiGroups:
      - apps
      resourceNames:
      - DNS_DEPLOYMENT_NAME
      resources:
      - deployments/scale
      verbs:
      - get
      - update
    - apiGroups:
      - ""
      resources:
      - configmaps
      verbs:
      - get
      - create
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: custom-dns-autoscaler
      namespace: kube-system
      labels:
        k8s-app: custom-dns-autoscaler
    spec:
      selector:
        matchLabels:
          k8s-app: custom-dns-autoscaler
      template:
        metadata:
          labels:
            k8s-app: custom-dns-autoscaler
        spec:
          priorityClassName: system-cluster-critical
          securityContext:
            seccompProfile:
              type: RuntimeDefault
            supplementalGroups: [ 65534 ]
            fsGroup: 65534
          nodeSelector:
            kubernetes.io/os: linux
          containers:
          - name: autoscaler
            image: registry.k8s.io/autoscaling/cluster-proportional-autoscaler:1.8.9
            resources:
              requests:
                cpu: "20m"
                memory: "10Mi"
            command:
            - /cluster-proportional-autoscaler
            - --namespace=kube-system
            - --configmap=custom-dns-autoscaler
            - --target=Deployment/DNS_DEPLOYMENT_NAME
            - --default-params={"linear":{"coresPerReplica":256,"nodesPerReplica":16,"preventSinglePointFailure":true}}
            - --logtostderr=true
            - --v=2
          tolerations:
          - key: "CriticalAddonsOnly"
            operator: "Exists"
          serviceAccountName: kube-dns-autoscaler
    

    resourceNames 欄位和 command 欄位中的 DNS_DEPLOYMENT_NAME 替換成自訂 DNS 部署作業的名稱。

  2. 將資訊清單套用至叢集:

    kubectl create -f custom-dns-autoscaler.yaml
    

驗證 Deployment

確認自訂 DNS Pod 正在執行:

kubectl get pods -n kube-system -l k8s-app=kube-dns

由於您將 GKE 管理的 kube-dns 部署作業縮減為零個副本,因此輸出內容只會顯示自訂部署作業的 Pod。確認狀態為 Running

還原 GKE 管理的 kube-dns

如果您部署了自訂 kube-dns 設定,且需要還原為預設的 GKE 管理設定,請刪除自訂資源,然後重新啟用受管理 kube-dns 部署作業。

請按照下列步驟還原 GKE 管理的 kube-dns

  1. 刪除自訂 kube-dns 部署作業及其自動調度器。如果您已將資訊清單儲存為 custom-kube-dns.yamlcustom-dns-autoscaler.yaml,請執行下列指令來刪除資源:

    kubectl delete -f custom-dns-autoscaler.yaml
    kubectl delete -f custom-kube-dns.yaml
    

    如果沒有儲存資訊清單,請手動刪除為自訂部署作業建立的 Deployment、ClusterRole 和 ClusterRoleBinding。

  2. 還原 GKE 代管的 kube-dns-autoscaler。執行下列指令,將 kube-dns-autoscaler 部署作業的副本數調回一個:

    kubectl scale deployment --replicas=1 kube-dns-autoscaler --namespace=kube-system
    

    這個指令會重新啟用代管 kube-dns-autoscaler,然後自動將代管 kube-dns 部署作業擴充至適合叢集大小的副本數量。

  3. 確認還原作業。

    檢查 kube-dnskube-dns-autoscaler Pod,確保運作正常:

    kubectl get pods -n kube-system -l k8s-app=kube-dns
    

    輸出內容應顯示 GKE 管理的 kube-dns Pod 處於 Running 狀態。

後續步驟