文档首页/ 云容器引擎 CCE/ 用户指南/ 网络/ DNS/ 使用NodeLocal DNSCache提升DNS性能
更新时间:2024-10-24 GMT+08:00
分享

使用NodeLocal DNSCache提升DNS性能

应用现状

当集群中的DNS请求量增加时,CoreDNS将会承受更大的压力,可能会导致如下影响:

  • 延迟增加:CoreDNS需要处理更多的请求,可能会导致DNS查询变慢,从而影响业务性能。
  • 资源占用率增加:为保证DNS性能,CoreDNS往往需要更高规格的配置。

解决方案

为了避免DNS延迟的影响,可以在集群中部署NodeLocal DNSCache来提升服务发现的稳定性和性能。NodeLocal DNSCache会在集群节点上运行DNS缓存代理,所有注入DNS配置的Pod都会使用节点上运行的DNS缓存代理进行域名解析,而不是使用CoreDNS服务,以此来减少CoreDNS服务的压力,提高集群DNS性能。

启用NodeLocal DNSCache之后,DNS查询所遵循的路径如下图所示。

图1 NodeLocal DNSCache查询路径
其中解析线路说明如下:
  • ①:已注入DNS本地缓存的Pod,默认会通过NodeLocal DNSCache解析请求域名。
  • ②:NodeLocal DNSCache本地缓存如果无法解析请求,则会请求集群CoreDNS进行解析。
  • ③:对于非集群内的域名,CoreDNS会通过VPC的DNS服务器进行解析。
  • ④:已注入DNS本地缓存的Pod,如果无法连通NodeLocal DNSCache,则会直接通过CoreDNS解析域名。
  • ⑤:未注入DNS本地缓存的Pod,默认会通过CoreDNS解析域名。

约束与限制

  • 节点本地域名解析加速插件仅支持1.19及以上版本集群。
  • CCI上不支持NodeLocal DNSCache。当负载动态弹性伸缩到CCI时,CCI上Pod会因为无法联通NodeLocal DNSCache导致域名解析超时。因此创建弹性到CCI的负载时,需为Pod添加node-local-dns-injection: disabled的标签,避免DNSConfig自动注入,详情请参见常见问题
  • node-local-dns-injection标签为NodeLocal DNSCache使用的系统标签,除避免DNSConfig自动注入的场景外,应避免使用该标签。

插件安装

CCE提供了节点本地域名解析加速插件,可以快捷安装NodeLocal DNSCache。

NodeLocal DNSCache不提供Hosts、Rewrite等插件能力,仅作为CoreDNS的透明缓存代理。如有需要,可在CoreDNS配置中修改。

  1. (可选)修改CoreDNS配置,让CoreDNS优先采用UDP协议与上游DNS服务器通信。

    NodeLocal DNSCache采用TCP协议与CoreDNS进行通信,CoreDNS会根据请求来源使用的协议与上游DNS服务器进行通信。当使用了NodeLocal DNSCache时,访问上游DNS服务器时会使用TCP协议,而云上DNS服务器对TCP协议支持有限,如果您使用了NodeLocal DNSCache,您需要修改CoreDNS配置,让其总是优先采用UDP协议与上游DNS服务器进行通信,避免解析异常。

    执行如下步骤,在forward插件中指定请求上游的协议为perfer_udp,修改之后CoreDNS会优先使用UDP协议与上游通信。

    1. 登录CCE控制台,单击集群名称进入集群。
    2. 在左侧导航栏中选择“插件中心”,在CoreDNS下单击“编辑”,进入插件详情页。
    3. “参数配置”下编辑扩展参数,在plugins字段修改以下内容。
      {
          "configBlock": "prefer_udp",
          "name": "forward",
          "parameters": ". /etc/resolv.conf"
      }
      如果使用Corefile视图,则对应的Corefile为:
      Corefile: |-
        .:5353 {
            bind {$POD_IP}
            cache 30 {
                servfail 5s
            }
            errors
            health {$POD_IP}:8080
            kubernetes cluster.local in-addr.arpa ip6.arpa {
                pods insecure
                fallthrough in-addr.arpa ip6.arpa
            }
            loadbalance round_robin
            prometheus {$POD_IP}:9153
            forward . /etc/resolv.conf {
                prefer_udp
            }
            reload
            ready {$POD_IP}:8081
        }

  2. 登录CCE控制台,单击集群名称进入集群,在左侧导航栏中选择“插件中心”,在右侧找到节点本地域名解析加速插件,单击“安装”
  3. 在安装插件页面,选择插件规格,并配置相关参数。

    • DNSConfig自动注入:启用后,会创建DNSConfig动态注入控制器,该控制器基于Admission Webhook机制拦截目标命名空间(即命名空间包含标签node-local-dns-injection=enabled)下Pod的创建请求,自动为Pod配置DNSConfig。未开启DNSConfig自动注入或Pod属于非目标命名空间,则需要手动给Pod配置DNSConfig。
      开启自动注入后,您可以为DNSConfig自定义以下配置项(插件版本为1.6.7及以上支持):

      如果开启自动注入时Pod中已经配置了DNSConfig,则优先使用Pod中的DNSConfig。

      • 域名解析服务器地址nameserver(可选):容器解析域名时查询的DNS服务器的IP地址列表。默认会添加NodeLocal DNSCache的地址,以及CoreDNS的地址,允许用户额外追加1个地址,重复的IP地址将被删除。
      • 搜索域search(可选):定义域名的搜索域列表,当访问的域名不能被DNS解析时,会把该域名与搜索域列表中的域依次进行组合,并重新向DNS发起请求,直到域名被正确解析或者尝试完搜索域列表为止。允许用户额外追加3个搜索域,重复的域名将被删除。
      • ndots(可选):该参数的含义是当域名的“.”个数小于ndots的值,会先把域名与search搜索域列表进行组合后进行DNS查询,如果均没有被正确解析,再以域名本身去进行DNS查询。当域名的“.”个数大于或者等于ndots的值,会先对域名本身进行DNS查询,如果没有被正确解析,再把域名与search搜索域列表依次进行组合后进行DNS查询。
    • 目标命名空间:启用DNSConfig自动注入时支持设置。仅1.3.0及以上版本的插件支持。
      • 全部开启:CCE会为已创建的命名空间添加标签(node-local-dns-injection=enabled),同时会识别命名空间的创建请求并自动添加标签,这些操作的目标不包含系统内置的命名空间(如kube-system)。
      • 手动配置:手动为需要注入DNSConfig的命名空间添加标签(node-local-dns-injection=enabled),操作步骤请参见管理命名空间标签

  4. 完成以上配置后,单击“安装”

