你知道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.conf的 nameserver解析.
刚才我们介绍过,k8s里面有4种DNS策略, 而coredns使用的DNS策略就是Default, 这个策略的意思就是继承宿主机上的/etc/resolve.conf, 所以coredns Pod 里面的/etc/resolve.conf 的内容就是宿主机上的内容。
所以对于dnsPolicy 默认(也就是ClusterFirst)的情况下,Pod DNS的查询链路如下: