CoreDns配置以及外部dns使用
CoreDNS ConfigMap选项
先来看看默认的CoreDns的配置文件
Corefile: |2-
.:53 {
errors
health
kubernetes cluster.local. in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
reload
loadbalance
}
Corefile 配置包括以下 CoreDNS 插件:
errors:错误记录到标准输出。
health:在 http://localhost:8080/health 处提供 CoreDNS 的健康报告。
ready:在端口 8181 上提供的一个 HTTP 末端,当所有能够 表达自身就绪的插件都已就绪时,在此末端返回 200 OK。
kubernetes:CoreDNS 将基于 Kubernetes 的服务和 Pod 的 IP 答复 DNS 查询。你可以在 CoreDNS 网站阅读更多细节。 你可以使用
ttl来定制响应的 TTL。默认值是 5 秒钟。TTL 的最小值可以是 0 秒钟, 最大值为 3600 秒。将 TTL 设置为 0 可以禁止对 DNS 记录进行缓存, 此行内的cluster.local处理custer.local区域中的所有查询(以及in-addr.arpa中的反向dns查找)pods insecure选项是为了与 kube-dns 向后兼容。你可以使用pods verified选项,该选项使得 仅在相同名称空间中存在具有匹配 IP 的 Pod 时才返回 A 记录。如果你不使用 Pod 记录,则可以使用pods disabled选项。prometheus:CoreDNS 的度量指标值以 Prometheus 格式在 http://localhost:9153/metrics 上提供。
forward: 不在 Kubernetes 集群域内的任何查询都将转发到 预定义的解析器 (/etc/resolv.conf).
解析外部域名 coredns 默认会请求上游 DNS 来查询,这里的上游 DNS 默认是 coredns pod 所在宿主机的 resolv.conf 里面的 nameserver (coredns pod 的 dnsPolicy 为 “Default”,也就是会将宿主机里的 resolv.conf 里的 nameserver 加到容器里的 resolv.conf, coredns 默认配置 proxy . /etc/resolv.conf, 意思是非 service 域名会使用 coredns 容器中 resolv.conf 文件里的 nameserver 来解析)
POD里面访问集群外的域名 走的是上游DNS服务器,也就是coredns所在的CVM节点DNS去做解析, 会先在coredns 的search域里面查找,查找不到走的是上游DNS服务器
外部域名请求的一个流程
路由请求流程
未配置存根域:没有匹配上配置的集群域名后缀的任何请求,例如 “www.kubernetes.io”,将会被转发到继承自节点的上游域名服务器。
已配置存根域:如果配置了存根域和上游DNS服务器,DNS查询将基于下面的流程对请求进行路由: \1. 查询首先被发送到coredns中的DNS缓存层。 \2. 从缓存层,检查请求的后缀,并根据下面的情况转发到对应的DNS上: - 具有集群后缀的名字(例如“.cluster.local”):请求被发送到coredns。 - 具有存根域后缀的名字(例如“.acme.local”):请求被发送到配置的自定义DNS解析器(例如:监听在 1.2.3.4)。 - 未能匹配上后缀的名字(例如“widget.com”):请求被转发到上游DNS。
上游DNS解析是 随机的策略
默认是随机策略