使用NodeLocal DNSCache

默认情况下,应用的请求会通过CoreDNS代理,如果需要使用node-local-dns进行DNS缓存代理,您有以下几种方式可以选择:

  • 自动注入:创建Pod时自动配置Pod的dnsConfig字段。(kube-system等系统命名空间下的Pod不支持自动注入)
  • 手动配置:手动配置Pod的dnsConfig字段,从而使用NodeLocal DNSCache。

开启自动注入的操作步骤如下:

  1. 安装节点本地域名解析加速插件,并开启“DNSConfig自动注入”,详情请参见插件安装
  2. 使用kubectl连接集群,为命名空间添加node-local-dns-injection=enabled标签。例如,为default命名空间添加该标签的命令如下:

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

  3. 在开启自动注入的命名空间中,任意创建一个工作负载。操作步骤详情请参见创建无状态负载(Deployment)

    开启自动注入的Pod需满足以下要求:

    • 新建Pod不位于kube-system和kube-public等系统命名空间。
    • 新建Pod没有被打上禁用DNS注入的标签node-local-dns-injection=disabled。
    • 新建Pod的DNSPolicy设置为ClusterFirstWithHostNet,或Pod未使用hostNetwork且DNSPolicy为ClusterFirst。

  4. 查看该Pod的配置。

    kubectl get pod <pod_name> -oyaml
    开启自动注入后,创建的Pod会自动添加如下dnsConfig字段,其中nameservers字段中除了NodeLocal DNSCache的地址(169.254.20.10)外,还添加了CoreDNS的地址(10.247.3.10),保障了业务DNS请求高可用。
    ...
      dnsConfig:
        nameservers:
          - 169.254.20.10
          - 10.247.3.10
        searches:
          - default.svc.cluster.local
          - svc.cluster.local
          - cluster.local
        options:
          - name: timeout
            value: ''
          - name: ndots
            value: '5'
          - name: single-request-reopen
    ...

手动配置即自行给Pod加上dnsConfig配置。

  1. 使用kubectl连接集群,详情请参见通过kubectl连接集群
  2. 创建一个Pod,并在dnsConfig中的nameservers配置中添加NodeLocal DNSCache的地址(169.254.20.10)。

    不同集群类型的NodeLocal DNSCache地址如下:

    • CCE Standard集群:169.254.20.10
    • CCE Turbo集群:169.254.1.1

    创建nginx.yaml文件,示例如下:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
    spec:
      containers:
      - image: nginx:alpine
        name: container-0
      dnsConfig:
        nameservers:
        - 169.254.20.10
        - 10.247.3.10
        searches:
        - default.svc.cluster.local
        - svc.cluster.local
        - cluster.local
        options:
        - name: ndots
          value: '2'
      imagePullSecrets:
      - name: default-secret

  3. 执行以下命令创建Pod。

    kubectl create -f nginx.yaml

常见问题

  • 如何让指定Pod避免自动注入DNSConfig?

    解决方案:

    如果某个工作负载需要避免DNSConfig自动注入,可在Pod模板的labels字段中添加node-local-dns-injection: disabled的标签。示例如下:
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: test
      namespace: default
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: test
      template:
        metadata:
          labels:
            app: test
            node-local-dns-injection: disabled   # 避免DNSConfig自动注入
        spec:
          containers:
            - name: container-1
              image: nginx:latest
              imagePullPolicy: IfNotPresent
          imagePullSecrets:
            - name: default-secret

相关文档