全部產品
Search
文件中心

Container Service for Kubernetes:使用NodeLocal DNSCache

更新時間:Jun 19, 2024

在ACK叢集中部署NodeLocal DNSCache可以提升服務發現的穩定性和效能,NodeLocal DNSCache通過在叢集節點上作為DaemonSet運行DNS緩衝代理來提高叢集DNS效能。本文介紹如何安裝NodeLocal DNSCache,並在應用中使用NodeLocal DNSCache。

前提條件

使用限制

  • NodeLocal DNSCache不支援ACK Serverless叢集、以及託管版、專有版叢集中部署的ECI類型的Pod。

  • 如果叢集網路類型為Terway,請更新Terway至v1.0.10.301及以上版本。如果是基於IPVLAN的Terway多IP模式,需要對Terway進行配置修改。更多資訊,請參見修改Terway配置

  • 組件管理中的NodeLocal DNSCache和應用目錄中的ack-node-local-dns為同一應用,不需要重複安裝。

  • NodeLocal DNSCache不提供Hosts、Rewrite等外掛程式能力,僅作為CoreDNS的透明緩衝代理。如有需要,可在CoreDNS配置中修改。

  • 使用NodeLocal DNSCache前,您需要對CoreDNS配置進行修改,否則可能導致叢集外部網域名稱解析異常。具體操作,請參見配置Forward外掛程式與上遊VPC DNS伺服器的預設協議

NodeLocal DNSCache簡介

ACK NodeLocal DNSCache是基於社區開源專案NodeLocal DNSCache的一套DNS本機快取解決方案。ACK NodeLocal DNSCache在Helm Chart中的名稱是ack-node-local-dns。該方案主要由DNS本機快取DaemonSet和DNSConfig動態注入控制器Deployment組成:

  • DNSConfig動態注入控制器Deployment,基於Admission Webhook機制攔截Pod建立的請求,自動注入使用DNS緩衝的Pod DNSConfig資訊。

    說明

    如果不啟用DNSConfig動態注入控制器Deployment,您需要手動注入DNS網域名稱相關配置至Pod配置中。具體操作,請參見在應用中使用NodeLocal DNSCache下的方式二:手動指定DNSConfig。

  • DNS緩衝DaemonSet可以在每個節點上建立一個虛擬網路介面(預設監聽IP 169.254.20.10,如需修改請提交工單諮詢),配合Pod的DNSConfig和節點上的網路設定,Pod內產生的DNS請求會被該DaemonSet服務所代理。

    重要

    DaemonSet服務內同樣基於CoreDNS提供服務,但其僅具有代理和緩衝的功能,請勿啟用額外的外掛程式能力(如Hosts、Rewrite等)。

關於NodeLocal DNSCache的緩衝策略,請參見DNS解析及緩衝策略說明

圖 1. NodeLocal DNSCache工作原理圖

序號

描述

已注入DNS本機快取的Pod,預設會通過NodeLocal DNSCache監聽於節點上的IP(169.254.20.10)解析網域名稱。

NodeLocal DNSCache本地若無緩衝應答解析請求,則會通過kube-dns服務要求CoreDNS進行解析。

CoreDNS對於非叢集內網域名稱,會通過VPC DNS伺服器進行解析。

已注入DNS本機快取的Pod,當無法連通NodeLocal DNSCache時,會繼而直接通過kube-dns服務串連到CoreDNS進行解析,此鏈路為備用鏈路。

未注入DNS本機快取的Pod,會通過標準的kube-dns服務鏈結路串連到CoreDNS進行解析。

安裝NodeLocal DNSCache

您可以通過組件管理或者應用目錄頁面安裝NodeLocal DNSCache,建議您通過組件管理安裝NodeLocal DNSCache。

方式一:通過組件管理安裝NodeLocal DNSCache

  1. 登入Container Service管理主控台,在左側導覽列選擇叢集

  2. 叢集列表頁面,選擇目的地組群名稱或者目的地組群右側操作列下的更多 > 營運管理 > 組件管理

  3. 組件管理頁面,單擊網路頁簽,找到ACK NodeLocal DNSCache

  4. 單擊ACK NodeLocal DNSCache的安裝,在彈出的對話方塊中單擊確定

方式二:通過應用目錄安裝NodeLocal DNSCache

  1. 登入Container Service管理主控台,在左側導覽列選擇市場 > 應用市場

  2. 應用市場頁面單擊應用目錄頁簽,然後搜尋並選中ack-node-local-dns

  3. ack-node-local-dns頁面,單擊一鍵部署

  4. 建立面板中,選擇叢集和命名空間,然後單擊下一步

  5. 參數配置頁面,設定相應參數,然後單擊確定

    需設定的參數說明如下表。

    參數

    描述

    擷取路徑

    upstream_ip

    kube-system命名空間下 kube-dns服務的ClusterIP。NodeLocal DNSCache通過該服務與CoreDNS通訊來解析叢集內網域名稱。

    如果您需要指定不同的上遊DNS伺服器,可以修改此參數。

    clusterDomain

    叢集主網域名稱。

    查看節點上kubelet進程的--cluster-domain參數,預設為cluster.local

