背景:最近公司有个需求,要在POD应用容器里面能够访问到一些外部域名,这些域名都在一台自建的DNS服务器上做了解析绑定。如果直接在Pod容器里的/etc/hosts文件中设置域名解析,或修改/etc/resolv.conf中的nameserver指向这台DNS服务器,这两种方式都不太方便管理,因为每次重新创建Pod或后续还有新Pod要创建时,都需要重新设置一遍,这时就需要有一个统一的地方设置域名解析,不需要到每个Pod里设置,这个地方就是coredns。
CoreDNS是一个DNS解析的组件,作为集群内的DNS服务器,为集群内部提供域名解析服务。比如当集群内Pod要访问某个service name时,就会用到coredns的解析服务。
DNS解析原理:
当部署好coredns后,集群中会有一个名为kube-dns的service,以及这个service下还有两个名为CoreDNS的Pod后端。
$ kubectl get svc kube-dns -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 172.17.0.10 <none> 53/UDP,53/TCP 471d
$ kubectl get deployment coredns -n kube-system
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
coredns 2 2 2 2 471d
当集群中的Pod,需要访问集群内的nginx服务,会经过以下两个步骤:
.------> Pod1(nginx1)
(2) /
.------------------> Service(nginx)---------> Pod2(nginx2)
|
Pod(Client)
|
'------------------> Service(kube-dns) ---------> Pod(coredns)
(1) UDP
(1)Pod Client要访问nginx服务时,会先请求本地DNS配置文件(/etc/resolv.conf)中指向的DNS服务器,然后DNS服务器再将nginx service解析后的IP返回给Pod。
(2)Pod Client获取到nginx服务的IP后,会再次直接向这个IP发起请求,请求最终会经过Nginx Service转发到后端POD容器上(nginx1和nginx2)。
Pod的DNS配置策略:
每个Pod所使用的DNS策略,是通过pod.spec.dnsPolicy字段设置的,共有4种DNS策略:
- ClusterFirst:默认策略,表示使用集群内部的CoreDNS来做域名解析,Pod内/etc/resolv.conf文件中配置的nameserver是集群的DNS服务器,即kube-dns的地址。
- Default:Pod直接继承集群node节点的域名解析配置,也就是,Pod会直接使用宿主机上的/etc/resolv.conf文件内容。
- None:忽略k8s集群环境中的DNS设置,Pod会使用其dnsConfig字段所提供的DNS配置,dnsConfig字段的内容要在创建Pod时手动设置好。
- ClusterFirstWithHostNet:如果Pod的host