你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 Azure Kubernetes 服务自定义 CoreDNS

Azure Kubernetes 服务 (AKS) 可将适用于管理和解决群集 DNS 问题的 CoreDNS 项目与所有 1.12.x 及更高版本的群集配合使用。 有关 CoreDNS 自定义和 Kubernetes 的详细信息,请参阅官方的上游文档

由于 AKS 是一项托管服务,因此你无法修改 CoreDNS (CoreFile) 的主要配置。 可以改用 Kubernetes ConfigMap 来替代默认设置。 若要查看默认的 AKS CoreDNS ConfigMap,请使用 kubectl get configmaps --namespace=kube-system coredns -o yaml 命令。

本文介绍如何在 AKS 中将 ConfigMaps 用于 CoreDNS 的基本自定义选项。 此方法不同于在其他上下文(例如 CoreFile)中配置 CoreDNS。

注意

以前,kube-dns 用于群集 DNS 管理和解析,但现在已弃用。 kube-dns 通过 Kubernetes 配置映射提供不同的自定义选项。 CoreDNS 后向兼容 kube-dns。 以前使用的任何自定义项都必须在更新后才能用于 CoreDNS。

准备阶段

  • 本文假定你拥有现有的 AKS 群集。 如果需要 AKS 群集,可以使用 Azure CLIAzure PowerShellAzure 门户 创建一个。
  • 验证正在运行的 CoreDNS 版本。 版本之间的配置值可能会发生更改。
  • 创建类似以下示例的配置时,data 部分中的名称必须以 .server 或 .override 结尾。 这个命名约定是在默认的 AKS CoreDNS ConfigMap 中定义的,可以使用 kubectl get configmaps --namespace=kube-system coredns -o yaml 命令查看。

插件支持

支持所有内置 CoreDNS 插件。 不支持任何附加/第三方插件。

重写 DNS

可以使用 AKS 自定义 CoreDNS,以执行动态 DNS 名称重写。

  1. 创建名为 corednsms.yaml 的文件并粘贴以下示例配置。 请确保将 <domain to be rewritten> 替换为你自己的完全限定的域名。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      test.server: |
        <domain to be rewritten>.com:53 {
        log
        errors
        rewrite stop {
          name regex (.*)\.<domain to be rewritten>\.com {1}.default.svc.cluster.local
          answer name (.*)\.default\.svc\.cluster\.local {1}.<domain to be rewritten>.com
        }
        forward . /etc/resolv.conf # you can redirect this to a specific DNS server such as 10.0.0.10, but that server must be able to resolve the rewritten domain name
        }
    

    重要

    如果重定向到 DNS 服务器(例如 CoreDNS 服务 IP),则该 DNS 服务器必须能够解析重写的域名。

  2. 使用 kubectl apply configmap 命令创建 ConfigMap,并指定 YAML 清单的名称。

    kubectl apply -f corednsms.yaml
    
  3. 验证是否已使用 kubectl get configmaps 应用自定义项,并指定 coredns-custom ConfigMap。

    kubectl get configmaps --namespace=kube-system coredns-custom -o yaml
    
  4. 若要重新加载 ConfigMap 并支持 Kubernetes 计划程序在不停机的情况下重启 CoreDNS,请使用 kubectl rollout restart 执行滚动重启。

    kubectl -n kube-system rollout restart deployment coredns
    

自定义转发服务器

如需为网络流量指定转发服务器,可以创建 ConfigMap 以自定义 DNS。

  1. 创建名为 corednsms.yaml 的文件并粘贴以下示例配置。 请确保将 forward 名称和地址替换为自己环境的相应值。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      test.server: | # you may select any name here, but it must end with the .server file extension
        <domain to be rewritten>.com:53 {
            forward foo.com 1.1.1.1
        }
    
  2. 使用 kubectl apply configmap 命令创建 ConfigMap,并指定 YAML 清单的名称。

    kubectl apply -f corednsms.yaml
    
  3. 若要重新加载 ConfigMap 并支持 Kubernetes 计划程序在不停机的情况下重启 CoreDNS,请使用 kubectl rollout restart 执行滚动重启。

    kubectl -n kube-system rollout restart deployment coredns
    

使用自定义域