在應用中使用NodeLocal DNSCache

說明

NodeLocal DNSCache預設不會部署至Master節點。如果您的業務需要部署至Master節點,且您的Master節點設定了汙點,您需要修改命名空間kube-system下node-local-dns DaemonSet的汙點容忍。

為了將應用原本請求CoreDNS的流量改為由DNS緩衝DaemonSet代理,需要將Pod內部的nameservers配置成169.254.20.10和kube-dns對應的IP地址,您有以下幾種方式可以選擇:

  • 方式一:藉助DNSConfig動態注入控制器在Pod建立時配置DNSConfig自動注入,推薦使用此方式。

  • 方式二:建立Pod時手動指定DNSConfig。

  • 方式三:修改kubelet參數,並重啟節點kubelet。存在業務中斷風險,不推薦使用此方式。

方式一:配置DNSConfig自動注入

DNSConfig動態注入控制器可用於自動注入DNSConfig至建立的Pod中,避免您手工配置Pod YAML進行注入。本應用預設會監聽包含node-local-dns-injection=enabled標籤的命名空間中建立Pod的請求,您可以通過以下命令給命名空間打上Label標籤。

kubectl label namespace default node-local-dns-injection=enabled
說明
  • 上述命令僅會開啟default命名空間的自動注入,如需對其他命名空間開啟自動注入,則需要替換default為目標命名空間名稱。

  • 在命名空間DNSConfig自動注入開啟的情況下,如需對部分Pod進行豁免(即不進行注入),可以調整其Pod Template中Labels標籤欄位,加上node-local-dns-injection=disabled標籤。

  • ECI不支援NodeLocal DNSCache。當Deployment動態彈性擴容至ECI節點時,ECI上Pod會因無法連通NodeLocal DNSCache導致網域名稱解析逾時,此時必須對整個Deployment進行注入豁免,可以調整其Pod Template中的Labels標籤欄位加上node-local-dns-injection=disabled

開啟自動注入後,您建立的Pod會被增加以下欄位,為了最大程度上保證業務DNS請求高可用,nameservers中會額外加入kube-dns的ClusterIP地址作為備份的DNS伺服器。

dnsConfig:
  nameservers:
  - 169.254.20.10
  - 172.21.0.10
  options:
  - name: ndots
    value: "3"
  - name: attempts
    value: "2"
  - name: timeout
    value: "1"
  searches:
  - default.svc.cluster.local
  - svc.cluster.local
  - cluster.local
dnsPolicy: None

Pod在同時滿足以下條件時,才會自動注入DNS緩衝。如果您的Pod容器未注入DNS快取服務器的IP地址,請檢查Pod是否未滿足以下條件。

  • 建立Pod不位於kube-system和kube-public命名空間。

  • 建立Pod所在命名空間的Labels標籤包含node-local-dns-injection=enabled

  • 建立Pod所在命名空間的Labels不包含ECI Pod相關標籤,例如virtual-node-affinity-injectionecialibabacloud.com/eci等。

  • 建立Pod沒有被打上ecialibabacloud.com/eci等ECI相關標籤,或打上禁用DNS注入node-local-dns-injection=disabled標籤。

  • 建立Pod的網路為hostNetwork且DNSPolicy為ClusterFirstWithHostNet,或Pod為非hostNetwork且DNSPolicy為ClusterFirst

方式二:手動指定DNSConfig

如果不適用Admission Webhook Deployment自動注入,您可以通過修改Pod進行手動指定DNSConfig。

apiVersion: v1
kind: Pod
metadata:
  name: alpine
  namespace: default
spec:
  containers:
  - image: alpine
    command:
      - sleep
      - "10000"
    imagePullPolicy: Always
    name: alpine
  dnsPolicy: None
  dnsConfig:
    nameservers: ["169.254.20.10","172.21.0.10"]
    searches:
    - default.svc.cluster.local
    - svc.cluster.local
    - cluster.local
    options:
    - name: ndots
      value: "3"
    - name: attempts
      value: "2"
    - name: timeout 
      value: "1"
  • dnsPolicy:必須為None

  • nameservers:配置成169.254.20.10和kube-dns的ClusterIP對應的IP地址。

  • searches:設定搜尋域,保證叢集內部網域名稱能夠被正常解析。

  • ndots:預設為5,可以適當降低ndots以提升解析效率。更多資訊,請參見resolv.conf

