CoreDNS稳定性与高性能部署建议

CoreDNS是集群中的默认DNS Server,集群中Service和集群外域名的解析全部需要通过CoreDNS完成。CoreDNS的服务不可用会严重影响集群内的其他服务。在不同场景中,CoreDNS性能和可用性的要求有所区别,默认配置无法适配所有场景。请根据实际业务场景,采用本文中的建议对CoreDNS组件进行配置。

背景信息

在高负载场景下,默认配置的CoreDNS可能出现以下可用性问题:

  • 与同节点工作负载资源争用,响应延迟增加;

  • 节点负载过高导致网络I/O丢包;

  • 资源不足引发Pod被驱逐,服务中断。

上述问题将导致集群域名解析失败,影响所有依赖DNS的服务。建议采取下列操作提高CoreDNS的性能和可用性:

下列操作可并行执行,请根据集群实际情况调整。
重要
  • CoreDNS组件在非托管模式下,需要用户自行负责运维和健康状态监控,包括资源配置优化、故障排查、版本升级以及高可用性保障,以确保集群的 DNS 服务稳定运行。ACK托管集群智能托管模式支持CoreDNS托管版,请参见CoreDNS托管版性能说明

  • 调整CoreDNS Pod规格与使CoreDNS部署到独占节点池的操作都可能导致Pod暂时失效,可能会导致集群中出现概率性DNS延迟超时、解析失败的情况,建议在业务低峰期进行操作。

评估CoreDNS组件压力

包括DNSPerf在内的许多开源工具可评估集群内的整体DNS压力。如果无法准确评估,请参照下方的推荐的标准:

  • 在任何情况下,建议设置CoreDNS Pod数应至少为2,单个Pod的资源limit不小于11G。

  • CoreDNS所能提供的域名解析QPSCPU消耗成正相关,使用NodeLocal DNSCache的情况下,每CPU核可以支撑10000+ QPS的域名解析请求。不同类型的业务对域名请求的QPS需求存在较大差异,可以观察每个CoreDNS Pod的峰值CPU使用量,如果其在业务峰值期间占用CPU大于一核,建议对CoreDNS进行副本扩容。无法确定峰值CPU使用量时,可以保守地采用Pod数和集群节点数1:8的比值来部署,即每扩容8个集群节点,增加一个CoreDNS Pod。

调整CoreDNS Pod数量

重要
  • 由于UDP报文缺少重传机制,当集群节点存在IPVS UDP缺陷导致的丢包风险时,CoreDNS Pod的缩容或重启可能会导致长达五分钟的整个集群域名解析超时或异常。关于IPVS缺陷导致解析异常的解决方案,请参见DNS解析异常问题排查

  • 请勿使用工作负载自动伸缩:虽然工作负载自动伸缩,例如容器水平伸缩(HPA)、容器定时水平伸缩(CronHPA)等也可以自动调整Pod数量,但是它们会频繁执行扩缩容。由于Pod缩容时导致的解析异常,请勿使用工作负载自动伸缩控制CoreDNS Pod数量。

配置自动调整(推荐)

下方的cluster-proportional-autoscaler会参照评估CoreDNS组件压力中的推荐策略(Pod数和集群节点数1:8)实时自动调整CoreDNSPod数量。相较于容器水平伸缩(HPA),它不依赖CoreDNS CPU负载指标,适用于副本数量需求与集群规模成正比的服务。

示例中Pod数量的计算公式为replicas = max (ceil (cores × 1/coresPerReplica), ceil (nodes × 1/nodesPerReplica) ),且通过min、max限制了最小Pod数量为2,最大为100。

cluster-proportional-autoscaler

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dns-autoscaler
  namespace: kube-system
  labels:
    k8s-app: dns-autoscaler
spec:
  selector:
    matchLabels:
      k8s-app: dns-autoscaler
  template:
    metadata:
      labels:
        k8s-app: dns-autoscaler
    spec:
      serviceAccountName: admin
      containers:
      - name: autoscaler
        image: registry.cn-hangzhou.aliyuncs.com/acs/cluster-proportional-autoscaler:1.8.4
        resources:
          requests:
            cpu: "200m"
            memory: "150Mi"
        command:
        - /cluster-proportional-autoscaler
        - --namespace=kube-system
        - --configmap=dns-autoscaler
        - --nodelabels=type!=virtual-kubelet
        - --target=Deployment/coredns
        - --default-params={"linear":{"coresPerReplica":64,"nodesPerReplica":8,"min":2,"max":100,"preventSinglePointFailure":true}}
        - --logtostderr=true
        - --v=9

手动调整

也可通过下方的命令手动调整CoreDNS所属的Pod数量。

kubectl scale --replicas={target} deployment/coredns -n kube-system # target替换为目标Pod数量

调整CoreDNS Pod规格

ACK托管集群Pro中,CoreDNS Pod默认的内存限制为2Gi,CPU则未限制。推荐将CPU Limit设置为4096m, 最小应不低于1024m。可通过控制台对CoreDNS Pod配置进行调整。

  1. 登录容器服务管理控制台,在左侧导航栏选择集群列表

  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,单击组件管理

  3. 单击网络页签,找到CoreDNS卡片。单击卡片上的配置

    image

  4. 修改CoreDNS配置,然后单击确认

    image

CoreDNS Pod采用独占节点池部署

CoreDNS Pod组件使用独占节点池的方式部署,可使CoreDNS负载与集群中其他应用完全隔离,不受资源抢占的影响。

新建CoreDNS专属节点池

CoreDNS Pod新建专属节点池。请注意下列事项:

  • CoreDNS对计算资源要求不高,但是需要较高网络性能。建议选择网络增强型实例,规格可选48GB。

  • CoreDNS默认部署两个Pod,节点池中至少需要两个节点。

  • 节点池需要进行污点和标签配置以避免其他Pod调度。例如,可在污点和标签中都添加system-addon: system-addon键值对,将污点Effect设置为NoSchedule,并在下一步骤中使用。

创建节点池的具体操作,请参见创建和管理节点池

配置CoreDNS组件调度Pod

  1. 组件管理页面找到CoreDNS卡片,单击配置

  2. NodeSelector中添加专属节点池标签。

    请勿删除已有的NodeSelector标签

    image.png

  3. Tolerations中添加专属节点池标签

    image.png

  4. 单击确认保存组件配置。然后执行下方命令,确认CoreDNS Pod是否已调度到专属节点池。

    kubectl -n kube-system get pod -o wide --show-labels | grep coredns