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>

参考:


本文访问量

本站总访问量

本站总访客数