方式三:配置kubelet啟動參數

kubelet通過--cluster-dns--cluster-domain兩個參數來全域控制Pod DNSConfig。在/etc/systemd/system/kubelet.service.d/10-kubeadm.conf 設定檔中需要增加一個--cluster-dns參數,設定值為鏈路本地地址169.254.20.10。修改後執行sudo systemctl daemon-reloadsudo systemctl restart kubelet來生效。

--cluster-dns=169.254.20.10 --cluster-dns=<kube-dns ip> --cluster-domain=<search domain>
  • cluster-dns:部署Pod時,預設採用的DNS伺服器位址,預設只引用了`kube-dns` 的服務IP,需要增加一個對鏈路本地地址169.254.20.10的引用。

  • cluster-domain:部署Pod時,預設採用的DNS搜尋域,保持原有搜尋域即可,一般為`cluster.local`

配置應用使用NodeLocal DNSCache樣本

通過在default命名空間下部署Deployment類型樣本應用,示範如何配置應用使用NodeLocal DNSCache。

  1. 執行以下命令,給接入NodeLocal DNSCache的應用所在的命名空間(default)設定標籤。

    kubectl label namespace default node-local-dns-injection=enabled
    重要

    Admission Controller會忽略kube-system和kube-public命名空間下的應用,請勿在這兩個命名空間下進行自動注入dnsConfig操作。

  2. 在叢集的default命名空間下部署樣本應用。

    1. 使用以下YAML模板建立名為ubuntu-deployment的樣本應用。

      apiVersion: apps/v1 # for versions before 1.8.0 use apps/v1beta1
      kind: Deployment
      metadata:
        name: ubuntu
        labels:
          app: ubuntu
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: ubuntu
        template:
          metadata:
            labels:
              app: ubuntu
          spec:
            containers:
            - name: ubuntu
              image: ubuntu
              command: ["sh", "-c"]
              args: ["sleep 100000"]
    2. 執行以下命令,使樣本應用在叢集中生效。

      kubectl apply -f ubuntu-deployment.yaml

      預期輸出:

      deployment.apps/ubuntu created
    3. 執行以下命令,查看應用資訊。

      kubectl get deployment ubuntu

      預期輸出:

      NAME     READY   UP-TO-DATE   AVAILABLE   AGE
      ubuntu   2/2     2            2           7s
  3. 查看是否成功注入dnsConfig

    1. 執行以下命令,查看Pod資訊。

      kubectl get pods

      預期輸出:

      NAME                      READY   STATUS    RESTARTS   AGE
      ubuntu-766448f68c-m****   1/1     Running   0          4m39s
      ubuntu-766448f68c-w****   1/1     Running   0          4m39s
    2. 執行以下命令,查看Pod的dnsConfig是否已經接入NodeLocal DNSCache。

      kubectl get pod ubuntu-766448f68c-m**** -o=jsonpath='{.spec.dnsConfig}'

      預期輸出:

      map[nameservers:[169.254.20.10 172.21.0.10] options:[map[name:ndots value:5]] searches:[default.svc.cluster.local svc.cluster.local cluster.local]]

      當輸出以上內容時,說明成功為應用接入NodeLocal DNSCache。

      開啟自動注入後,您建立的Pod會被增加以下欄位,為了最大程度上保證業務DNS請求高可用,nameservers中會額外加入kube-dns服務的ClusterIP地址(172.21.0.10)作為備份的DNS伺服器。

        dnsConfig:
          nameservers:
          - 169.254.20.10
          - 172.21.0.10
          options:
          - name: ndots
            value: "3"
          - name: attempts
            value: "2"
          - name: timeout
            value: "1"
          searches:
          - default.svc.cluster.local
          - svc.cluster.local
          - cluster.local
        dnsPolicy: None

升級NodeLocal DNSCache

如果您是在組件管理頁面安裝NodeLocal DNSCache,您需要在組件管理頁面升級NodeLocal DNSCache。如果您是在應用目錄頁面安裝NodeLocal DNSCache,您需要在Helm頁面卸載NodeLocal DNSCache,然後再重新安裝NodeLocal DNSCache。

通過組件管理頁面升級NodeLocal DNSCache

  1. 登入Container Service管理主控台,在左側導覽列選擇叢集

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇營運管理 > 組件管理

  3. 組件管理頁面單擊NodeLocal DNSCache下的升級,在彈出的對話方塊中單擊確定

    說明
    • 若您對node-local-dns DaemonSet進行過汙點容忍等修改操作,升級時汙點容忍等操作將會被覆蓋,升級後需要再次設定。

    • 如果升級NodeLocal DNSCache失敗,您需要根據操作異常碼尋找對應的問題,查看問題原因和解決方案。詳細描述,請參見組件異常問題排查