cache:启用前端缓存,需要指出的是,上文中的cache 30,表示 pttl 为30s,也就是说,一条域名解析记录在DNS缓存中的存留时间最长为30s。
loop:检测到简单的转发环,如果发现死循环,则中止 CoreDNS 进程。
reload:允许自动重新加载已更改的 Corefile。 编辑 ConfigMap 配置后,请等待两分钟,以使更改生效。
loadbalance:这是一个轮转式 DNS 负载均衡器, 它在应答中随机分配 A、AAAA 和 MX 记录的顺序。
CoreDNS内置的两个健康检查插件
health和ready的使用方式和适用场景 :https://tinychen.com/20220728-dns-11-coredns-08-healthcheck/路由请求流程
未配置存根域:没有匹配上配置的集群域名后缀的任何请求,例如 “www.kubernetes.io”,将会被转发到继承自节点的上游域名服务器。
已配置存根域:如果配置了存根域和上游DNS服务器,DNS查询将基于下面的流程对请求进行路由:
查询首先被发送到coredns中的DNS缓存层。
从缓存层,检查请求的后缀,并根据下面的情况转发到对应的DNS上:
具有集群后缀的名字(例如“.cluster.local”):请求被发送到coredns。
具有存根域后缀的名字(例如“.acme.local”):请求被发送到配置的自定义DNS解析器(例如:监听在 1.2.3.4)。
- 未能匹配上后缀的名字(例如“widget.com”):请求被转发到上游DNS。
DNS域名解析原理
节点kubelet的启动参数有--cluster-dns=<dns-service-ip>、--cluster-domain=<default-local-domain>,这两个参数分别被用来设置集群DNS服务器的IP地址和主域名后缀。
Pod内的DNS域名解析配置文件为/etc/resolv.conf,文件内容如下。
earch default.svc.cluster.local svc.cluster.local cluster.local
nameserver 172.18.254.219
options ndots:5
search:设置域名的查找后缀规则,查找配置越多,说明域名解析查找匹配次数越多,集群匹配有default.svc.cluster.local、svc.cluster.local、cluster.local3个后缀,最多进行8次查询才能得到正确解析结果,因为集群里面进行IPV4和IPV6查询各四次
nameserver:定义DNS服务器的IP地址
options:定义域名解析配置文件选项,支持多个KV值。例如该参数设置成ndots:5,说明如果访问的域名字符串内的点字符数量超过ndots值,则认为是完整域名,并被直接解析;如果不足ndots值,则追加search段后缀再进行查询
集群dnsPolicy配置
Kubernetes持通过dnsPolicy字段为每个Pod配置不同的DNS策略。目前支持四种策略:
- ClusterFirst:通过CoreDNS来做域名解析,Pod内/etc/resolv.conf配置的DNS服务地址是集群DNS服务的kube-dns地址。该策略是集群工作负载的默认策略。
- None:忽略集群DNS策略,需要您提供dnsConfig字段来指定DNS配置信息。
- Default:Pod直接继承集群节点的域名解析配置。即在ACK集群直接使用ECS的/etc/resolv.conf文件(文件内配置的是阿里云DNS服务)。
- ClusterFirstWithHostNet:强制在hostNetWork网络模式下使用ClusterFirst策略(默认使用Default策略)
Pod层面自定义DNS配置
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"
集群CoreDNS扩展配置
场景一:开启日志服务
如果需将CoreDNS每次域名解析的日志打印出来,您可以开启log插件,在Corefile里加上log。示例配置如下:
Corefile: |2-
.:53 {
errors
log
health
kubernetes cluster.local. in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
reload
loadbalance
}
场景二:配置外部上游dns服务器
有些服务不在kubernetes内部,在内部环境内需要通过dns去访问,名称后缀为carey.com ,强制所有非集群 DNS 查找通过特定的域名服务器(位于10.150.0.1),将 proxy 和 forward 指向域名服务器,而不是 /etc/resolv.conf。
carey.com:53 {
errors
cache 30
forward . 10.150.0.1
}
要显式强制所有非集群 DNS 查找通过特定的域名服务器(位于 172.16.0.1),可将 forward 指向该域名服务器,而不是 /etc/resolv.conf。
完整的配置文件
Corefile: |2-
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
domain-name:53 {
errors
cache 30
forward . custom-dns-server
reload #前面的域要加上reload
}
carey.com:53 {
errors
cache 30
forward . 10.150.0.1
}
场景三:通过coredns实现内外流量分离
- 场景 旧业务固定了域名,无法通过内部service直接访问服务 需要实现内部流量和外部流量自动拆分
- 实现 通过coredns的rewrite功能实现以上能力,如以下内部访问tenant.msa.chinamcloud.com域名时,会将流量转发到 tenantapi.yunjiao.svc.cluster.local域名,实现内外域名访问一致。 部分版本nginx配置时候可能遇见无法访问的情况
apiVersion: v1
data:
Corefile: |2-
.:53 {
errors
health
rewrite name tenant.msa.chinamcloud.com tenantapi.yunjiao.svc.cluster.local
rewrite name console.msa.chinamcloud.com console.yunjiao.svc.cluster.local
rewrite name user.msa.chinamcloud.com userapi.yunjiao.svc.cluster.local
rewrite name lims.msa.chinamcloud.com lims.yunjiao.svc.cluster.local
rewrite name labapp.msa.chinamcloud.com limsapp.yunjiao.svc.cluster.local
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
场景四:coredns的hosts特性声明
hosts :字段部分指明了三个域名的解析地址 , hosts是 CoreDNS 的一个 plugin,这一节的意思是加载 /etc/hosts文件里面的解析信息。hosts 在最前面,则如果一个域名在 hosts 文件中存在,则优先使用这个信息返回;
fallthrough :如果 hosts 中找不到,则进入下一个 plugin 继续。缺少这一个指令,后面的 plugins 配置就无意义了;
注意 请配置fallthrough,否则会造成非定制hosts域名解析失败。
apiVersion: v1
data:
Corefile: |
.:53 {
errors
health
hosts {
100.64.139.66 minio.chinamcloud.com
100.64.139.66 registry.chinamcloud.com
100.64.139.66 gitlab.chinamcloud.com
fallthrough
}
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
场景五:外部域名完全使用自建DNS服务器
如果您需要使用的自建DNS服务的域名没有统一的域名后缀,您可以选择所有集群外部域名走自建DNS服务器,例如,您自建的DNS服务器IP为10.10.0.10和10.10.0.20,可以更改forward参数进行配置。示例配置如下
Corefile: |2-
.:53 {
errors
health
kubernetes cluster.local. in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . 10.10.0.10 10.10.0.20 ######
cache 30
reload
loadbalance
}
场景六:集群外部访问集群内服务
如果您希望运行在集群节点上的进程能够访问到集群内的服务,虽然可以通过将节点的/etc/resolv.conf文件内nameserver配置为集群kube-dns的ClusterIP地址来达到目的,但不推荐您直接更改节点的/etc/resolv.conf文件的方式来达到任何目的
场景七:禁止CoreDNS对IPv6类型的AAAA记录查询返回
当业务容器不需要AAAA记录类型时,可以在CoreDNS中将AAAA记录类型拦截,返回域名不存在,以减少不必要的网络通信。示例配置如下:
Corefile: |
.:53 {
errors
health {
lameduck 15s
}
#新增以下一行Template插件,其它数据请保持不变。
template IN AAAA .
}
场景八:local dns配置外部域名
- 修改kube-system下的local dns 的configmap
kubectl edit cm node-local-dns -nkube-system
- 增加11行:
tencentyun.com:53 {
errors
cache 30
reload
loop
bind 169.254.20.10 COREDNS_CLUSTER_IP
forward . __PILLAR__CLUSTER__DNS__ {
force_tcp
}
prometheus :9253
}
ipvs在使用node-local-dns-dnscache缺陷导致访问链路异常 规避措施:
- node-local-dns 不要绑定 kube-dns service IP
- kubelet 增加命令行参数 --cluster-dns=169.254.20.10
参考文档:https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#coredns
https://github.com/coredns/coredns/blob/master/plugin/kubernetes/README.md
https://kubernetes.io/zh/docs/tasks/administer-cluster/dns-custom-nameservers/
Coredns+Nodelocaldns cache解决Coredns域名解析延迟
https://blog.51cto.com/u_14143894/2515451
CoreDNS 详情