K8S中 域名的解析过程

1,966 阅读2分钟

你知道k8sPod中是如何解析域名的吗? 如果解析的域名不在集群内,又是如何被转发到集群外部的?

首先,要访问一个域名,比如说ping www.baidu.com, glibc 都会查询 /etc/resolve.conf 这个文件,向文件中的nameserver 请求,来解析域名.

那么,容器中的/etc/resolve.conf 是怎么来的?这就涉及到 k8s 的 pod dnsPolicy,这个文件有4种不同的来源。

Pod 的 DNS 策略

DNS 策略可以逐个 Pod 来设定。当前k8s支持这4中DNS 策略

  • "Default": Pod 从运行所在的节点继承名称解析配置。
  • "ClusterFirst": 与配置的集群域后缀不匹配的任何 DNS 查询(例如 "www.kubernetes.io") 都将转发到从节点继承的上游名称服务器。集群管理员可能配置了额外的存根域和上游 DNS 服务器。
  • "ClusterFirstWithHostNet":对于以 hostNetwork 方式运行的 Pod,应显式设置其 DNS 策略 "ClusterFirstWithHostNet"。
  • "None": 此设置允许 Pod 忽略 Kubernetes 环境中的 DNS 设置。Pod 会使用其 dnsConfig 字段 所提供的 DNS 设置。

如果我们不填dnsPolicy, 默认策略就是ClusterFirst

这个策略什么意思呢? 我们创建一个Pod看看:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: dnsutils
  namespace: default
spec:
  containers:
  - name: dnsutils
    image: gcr.io/kubernetes-e2e-test-images/dnsutils:1.3
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always
EOF

查看Pod的/etc/resolv.conf, 它的nameserver 是指向coredns.

/ # cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

coredns 使用的Corefile 来配置DNS,我们来看看corefile

Corefile 文件

我看看coredns的配置文件

$kubectl get configmaps -n kube-system coredns -o yaml
apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
           lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2021-05-14T11:08:55Z"
  name: coredns
  namespace: kube-system
  resourceVersion: "5117475"
  selfLink: /api/v1/namespaces/kube-system/configmaps/coredns
  uid: 7ec941ca-12a8-49ff-8b66-f90244ed6d95

这段配置主要有两个地方来解析域名,

第一个地方:

        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }

这段配置的意思是cluster.local后缀的域名都是k8s内部的域名,coredns 会监控service的变化来修改域名的记录.

第二个地方:

        forward . /etc/resolv.conf

这段配置的意思是,如果coredns没有找到dns记录,则去找/etc/resolv.confnameserver解析.

刚才我们介绍过,k8s里面有4种DNS策略, 而coredns使用的DNS策略就是Default, 这个策略的意思就是继承宿主机上的/etc/resolve.conf, 所以coredns Pod 里面的/etc/resolve.conf 的内容就是宿主机上的内容。

所以对于dnsPolicy 默认(也就是ClusterFirst)的情况下,Pod DNS的查询链路如下:

image.png