DNS概述

Kubernetes集群中,Pod访问Service或集群外的服务时使用的是域名,但是域名需要被解析为IP地址才可访问。DNS(Domain Name System)就用于这个场景,它保存了名称与IP地址的对应关系。本文介绍DNS的基础知识、ACK中的DNS组件以及DNS配置。

DNS域名解析原理

虽然互联网设备通过IP地址互相通信,但是域名本身包含了语义,比起IP地址更容易记忆。因此,绝大多数情况下,客户端会通过域名发起请求。下图展示了客户端向example.com发送请求时的流程:

image
  1. 服务器向DNS服务器注册自身的IP地址与域名,DNS服务器会保存对应的记录。

  2. 客户端向DNS服务器询问example.com对应的IP地址。

  3. DNS服务器根据保存的记录将IP返回给客户端。

  4. 客户端使用IP地址访问目标服务器。

集群视角的域名分类

  • 集群内域名:集群内Service的域名,仅在集群内有效。推荐相关业务使用完整域名(<service-name>.<namespace>.svc.<cluster-domain>)格式进行访问。使用短域名(<service-name>)会导致过多无效DNS查询,增加解析耗时。

    cluster-domain在集群创建时自定义配置,默认为cluster.local
  • 集群外域名:包含VPC内域名和公网域名。解析这些域名时,CoreDNS需要从上游DNS服务器获取解析结果。上游DNS默认为内网域名解析(PrivateZone)服务,IP地址100.100.2.136100.100.2.138。

    重要

    内网域名解析对公网域名的递归解析不提供SLA保障。递归解析的使用限制,请参见递归管理

集群中的DNS组件

ACK托管集群中,有两个负责DNS的组件:CoreDNSNodeLocal DNSCache

CoreDNS

CoreDNS分为托管与非托管两种形态:

比较项

CoreDNS托管版

CoreDNS非托管版

适用集群

  • ACK托管集群

  • ACK专有集群

  • ACK Serverless集群

部署模式

部署在集群控制面,由ACK全面托管。

在控制台的组件管理页面,托管版组件卡片将显示托管

通过工作负载(Deployment)的形式部署在集群中,默认安装在kube-system命名空间下,会占用Worker节点的资源。

运维职责

阿里云负责组件运维。

责任共担模式:

  • 阿里云提供组件软件版本及技术支持,并提供可配置参数供客户运维使用。

  • 客户需要保障集群下有充足的资源部署CoreDNS,开启日志和监控告警功能,并负责组件的资源规格配置、升级、扩缩容,请参见非托管CoreDNS稳定性与高性能部署建议进行配置。

功能特性

  • 默认支持弹性扩缩容,扩缩容时效性约5~10分钟。

  • 通过CRD支持通用场景中的自定义参数配置

  • 支持自定义组件使用的资源规格。

  • 默认未配置弹性扩缩容,支持用户自行配置

  • 支持通过修改kube-system命名空间下名为corednsConfigMap进行自定义配置。

日志

默认开启日志。

支持,需手动开启CoreDNS日志

监控与告警

支持Prometheus监控,需要为集群接入与配置监控

性能

CoreDNS托管版性能说明

取决于组件配置。

CoreDNS非托管版

CoreDNSKubernetes集群中负责DNS解析的组件,能够支持解析集群内部自定义服务域名和集群外部域名。CoreDNS项目由CNCF托管。关于CoreDNS的更多信息,请参见CoreDNS: DNS and Service Discovery

与开源Kubernetes标准相同,ACK集群默认安装CoreDNS作为DNS服务器。CoreDNSDeployment的方式部署在了集群的kube-system命名空间下。kube-dns则是CoreDNS所属的ClusterIP类型的Service。CoreDNS的配置方法,请参见非托管CoreDNS配置说明

通过kubectl查看CoreDNS所属的资源

  1. 查看Deployment

    kubectl get deployment -l k8s-app=kube-dns -n kube-system 

    预期输出:

    NAME      READY   UP-TO-DATE   AVAILABLE   AGE
    coredns   2/2     2            2           1h
  2. 查看Service

    kubectl get service -n kube-system kube-dns

    预期输出:

    NAME       TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                  AGE
    kube-dns   ClusterIP   172.**.**.**   <none>        53/UDP,53/TCP,9153/TCP   1h

下面的示例中,处于default命名空间的Pod尝试访问database-svc,经历了以下流程:

