DNS概述
CoreDNS介绍
创建集群时会安装CoreDNS插件,CoreDNS是用来做集群内部域名解析。
在kube-system命名空间下可以查看到CoreDNS的Pod。
$ kubectl get po --namespace=kube-system NAME READY STATUS RESTARTS AGE coredns-7689f8bdf-295rk 1/1 Running 0 9m11s coredns-7689f8bdf-h7n68 1/1 Running 0 11m
CoreDNS安装成功后会成为DNS服务器,当创建Service后,CoreDNS会将Service的名称与IP记录起来,这样Pod就可以通过向CoreDNS查询Service的名称获得Service的IP地址。
访问时通过nginx.<namespace>.svc.cluster.local访问,其中nginx为Service的名称,<namespace>为命名空间名称,svc.cluster.local为域名后缀,在实际使用中,在同一个命名空间下可以省略<namespace>.svc.cluster.local,直接使用ServiceName即可。
使用ServiceName的方式有个主要的优点就是可以在开发应用程序时可以将ServiceName写在程序中,这样无需感知具体Service的IP地址。
CoreDNS插件安装后也有一个Service,在kube-system命名空间下,如下所示。
$ kubectl get svc -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE coredns ClusterIP 10.247.3.10 <none> 53/UDP,53/TCP,8080/TCP 13d
默认情况下,其他Pod创建后,会将coredns Service的地址作为域名解析服务器的地址写在Pod的 /etc/resolv.conf 文件中,创建一个Pod,查看/etc/resolv.conf文件,如下所示。
$ kubectl exec test01-6cbbf97b78-krj6h -it -- /bin/sh / # cat /etc/resolv.conf nameserver 10.247.3.10 search default.svc.cluster.local svc.cluster.local cluster.local options ndots:5 timeout single-request-reopen
在Pod中访问nginx Pod的ServiceName:Port,会先从CoreDNS中解析出nginx Service的IP地址,然后再访问nginx Service的IP地址,从而访问到nginx Pod。
Kubernetes中的域名解析逻辑
DNS策略可以在每个pod基础上进行设置,目前,Kubernetes支持Default、ClusterFirst、ClusterFirstWithHostNet和None四种DNS策略,具体请参见https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/。这些策略在pod-specific的dnsPolicy字段中指定。
- “Default”:如果dnsPolicy被设置为“Default”,则名称解析配置将从pod运行的节点继承。 自定义上游域名服务器和存根域不能够与这个策略一起使用。
- “ClusterFirst”:如果dnsPolicy被设置为“ClusterFirst”,任何与配置的集群域后缀不匹配的DNS查询(例如,www.kubernetes.io)将转发到从该节点继承的上游名称服务器。集群管理员可能配置了额外的存根域和上游DNS服务器。
- “ClusterFirstWithHostNet”:对于使用hostNetwork运行的Pod,您应该明确设置其DNS策略“ClusterFirstWithHostNet”。
- “None”:它允许Pod忽略Kubernetes环境中的DNS设置。应使用dnsConfigPod规范中的字段提供所有DNS设置 。
- Kubernetes 1.10及以上版本,支持Default、ClusterFirst、ClusterFirstWithHostNet和None四种策略;低于Kubernetes 1.10版本,仅支持default、ClusterFirst和ClusterFirstWithHostNet三种。
- “Default”不是默认的DNS策略。如果dnsPolicy的Flag没有特别指明,则默认使用“ClusterFirst”。
路由请求流程:
未配置存根域:没有匹配上配置的集群域名后缀的任何请求,例如 “www.kubernetes.io”,将会被转发到继承自节点的上游域名服务器。
已配置存根域:如果配置了存根域和上游DNS服务器,DNS查询将基于下面的流程对请求进行路由:
- 查询首先被发送到coredns中的DNS缓存层。
- 从缓存层,检查请求的后缀,并根据下面的情况转发到对应的DNS上:
- 具有集群后缀的名字(例如“.cluster.local”):请求被发送到coredns。
- 具有存根域后缀的名字(例如“.acme.local”):请求被发送到配置的自定义DNS解析器(例如:监听在 1.2.3.4)。
- 未能匹配上后缀的名字(例如“widget.com”):请求被转发到上游DNS。