kube-dns/coredns
kube-dns
主要参考:https://zhuanlan.zhihu.com/p/80141656
上面这篇可比官方那个不讲人话的文档要讲的清楚多了
https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/dns-debugging-resolution/
aliyunhttps://help.aliyun.com/document_detail/188179.html?utm_content=g_1000230851&spm=5176.20966629.toubu.3.f2991ddcpxxvD1#title-b7y-d6a-bcy
https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/?spm=a2c4g.11186623.0.0.23c66b886YeKE2
集群默认使用的是kube-dns
[root@master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-7f6cbbb7b8-hvpcg 1/1 Running 0 3d17h
coredns-7f6cbbb7b8-pphjt 1/1 Running 0 3d17h
etcd-master 1/1 Running 0 3d17h
kube-apiserver-master 1/1 Running 0 3d17h
kube-controller-manager-master 1/1 Running 1 (3d17h ago) 3d17h
kube-proxy-fjmj9 1/1 Running 0 3d17h
kube-proxy-ht5xt 1/1 Running 0 3d17h
kube-scheduler-master 1/1 Running 0 3d17h
[root@master ~]# kubectl 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 3d17h
我们可以看到的dns的地址,现在让我们随便进一个pod里面来查看一下
[root@master ~]# kubectl exec -it -n devops-tools jenkins-559d8cd85c-qg9zx -c jenkins -- bash
jenkins@jenkins-559d8cd85c-qg9zx:/$ cat /etc/resolv.conf
nameserver 10.96.0.10
search devops-tools.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
可以看到这个容器里面的域名解析地址指向了上面的kube-dns
上面的例子是dns策略为ClusterFirst时kube-dns会自动为pod生成的,当域名里面的点不超过options里面时,k8s会去在search里面一个个匹配
比如我找个a
那么他就会从a.devops-tools.svc.cluster.local一直找到a.cluster.local
让我们来康康官方是怎么讲的
"ClusterFirst": 与配置的集群域后缀不匹配的任何 DNS 查询(例如 "www.kubernetes.io") 都会由 DNS 服务器转发到上游名称服务器。集群管理员可能配置了额外的存根域和上游 DNS 服务器
嗯,确实是很有官方风格的叙(不)事(讲)方(人)式(话)
上面的例子是访问内部域名的,如果你想要访问一个外部域名,但是依旧还要经过几轮的search轮询的话,那未免有点浪费,避免这种情况的方式有两种,一种是直接访问绝对域名,如原本xxx.com 选择写成xxx.com.
另外一种是在dnsConfig里面修改option,大于等于一个点就不走search
几种dns模式的差别
ClusterFirstWithHostNet
当一个 Pod 以 HOST 模式(和宿主机共享网络,hostNetwork: true)启动时,这个 POD 中的所有容器都会使用宿主机的 /etc/resolv.conf 配置进行 DNS 查询,但是如果在 Pod 中仍然还想继续使用 k8s 集群 的 DNS 服务时,就需要将 dnsPolicy 设置为 ClusterFirstWithHostNet。
ClusterFirst
使用这种方式表示 Pod 内的 DNS 优先会使用 k8s 集群内的 DNS 服务,也就是会使用 kubedns 或者 coredns 进行域名解析。如果解析不成功,才会使用宿主机的 DNS 配置进行解析。
Default
这种方式,会让 kubelet 来决定 Pod 内的 DNS 使用哪种 DNS 策略。kubelet 的默认方式,其实就是使用宿主机的 /etc/resolv.conf 来进行解析。你可以通过设置 kubelet 的启动参数, --resolv-conf=/etc/resolv.conf 来决定该 DNS 服务使用的解析文件的地址
当我们部署集群 DNS 服务的时候,一般就需要将 dnsPolicy 设置成 Default,而并非使用默认值 ClusterFirst,否则该 DNS 服务的上游解析地址会变成它自身的 Service 的 ClusterIP(我解析我自己),导致域名无法解析
None
这种方式顾名思义,不会使用集群和宿主机的 DNS 策略。而是和 dnsConfig 配合一起使用,来自定义 DNS 配置,否则在提交修改时报错。
kube-dns的组成
- kubedns: 依赖 client-go 中的 informer 机制监视 k8s 中的 Service 和 Endpoint 的变化,并将它们转换为 skydns 能够理解的格式,以目录树的形式存在内存中,来服务内部 DNS 解析请求。skydns 是以 etcd 的标准作为后端存储的,所以为了兼容 etcd ,kubedns 在某些错误信息方面也都以 etcd 的格式进行定义的。因此 kubedns 的作用其实可以理解为为 skydns 提供存储。
- dnsmasq: 区分 Domain 是集群内部还是外部,给外部域名提供上游解析,内部域名发往 10053 端口,并将解析结果缓存,提高解析效率。
- sidecar: 对 kubedns 和 dnsmasq 进行健康检查和收集监控指标。
配置你的dns
自设dns
参考https://jimmysong.io/blog/configuring-kubernetes-kube-dns/
当你运行一个pod时,kubelet会将预先设定好的dns给你的pod布上,如果你想给他换个dns,那就需要另外的设置,使用 --resolv-conf来指定一个合法的文件,这个pod将以这个文件为标准来部署你的dns,而非使用默认的
/etc/resolv.conf来作为继承对象
这种方式只对clusterfirst有效,对default和none无效
通过为kube-system:kube-dns添加一个configmap来为pod添加存根域和上游域名解析(外部)
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-dns
namespace: kube-system
data:
stubDomains: |
{“acme.local”: [“1.2.3.4”]}
upstreamNameservers: |
[“8.8.8.8”, “8.8.4.4”]
none
apiVersion: v1
kind: Pod
metadata:
name: alpine
namespace: default
spec:
containers:
- image: alpine
command:
- sleep
- "10000"
imagePullPolicy: Always
name: alpine
dnsPolicy: None
dnsConfig:
nameservers: ["169.254.xx.xx"]
searches:
- default.svc.cluster.local
- svc.cluster.local
- cluster.local
options:
- name: ndots
value: "2"
参数 | 描述 |
---|---|
nameservers | 将用作Pod的DNS服务器的IP地址列表。最多可以指定3个IP地址。当Pod的dnsPolicy设置为None时,列表必须至少包含一个IP地址,否则此属性是可选的。列出的DNS的IP列表将合并到基于dnsPolicy生成的域名解析文件的nameserver字段中,并删除重复的地址。 |
searches | Pod中主机名查找的DNS搜索域列表。此属性是可选的。指定后,提供的列表将合并到从所选DNS策略生成的基本搜索域名中,并删除重复的域名。Kubernetes最多允许6个搜索域。 |
options | 可选的对象列表,其中每个对象可以具有name属性(必需)和value属性(可选)。此属性中的内容将合并到从指定的DNS策略生成的选项中,并删除重复的条目。 |
https://www.ichenfu.com/2018/12/20/k8s-pod-dns-policy/
apiVersion: v1
kind: Pod
metadata:
namespace: default
name: dns-example
spec:
containers:
- name: test
image: nginx
dnsPolicy: "None"
dnsConfig:
nameservers:
- 1.2.3.4
searches:
- ns1.svc.cluster.local
- my.dns.search.suffix
options:
- name: ndots
value: "2"
- name: edns0
default
不走coredns,直接走ecs的解析
apiVersion: v1
kind: Pod
metadata:
name: alpine
namespace: default
spec:
containers:
- image: alpine
command:
- sleep
- "10000"
imagePullPolicy: Always
name: alpine
dnsPolicy: Default