Foreward
对于k8s的DNS理解还是有些模糊,这里梳理阅读相关文章后的理解.
- Using CoreDNS for Service Discovery
- 在 Kubernetes 中配置私有 DNS 和上游域名服务器
- DNS for Services and Pods
- Customizing DNS Service
Kubernetes提供的DNS服务
DNS是kubernetes内置的Pod服务.包含三个容器:
kubedns
监测kubernetes的master节点对Services和Endpoints的变化,并且保留在内存中,服务DNS查询.
dnsmasq
缓存DNS,提高查询效率.
sidecars
为dnsmasq和kubedns提供健康检查的端点.
Kube-DNS和CoreDNS
kubernetes提供了两种DNS服务
- kube-dns
- CoreDNS
从v1.11版本开始,CoreDNS已经是GA版本了,且已经作为Kubernetes的DNS服务.(CoreDNS已经作为CNCF的独立项目)
kube-dns是在1.9版本前使用.
在v1.11版本之后,(不建议)如果还想继续使用kube-dns,则在初始化集群是配置以下参数
1 | $ kubeadm init --feature-gates=CoreDNS=false |
配置kube-dns的存根域和上游DNS服务器
这里有两个概念:stub domains 和upstream nameservers.这里我翻译为存根域和上游DNS服务器.
- upstreamNameservers,会覆盖node节点上的/etc/resolv.conf文件,且最多配置三个upstream nameservers.
例子:
1 | apiVersion: v1 |
DNS请求如果后缀有acme.local
,则返回DNS Server的地址1.2.3.4.
Domain name | Server answering the query |
---|---|
kubernetes.default.svc.cluster.local | kube-dns |
foo.acme.local | custom DNS (1.2.3.4) |
widget.com | upstream DNS (one of 8.8.8.8, 8.8.4.4) |
Pod设置dnsPolicy对DNS查询的影响
当在pod中设置的dnsPolicy为default
和None
,则自定义的stub domain和upstream nameservers不会生效.
当dnsPolicy为ClusterFirst
后
未配置了存根域和upstream
如果咩有匹配的domain后缀,如
www.kubernetes.io
则去查找upstream nameserver.配置自定义存根域和upstream
首先查找kube-dns的DNS cache.
再查找自定义的stub domain,即图中的custom DNS.
最后查找upstream DNS.
配置CoreDNS的存根域和上游DNS服务器
CoreDNS提供链条插件式扩展,非常灵活.CoreDNS安装后默认包含了30个插件.CoreDNS的功能可以由一个或多个插件组成.只要会go语言,以及指导DNS工作原理就可以开发插件.
CoreDNS的配置文件Corefile.且语法规则如下:
1 | coredns.io { |
详细信息可浏览官网CoreDNS.
在v1.10版本后,kubeadm支持自动转换ConfigMap为Corefile.
Example:
kubedns使用以下配置.stubDomain存根域及upstream上游域.
1 | apiVersion: v1 |
等价的Corefile配置文件为:
- For federations:
1 | federation cluster.local { |
- For stubDomains:
1 | abc.com:53 { |
完整配置如下:DNS使用UDP协议,且端口为53
1 | .:53 { |
DNS中的记录生成规则
DNS包含A记录和SRV记录.A记录就是ip和域名的映射,SRV记录是端口映射.
Service
Service分为Headless和非Headless.(Headless Service:.spec.clusterIP
设置为None)
Service创建之后,默认会生成一条DNS映射的A记录,格式为:[.metadata.name].[namespace].svc.cluster.local
.
还会生成一条DNS映射的SRV(端口)记录,格式为:_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster.local
.
对非Headless的Service,端口的DNS映射就是:[.metadata.name].[namespace].svc.cluster.local
.
对于Headless的Service,目前还不是特别明白.暂且先将原文描述贴下来.For a headless service, this resolves to multiple answers, one for each pod that is backing the service, and contains the port number and the domain name of the pod of the form auto-generated-name.my-svc.my-namespace.svc.cluster.local
.
Pod
创建Pod会生成一条DNS的A记录:pod-ip-address.my-namespace.pod.cluster.local
.
在集群中查找Pod,可以通过这种格式[.metadata.name].[.spec.subdomain].[namespace].svc.cluster.local
查找.
Pod的DNS规则
设置字段:.spec.dsnPolicy
.有四种规则:
Default
虽然名字是Default,但是不是默认规则.
The Pod inherits the name resolution configuration from the node that the pods run on
ClusterFirst
集群规则优先,如果没有查询到,则去上游域名服务器查询.集群DNS服务和上游DNS服务都可以配置.
ClusterFirstWithHostNet
For Pods running with hostNetwork, you should explicitly set its DNS policy
None
忽略在kubernetes环境DNS配置,并使用自定义的DNS配置.
.spec.dsnConfig
如何手动设置Pod中的DNS解析配置
需要在集群中开启功能支持,--feature-gates=CustomPodDNS=true
.
例如:
1 | apiVersion: v1 |
运行后,会在Pod中的/etc/resolv.conf文件中生成以下内容:
1 | nameserver 1.2.3.4 |