可能需要配置只能在内部进行解析的自定义域。 例如,可能需要解析自定义域 puglife.local,该域不是有效的顶级域。 在没有自定义域 ConfigMap 的情况下,AKS 群集无法解析该地址。

  1. 创建名为 corednsms.yaml 的新文件并粘贴以下示例配置。 确保将自定义域和 IP 地址更新为自己环境的相应值。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      puglife.server: | # you may select any name here, but it must end with the .server file extension
        puglife.local:53 {
            errors
            cache 30
            forward . 192.11.0.1  # this is my test/dev DNS server
        }
    
  2. 使用 kubectl apply configmap 命令创建 ConfigMap,并指定 YAML 清单的名称。

    kubectl apply -f corednsms.yaml
    
  3. 若要重新加载 ConfigMap 并支持 Kubernetes 计划程序在不停机的情况下重启 CoreDNS,请使用 kubectl rollout restart 执行滚动重启。

    kubectl -n kube-system rollout restart deployment coredns 
    

存根域

CoreDNS 也可用于配置存根域。

  1. 创建名为 corednsms.yaml 的文件并粘贴以下示例配置。 确保将自定义域和 IP 地址更新为自己环境的相应值。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      test.server: | # you may select any name here, but it must end with the .server file extension
        abc.com:53 {
         errors
         cache 30
         forward . 1.2.3.4
        }
        my.cluster.local:53 {
            errors
            cache 30
            forward . 2.3.4.5
        }
    
    
  2. 使用 kubectl apply configmap 命令创建 ConfigMap,并指定 YAML 清单的名称。

    kubectl apply -f corednsms.yaml
    
  3. 若要重新加载 ConfigMap 并支持 Kubernetes 计划程序在不停机的情况下重启 CoreDNS,请使用 kubectl rollout restart 执行滚动重启。

    kubectl -n kube-system rollout restart deployment coredns
    

Hosts 插件

由于所有内置插件都受支持,因此 CoreDNS 主机插件也可用于自定义 /etc/hosts。

  1. 创建名为 corednsms.yaml 的文件并粘贴以下示例配置。 确保将 IP 地址和主机名更新为自己环境的相应值。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom # this is the name of the configmap you can overwrite with your changes
      namespace: kube-system
    data:
        test.override: | # you may select any name here, but it must end with the .override file extension
              hosts { 
                  10.0.0.1 example1.org
                  10.0.0.2 example2.org
                  10.0.0.3 example3.org
                  fallthrough
              }
    
  2. 使用 kubectl apply configmap 命令创建 ConfigMap,并指定 YAML 清单的名称。

    kubectl apply -f corednsms.yaml
    
  3. 若要重新加载 ConfigMap 并支持 Kubernetes 计划程序在不停机的情况下重启 CoreDNS,请使用 kubectl rollout restart 执行滚动重启。

    kubectl -n kube-system rollout restart deployment coredns
    

internal.cloudapp.net 和 reddog.microsoft.com 的搜索域完成无效

Azure DNS 在使用 Azure DNS 的虚拟网络中配置 <vnetId>.<region>.internal.cloudapp.net 的默认搜索域,在使用自定义 DNS 服务器的虚拟网络中配置非功能存根 reddog.microsoft.com(有关更多详细信息,请参阅资源的名称解析文档)。 Kubernetes 使用 ndots: 5 配置 Pod DNS 设置,以正确支持群集服务主机名解析。 这两种配置组合在一起,导致在系统通过域搜索列表处理时永远不会成功发送到上游名称服务器的搜索域完成查询无效。 这些无效的查询会导致名称解析延迟,并可能给上游 DNS 服务器带来额外的负载。

从 v20241025 AKS 版本开始,AKS 将 CoreDNS 配置为在下面两种情况下响应 NXDOMAIN,以防止这些无效的搜索域完成查询转发给上游 DNS:

  • 针对根域或 reddog.microsoft.com 的子域的任何查询。
  • 针对域名中具有 7 个或更多标签的 internal.cloudapp.net 的子域的任何查询。
    • 在此配置下,按主机名解析虚拟机仍然会成功。 例如,CoreDNS 将 aks12345.myvnetid.myregion.internal.cloudapp.net(6 个标签)发送到 Azure DNS,但拒绝 mcr.microsoft.com.myvnetid.myregion.internal.cloudapp.net(8 个标签)

