使用 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
    

疑难解答

如需了解常规 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 中应用程序的网络概念