K8s DNS

K8s DNS #


DNS 策略 #

  • Default
    • The Pod inherits the name resolution configuration from the node that the pods run on
  • ClusterFirst
    • Any DNS query that does not match the configured cluster domain suffix, such as “www.kubernetes.io”, is forwarded to the upstream nameserver inherited from the node.
  • ClusterFirstWithHostNet
    • For Pods running with hostNetwork, you should explicitly set its DNS policy “ClusterFirstWithHostNet”
  • None
    • It allows a Pod to ignore DNS settings from the Kubernetes environment.
    • All DNS settings are supposed to be provided using the dnsConfig field in the Pod Spec.
“`Default`” is not the default DNS policy. If dnsPolicy is not explicitly specified, then “`ClusterFirst`” is used.

参考:


k8s 中域名是如何被解析的 #

在 k8s 中,一个 Pod 如果要访问相同 Namespace 下的 Service(比如 user-svc),那么只需要 curl user-svc。 如果 Pod 和 Service 不在同一域名下,那么就需要在 Service Name 之后添加上 Service 所在的 Namespace(比如 beta),curl user-svc.beta。 那么 k8s 是如何知道这些域名是内部域名并为他们做解析的呢?

无论是在 宿主机 或者是在 k8s 集群中,DNS 解析会依赖这个三个文件

  • /etc/host.conf
  • /etc/hosts
  • /etc/resolv.conf

/etc/resolv.conf #

resolv.conf 是 Pod 在 dnsPolicy: ClusterFirst 的情况下,k8s 为其自动生成的。 在该 Pod 内请求的所有的域名解析都需要经过 DNS Service 进行解析,不管是集群内部域名还是外部域名。

每行都会以一个关键字开头,然后跟配置参数。

在集群中主要使用到的关键词有 3 个

  • nameserver 定义 DNS 服务器的 IP 地址(Kube-DNS 的 Service IP)
  • search 定义域名的搜索列表,当查询的域名中包含的 . 的数量少于 options.ndots 的值时,会依次匹配列表中的每个值
  • options 定义域名查找时的配置信息

nameserver、search 和 options 都是可以通过 dnsConfig 字段进行配置的,详细参考官方文档

例如

nameserver 10.250.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

nameserver #

nameserver 所对应的地址正是 DNS Service 的 Cluster IP(该值在启动 kubelet 的时候,通过 clusterDNS 指定)。

search 域 #

search 域默认包含了 namespace.svc.cluster.localsvc.cluster.localcluster.local 三种。

当我们在 Pod 中访问 a Service 时( curl a ),会选择 nameserver 10.250.0.10 进行解析,然后依次带入 search 域进行 DNS 查找,直到找到为止。

$ curl a
a.default.svc.cluster.local

显然因为 Pod 和 a Service 在同一 Namespace 下,所以第一次 lookup 就能找到。

如果 Pod 要访问不同 Namespace(例如: beta )下的 Service b ( curl b.beta ),会经过两次 DNS 查找,分别是

$ curl b.beta
b.beta.default.svc.cluster.local # Not Found
b.beta.svc.cluster.local # Found

正是因为 search 的顺序性,所以访问同一 Namespace 下的 Service, curl a 是要比 curl a.default 的效率更高的,因为后者多经过了一次 DNS 解析。

$ curl a
a.default.svc.cluster.local # Found

$ curl a.default
b.default.default.svc.cluster.local # Not Found
b.default.svc.cluster.local # Found

options #

ndots #

ndots:5,表示:

  • 如果需要 lookup 的 Domain 中包含少于 5 个 . ,那么将会被当做非绝对域名,
  • 如果需要查询的 Domain 中包含大于或等于 5 个 . ,那么就会被当做绝对域名。

如果是绝对域名则不会走 search 域,

如果是非绝对域名,就会按照 search 域中进行逐一匹配查询, 如果 search 走完了都没有找到,那么就会使用原域名进行查找。

优化外网域名解析 #

在真正解析 http://iftech.io 之前,经历了

iftech.io.default.svc.cluster.local
-> iftech.io.svc.cluster.local
-> iftech.io.cluster.local
-> iftech.io

这样也就意味着前 3 次 DNS 请求是浪费的,没有意义的。

直接使用绝对域名 #

这是最简单直接的优化方式,可以直接在要访问的域名后面加上 . 如:iftech.io. ,这样就可以避免走 search 域进行匹配。

配置 ndots #

比如配置 ndots:1iftech.io. 就会使用原域名进行查找。


CoreDNS vs KubeDNS #

在 kube-dns 中,一个 pod 内使用了数个容器:kubedns、dnsmasq 和 sidecar。

  • kubedns 容器监视 Kubernetes API 并基于 Kubernetes DNS 规范提供 DNS 记录,
  • dnsmasq 提供缓存和存根域支持,
  • sidecar 提供指标和健康检查。

此设置会导致一些问题随着时间的推移而出现。首先,dnsmasq 中的安全漏洞导致过去需要发布 Kubernetes 安全补丁。 此外,由于 dnsmasq 处理存根域,但 kubedns 处理 External Services,因此你无法在外部服务中使用存根域,这非常限制该功能(参阅 dns#131)。

在 CoreDNS 中,所有这些功能都在一个容器中完成 —— 该容器运行用 Go 编写的进程。 启用的不同插件来复制(并增强)kube-dns 中的功能。

为什么 pod 是 coredns,service 是 kube-dns? #

其实是 CoreDNS

CoreDNS is default from K8S 1.11. For previous installations it’s kube-dns.

image,其他都是 metadata,不重要

$ k describe pod coredns-6967fb4995-76trs -n kube-system | grep -i "image"

Image:         registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.3.1

问题详情

$ k cluster-info
Kubernetes master is running at https://192.168.99.102:8443
KubeDNS is running at https://192.168.99.102:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

$ k get po -n kube-system
NAME                               READY   STATUS    RESTARTS   AGE
coredns-6967fb4995-76trs           1/1     Running   6          32d
coredns-6967fb4995-grnzj           1/1     Running   6          32d
etcd-minikube                      1/1     Running   3          32d
kube-addon-manager-minikube        1/1     Running   3          32d
kube-apiserver-minikube            1/1     Running   3          32d
kube-controller-manager-minikube   1/1     Running   3          32d
kube-proxy-z765q                   1/1     Running   3          32d
kube-scheduler-minikube            1/1     Running   3          32d
storage-provisioner                1/1     Running   5          32d

$ k get svc -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   32d

$ k describe svc/kube-dns -n kube-system
Name:              kube-dns
Namespace:         kube-system
Labels:            k8s-app=kube-dns
                   kubernetes.io/cluster-service=true
                   kubernetes.io/name=KubeDNS
Annotations:       prometheus.io/port: 9153
                   prometheus.io/scrape: true
Selector:          k8s-app=kube-dns
Type:              ClusterIP
IP:                10.96.0.10
Port:              dns  53/UDP
TargetPort:        53/UDP
Endpoints:         172.17.0.2:53,172.17.0.3:53
Port:              dns-tcp  53/TCP
TargetPort:        53/TCP
Endpoints:         172.17.0.2:53,172.17.0.3:53
Port:              metrics  9153/TCP
TargetPort:        9153/TCP
Endpoints:         172.17.0.2:9153,172.17.0.3:9153
Session Affinity:  None
Events:            <none>

参考:


本文访问量

本站总访问量

本站总访客数