image
  1. Pod查看/etc/resolv.conf配置文件,确定了DNS服务器的IP172.0.XX.XX,这是kube-dnsClusterIP。示例配置文件内容如下。

    nameserver 172.0.XX.XX                                              # 定义DNS服务器的IP地址。
    search default.svc.cluster.local svc.cluster.local cluster.local    # 设置域名的查找后缀规则,查找配置越多,说明域名解析查找匹配次数越多。
    options ndots:5                                                     # 定义域名解析配置文件选项,支持多个KV值。
  2. Podkube-dns发起DNS查询,它会以search中的值作为后缀发起查询,即依次尝试查询:

    1. database-svc.default.svc.cluster.local(与Pod同一命名空间的Service)

    2. database-svc.svc.cluster.local(其他命名空间的Service)

    3. database-svc.cluster.local(集群范围内的域名)

    4. database-svc(集群外域名)

  3. CoreDNS Pod返回结果,对应的IP172.4.XX.XX。

  4. Pod使用此IP访问目标服务database-svc

  5. 如果请求的是集群外域名,例如VPC域名、公网域名等,CoreDNS Pod将向上游DNS服务发起查询。

    重要

    请勿修改节点DNS Server配置,因为CoreDNS默认继承所在节点的上游DNS服务地址。

    CoreDNS的配置保存于kube-system命名空间中的coredns配置项 。默认配置中的forward指向/etc/resolv.conf,表示需要向上游DNS服务查询时,使用CoreDNS容器/etc/resolv.conf中保存的DNS Server地址,而CoreDNS/etc/resolv.conf默认与所在节点的/etc/resolv.conf相同,节点默认保存的DNS Server地址为100.100.2.136100.100.2.138。如果修改节点的DNS Server配置,会导致CoreDNS使用错误的上游DNS服务地址,导致解析失败或结果不符合预期。

        .:53 {
            ...
            forward . /etc/resolv.conf {
              prefer_udp
            }
            ...
        }

CoreDNS托管版

CoreDNS托管版的工作原理与非托管CoreDNS相同,但由ACK托管。CoreDNS托管版不占用集群资源,也无需用户自行运维,同时会按照负载自动执行弹性伸缩,CoreDNS托管版的性能说明请参见CoreDNS托管版性能说明

ACK智能托管模式支持CoreDNS托管版。如需使用ACK智能托管模式,请参见创建ACK托管集群(智能托管模式)

NodeLocal DNSCache

NodeLocal DNSCache会在每个Worker节点配置DNS缓存,可以降低CoreDNS的压力,提升集群DNS的稳定性和可用性。在DNS负载较高,对DNS请求响应速度和稳定性和较高要求的场景中建议安装。请参见使用NodeLocal DNSCache组件安装并使用组件。

下面的示例中,在安装了NodeLocal DNSCache且给default命名空间打上node-local-dns-injection: "enabled"标签后,处于default命名空间的Pod尝试访问database-svc,经历了以下流程:

image
  1. Pod会首先查看所在节点的DNS缓存。

  2. 根据节点DNS缓存是否命中,此时会分为两种情况:

    1. 缓存命中,即节点DNS缓存中有database-svc记录,则缓存返回结果,Pod使用结果访问服务。

    2. 缓存未命中,即节点DNS缓存中没有database-svc记录,则仍旧通过CoreDNS获取结果。从CoreDNS获取的结果将同步到节点DNS缓存以便后续使用。

集群DNS配置

集群中的DNS配置可分为下列三个维度,它们分别作用于不同的范围。

集群配置(全局)

ClusterDomain是每个节点的kubelet配置,但是在整个集群内所有节点的kubelet中都应保持一致,否则会出现网络错误。

  • ClusterDomain

    ClusterDomain是集群本地顶级域名,即集群中所有Service完整域名的默认后缀,默认为cluster.local。ClusterDomain配置通常用于区分集群内网络与集群外网络。在创建集群时,可对ClusterDomain自定义,请勿与常用的外部域名重合。

    image.png

节点配置

  • resolveConf

    resolveConf指定节点上 DNS 配置文件的路径。当 Pod 的 dnsPolicyDefault 时,kubelet 会将 resolveConf 指定的文件(默认 /etc/resolv.conf)复制到 Pod 的 /etc/resolv.conf 中。

Pod配置

  • 每个Pod都有两个配置:dnsPolicydnsConfig,可通过它们为Pod自定义DNS策略。dnsPolicy定义PodDNS解析策略,dnsConfig 用于自定义 DNS 服务器和搜索域。请参见DNS策略配置和域名解析说明,了解如何结合场景使用dnsPolicydnsConfig