DNS原理和配置说明

本文介绍ACS集群中的DNS服务原理,并针对不同场景介绍如何配置DNS策略。

背景信息

ACS集群默认不会部署DNS服务,您需要在创建集群时选中CoreDNS。通过kube-dns的服务名暴露DNS服务。您可以执行以下命令查看kube-dns的服务详情。关于创建集群的具体操作,请参见创建ACS集群

kubectl get svc kube-dns -n kube-system

预期输出:

NAME       TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   172.24.0.10   <none>        53/UDP,53/TCP,9153/TCP   27d

集群DNS域名解析原理

ACS集群中kubelet的启动参数有--cluster-dns=<dns-service-ip>--cluster-domain=<default-local-domain>,这两个参数分别被用来设置集群DNS服务器的IP地址和主域名后缀。

Pod内的DNS域名解析配置文件为/etc/resolv.conf,文件内容如下。

nameserver xx.xx.0.10
search kube-system.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

参数

描述

nameserver

定义DNS服务器的IP地址。

search

设置域名的查找后缀规则,查找配置越多,说明域名解析查找匹配次数越多。ACS集群匹配有kube-system.svc.cluster.localsvc.cluster.localcluster.local3个后缀,最多进行4次查询才能得到正确解析结果。

options

定义域名解析配置文件选项,支持多个KV值。例如该参数设置成ndots:5,说明如果访问的域名字符串内的点字符数量超过ndots值,则认为是完整域名,并被直接解析;如果不足ndots值,则追加search段后缀再进行查询。

根据上述Pod内的配置,集群会将域名请求(集群内部定义的服务或是集群外部域名)查询发往集群DNS服务器获取结果。

集群dnsPolicy配置和场景说明

ACS支持通过dnsPolicy字段为每个Pod配置不同的DNS策略。目前ACS集群支持以下三种策略:

  • ClusterFirst:通过CoreDNS来做域名解析,Pod内/etc/resolv.conf配置的DNS服务地址是集群DNS服务的kube-dns地址。该策略是集群工作负载的默认策略。

  • None:忽略集群DNS策略,需要您提供dnsConfig字段来指定DNS配置信息。

  • Default:Pod直接继承集群节点的域名解析配置。即在ACS集群直接使用ECS的/etc/resolv.conf文件(文件内配置的是阿里云DNS服务)。

针对上述三种策略,本文列举三种场景分别介绍如何配置dnsPolicy。

场景一:使用ACS集群提供的CoreDNS来做域名解析

针对这种场景,可使用dnsPolicy: ClusterFirst策略。示例配置如下:

apiVersion: v1
kind: Pod
metadata:
  name: alpine
  namespace: default
spec:
  containers:
  - image: alpine
    command:
      - sleep
      - "10000"
    imagePullPolicy: Always
    name: alpine
  dnsPolicy: ClusterFirst

场景二:Pod层面自定义DNS配置

当您需要给Deployment类型的工作负载指定DNS配置时,可使用dnsPolicy: None策略。示例配置如下:

apiVersion: v1
kind: Pod
metadata:
  name: alpine
  namespace: default
spec:
  containers:
  - image: alpine
    command:
      - sleep
      - "10000"
    imagePullPolicy: Always
    name: alpine
  dnsPolicy: None
  dnsConfig:
    nameservers: ["169.254.xx.xx"]
    searches:
    - default.svc.cluster.local
    - svc.cluster.local
    - cluster.local
    options:
    - name: ndots
      value: "2"

其中,dnsConfig中的参数说明如下:

参数

描述

nameservers

将用作Pod的DNS服务器的IP地址列表。最多可以指定3个IP地址。当Pod的dnsPolicy设置为None时,列表必须至少包含一个IP地址,否则此属性是可选的。列出的DNS的IP列表将合并到基于dnsPolicy生成的域名解析文件的nameserver字段中,并删除重复的地址。

searches

Pod中主机名查找的DNS搜索域列表。此属性是可选的。指定后,提供的列表将合并到从所选DNS策略生成的基本搜索域名中,并删除重复的域名。Kubernetes最多允许6个搜索域。

options

可选的对象列表,其中每个对象可以具有name属性(必需)和value属性(可选)。此属性中的内容将合并到从指定的DNS策略生成的选项中,并删除重复的条目。

场景三:采用阿里云ECS的DNS配置

当您的应用Pod不需要访问集群内的其他服务,只需要通过阿里云DNS来做解析,也不希望DNS解析经过CoreDNS,可以采用dnsPolicy: Default策略。示例配置如下:

apiVersion: v1
kind: Pod
metadata:
 name: alpine
 namespace: default
spec:
 containers:
 - image: alpine
 command:
 - sleep
 - "10000"
 imagePullPolicy: Always
 name: alpine
 dnsPolicy: Default

使用HostAliases配置容器Pod的/etc/hosts

当您希望在容器Pod内部解析某一域名到固定IP地址时,可以在CoreDNS启用hosts插件,具体操作,请参见CoreDNS的扩展配置

若您希望解析域名到固定IP地址仅生效在某个容器Pod内,您可以通过HostAliases字段修改容器Pod内/etc/hosts文件实现该操作。示例配置如下:

apiVersion: v1
kind: Pod
metadata:
  name: hostaliases-pod
spec:
  hostAliases:
  - ip: "127.0.**.**"
    hostnames:
    - "foo.local"
    - "bar.local"
  - ip: "10.1.**.**"
    hostnames:
    - "foo.remote"
  containers:
  - name: cat-hosts
    image: busybox:1.28
    command:
    - cat
    args:
    - "/etc/hosts"

当为Pod的spec字段中增加hostAliases字段后,Pod启动后/etc/hosts文件会被初始化成以下内容。

# Kubernetes-managed hosts file.
127.0.**.**	localhost
10.200.**.**	hostaliases-pod

# Entries added by HostAliases.
127.0.**.**	foo.local	bar.local
10.1.**.**	foo.remote	bar.remote

可以看到,foo.local、bar.local、foo.remote域名都已经绑定到固定IP。