通過應用目錄頁面升級NodeLocal DNSCache

如果您是通過應用目錄頁面安裝NodeLocal DNSCache,您可以先卸載NodeLocal DNSCache,再重新安裝。具體操作,請參見卸載NodeLocal DNSCache安裝NodeLocal DNSCache

卸載NodeLocal DNSCache

如果您是在組件管理頁面安裝NodeLocal DNSCache,您需要在組件管理頁面卸載NodeLocal DNSCache。如果您是在應用目錄頁面安裝NodeLocal DNSCache,您需要在Helm頁面卸載NodeLocal DNSCache。

通過組件管理頁面卸載NodeLocal DNSCache

  1. 登入Container Service管理主控台,在左側導覽列選擇叢集

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇營運管理 > 組件管理

  3. 組件管理頁面單擊NodeLocal DNSCache下的卸載,在彈出的對話方塊中單擊確定

    說明

    卸載後所有解析流量會請求至CoreDNS,建議提前對CoreDNS副本數進行擴容。

通過應用目錄頁面卸載NodeLocal DNSCache

  1. 卸載前檢查。

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇應用 > Helm

    3. Helm頁面單擊ack-node-local-dns-default

    4. 單擊參數配置頁簽,檢查參數。

      • 如果本地監聽IP地址(local_dns_ip)等同於kube-dns的ClusterIP地址,則您可以執行步驟2卸載NodeLocal DNSCache。

      • 如果高可用開關(high_availability)為開啟狀態,且本地監聽IP地址(local_dns_ip)為169.254.20.10。則您可以執行步驟2卸載NodeLocal DNSCache。

      • 如果參數不滿足以上條件,請按照以下流程進行卸載:

        1. 執行kubectl get ns -o yaml命令,檢查哪些命名空間被打上了node-local-dns-injection=enabled的標籤,並將標籤刪除。

        2. 執行kubectl get pod -o yaml命令,檢查哪些業務Pod被注入DNSConfig,刪除這些Pod並重建。

        3. 執行步驟2卸載NodeLocal DNSCache。

  2. 卸載NodeLocal DNSCache。

    1. 在控制台左側導覽列,單擊叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇應用 > Helm

    3. Helm頁面單擊ack-node-local-dns-default操作列的刪除,在彈出的對話方塊中選中清除發布記錄,然後單擊確定

修改Terway配置

  1. 執行以下命令,查看Terway設定檔。

    kubectl -n kube-system edit cm eni-config -o yaml
  2. 檢查Terway設定檔。

    • 檢查設定檔中eniip_virtual_type欄位是否開啟IPVLAN模式。如果設定檔中此項不存在或不是IPVLAN,則您不需要按後續步驟進行配置,可以直接安裝NodeLocal DNSCache。具體操作,請參見安裝NodeLocal DNSCache

    • 檢查設定檔中是否已配置host_stack_cidrs欄位。如果設定檔中已配置host_stack_cidrs 欄位,則您不需要按後續步驟進行配置,可以直接安裝NodeLocal DNSCache。具體操作,請參見安裝NodeLocal DNSCache

  3. 在Terway設定檔中添加host_stack_cidrs欄位,並輸入網段169.254.20.10/32,儲存並退出。

     10-terway.conf: |
      {
        "cniVersion": "0.3.0",
        "name": "terway",
        "eniip_virtual_type": "IPVlan",
        "host_stack_cidrs": ["169.254.20.10/32"], 
        "type": "terway"
      }
  4. 執行以下命令,查看當前Terway的所有DaemonSet容器組。

    kubectl -n kube-system get pod | grep terway-eniip

    預期輸出:

    terway-eniip-7****         2/2     Running   0          30m
    terway-eniip-s****         2/2     Running   0          30m
  5. 執行以下命令,觸發Terway容器組重建。

     kubectl -n kube-system delete pod terway-eniip-7**** terway-eniip-s****
  6. 登入任意叢集節點,執行以下命令,查看Terway設定檔。

    如果Terway設定檔包含添加的網段,則說明配置成功。

    cat /etc/cni/net.d/*

    預期輸出:

     {
       "cniVersion": "0.3.0",
       "name": "terway-chainer",
       "plugins": [
         {
           "eniip_virtual_type": "IPVlan",
           "host_stack_cidrs": [ 
             "169.254.20.10/32",
           ],
           "type": "terway"
         },
         {
           "type": "cilium-cni"
         }
       ]
     }

    所有Terway Pod重建並正常後,您可以繼續安裝NodeLocal DNSCache了。