kubernetes的DNS理解

Foreward

对于k8s的DNS理解还是有些模糊,这里梳理阅读相关文章后的理解.

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
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-dns
namespace: kube-system
data:
stubDomains: |
{"acme.local": ["1.2.3.4"]}
upstreamNameservers: |
["8.8.8.8", "8.8.4.4"]

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为defaultNone,则自定义的stub domain和upstream nameservers不会生效.

当dnsPolicy为ClusterFirst

  • 未配置了存根域和upstream

    如果咩有匹配的domain后缀,如www.kubernetes.io则去查找upstream nameserver.

  • 配置自定义存根域和upstream

    首先查找kube-dns的DNS cache.

    再查找自定义的stub domain,即图中的custom DNS.

    最后查找upstream DNS.

    image-20180824174249533

配置CoreDNS的存根域和上游DNS服务器

CoreDNS提供链条插件式扩展,非常灵活.CoreDNS安装后默认包含了30个插件.CoreDNS的功能可以由一个或多个插件组成.只要会go语言,以及指导DNS工作原理就可以开发插件.

CoreDNS的配置文件Corefile.且语法规则如下:

1
2
3
4
5
6
7
8
coredns.io {
file coredns.io.signed {
transfer to * 185.49.140.62
}
prometheus
errors
log
}

详细信息可浏览官网CoreDNS.

在v1.10版本后,kubeadm支持自动转换ConfigMap为Corefile.

Example:

kubedns使用以下配置.stubDomain存根域及upstream上游域.

1
2
3
4
5
6
7
8
9
apiVersion: v1
data:
federations: |
{"foo" : "foo.feddomain.com"}
stubDomains: |
{"abc.com" : ["1.2.3.4"], "my.cluster.local" : ["2.3.4.5"]}
upstreamNameservers: |
["8.8.8.8", "8.8.4.4"]
kind: ConfigMap

等价的Corefile配置文件为:

  • For federations:
1
2
3
federation cluster.local {
foo foo.feddomain.com
}
  • For stubDomains:
1
2
3
4
5
6
7
8
9
10
abc.com:53 {
errors
cache 30
proxy . 1.2.3.4
}
my.cluster.local:53 {
errors
cache 30
proxy . 2.3.4.5
}

完整配置如下:DNS使用UDP协议,且端口为53

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
upstream 8.8.8.8 8.8.4.4
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
federation cluster.local {
foo foo.feddomain.com
}
prometheus :9153
proxy . 8.8.8.8 8.8.4.4
cache 30
}
abc.com:53 {
errors
cache 30
proxy . 1.2.3.4
}
my.cluster.local:53 {
errors
cache 30
proxy . 2.3.4.5
}

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: Pod
metadata:
namespace: default
name: dns-example
spec:
containers:
- name: test
image: nginx
dnsPolicy: "None"
dnsConfig:
nameservers:
- 1.2.3.4
searches:
- ns1.svc.cluster.local
- my.dns.search.suffix
options:
- name: ndots
value: "2"
- name: edns0

运行后,会在Pod中的/etc/resolv.conf文件中生成以下内容:

1
2
3
nameserver 1.2.3.4
search ns1.svc.cluster.local my.dns.search.suffix
options ndots:2 edns0

自定义DNS服务

坚持原创技术分享,您的支持将鼓励我继续创作!
Fork me on GitHub