此块在群集 Corefile 的默认服务器块中实现。 如果需要,可以通过为启用了转发插件的相应域创建自定义服务器块来禁用此拒绝配置:

  1. 创建名为 corednsms.yaml 的文件并粘贴以下示例配置。 确保将 IP 地址和主机名更新为自己环境的相应值。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom # this is the name of the configmap you can overwrite with your changes
      namespace: kube-system
    data:
        override-block.server:
           internal.cloudapp.net:53 {
               errors
               cache 30
               forward . /etc/resolv.conf
           }
           reddog.microsoft.com:53 {
               errors
               cache 30
               forward . /etc/resolv.conf
           }
    
  2. 使用 kubectl apply configmap 命令创建 ConfigMap,并指定 YAML 清单的名称。

    kubectl apply -f corednsms.yaml
    
  3. 若要重新加载 ConfigMap 并支持 Kubernetes 计划程序在不停机的情况下重启 CoreDNS,请使用 kubectl rollout restart 执行滚动重启。

    kubectl -n kube-system rollout restart deployment coredns
    

疑难解答

如需了解常规 CoreDNS 故障排除步骤(例如检查终结点或解析),请参阅调试 DNS 解析

配置 CoreDNS Pod 缩放

由于 AKS 为工作负载提供的弹性,AKS 群集内的 DNS 流量突然激增是一种常见现象。 这些峰值可能导致 CoreDNS Pod 的内存消耗增加。 在某些情况下,内存消耗增加可能会导致 Out of memory 问题。 为了解决这个问题,AKS 群集会自动缩放 CoreDNS Pod,以减少每个 Pod 的内存使用量。 此自动缩放逻辑的默认设置存储在 coredns-autoscaler ConfigMap 中。 但是,你可能会发现,CoreDNS Pod 的默认自动缩放并不总是足够主动地防止 CoreDNS Pod 出现 Out of memory 问题。 在这种情况下,可以直接修改 coredns-autoscaler ConfigMap。 请注意,仅增加 CoreDNS Pod 的数量而不解决 Out of memory 问题的根本原因可能只能提供临时修复。 如果运行 CoreDNS Pod 的节点中没有足够的可用内存,则增加 CoreDNS Pod 的数量将无济于事。 可能需要进一步调查并实施适当的解决方案,例如优化资源使用率、调整资源请求和限制或向节点添加更多内存。

CoreDNS 使用水平群集按比例自动缩放程序进行 Pod 自动缩放。 可以编辑 coredns-autoscaler ConfigMap,以配置 CoreDNS Pod 数量的缩放逻辑。 coredns-autoscaler ConfigMap 目前支持两个不同的 ConfigMap 键值:linearladder,它们对应于两种受支持的控制模式。 linear 控制器可在 [min,max] 范围内生成与 max( ceil( cores * 1/coresPerReplica ) , ceil( nodes * 1/nodesPerReplica ) ) 等效的副本数。 ladder 控制器通过咨询两个不同的阶跃函数来计算副本数,一个用于核心缩放,另一个用于节点缩放,从而生成两个副本值的最大值。 有关控制模式和 ConfigMap 格式的详细信息,请参阅上游文档

重要

建议每个群集至少包含 2 个 CoreDNS Pod 副本。 配置至少 1 个 CoreDNS Pod 副本可能会导致在需要耗尽节点的操作(例如群集升级操作)中发生故障。

若要检索 coredns-autoscaler ConfigMap,可以运行 kubectl get configmap coredns-autoscaler -n kube-system -o yaml 命令,它将返回以下内容:

apiVersion: v1
data:
  ladder: '{"coresToReplicas":[[1,2],[512,3],[1024,4],[2048,5]],"nodesToReplicas":[[1,2],[8,3],[16,4],[32,5]]}'
kind: ConfigMap
metadata:
  name: coredns-autoscaler
  namespace: kube-system
  resourceVersion: "..."
  creationTimestamp: "..."

启用 DNS 查询日志记录

  1. 将以下配置添加到 coredns-custom ConfigMap:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      log.override: | # you may select any name here, but it must end with the .override file extension
            log
    
  2. 使用以下命令应用配置更改并强制 CoreDNS 重新加载 ConfigMap:

    # Apply configuration changes
    kubectl apply -f corednsms.yaml
    
    # Force CoreDNS to reload the ConfigMap
    kubectl -n kube-system rollout restart deployment coredns
    
  3. 使用 kubectl logs 命令查看 CoreDNS 调试日志记录。

    kubectl logs --namespace kube-system -l k8s-app=kube-dns
    

后续步骤

本文介绍了一些适用于 CoreDNS 自定义的示例方案。 有关 CoreDNS 项目的信息,请参阅 CoreDNS 上游项目页

若要详细了解核心网络概念,请参阅 AKS 中应用程序的网络概念