k8s DNS的研究与实践
背景
一直对于k8s的dns机制不甚了解, 借此机会彻底搞懂.
主要参照文章 KubeDNS 和 CoreDNS 进行个人消化.
总结
容器内部DNS配置
明白了容器内部/etc/resolv.conf
的含义:
$ cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 192.168.0.10
options ndots:5
本质上会:
- 根据传入的域名
- 当查询的域名中包含的 . 的数量少于 options.ndots 的值时,会依次拼接search列表中的每个值
- 逐个尝试拼接后缀
- 向nameserver发送解析请求
- 如果 search 走完了都没有找到, 那么就会使用原域名进行查找
例如
- 同个namesapce下:
-- 在host上执行, 看到有如下svc
[root@iZ2ze8h8q419hf1fze66dkZ ~]$ k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service ClusterIP 192.168.198.117 <none> 80/TCP 19d
-- 登录default namespace上某个pod内部执行如下命令,
-- 1. 直接通过clusterIP访问, 则不经过DNS, 可以访问通
$ curl 192.168.198.117:80
<!DOCTYPE html>
<html>
</html>
-- 2. 通过svc name访问, 则经过DNS, 可以访问通, 底层其实经过一次拼接, 完整域名是: nginx-service.default.svc.cluster.local
$ curl nginx-service:80
<!DOCTYPE html>
<html>
</html>
-- 3. 通过svc 完整访问, 则经过DNS, 可以访问通, 底层不经过拼接, 完整域名是: nginx-service.default.svc.cluster.local
$ curl nginx-service.default.svc.cluster.local:80
- 跨namesapce:
-- 在host上执行, 查看 kube-system namespace下的svc
[root@iZ2ze8h8q419hf1fze66dkZ ~]$ k get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
heapster ClusterIP 192.168.32.77 <none> 80/TCP 272d
-- 登录default namespace上某个pod内部执行如下命令,
-- 1. 直接通过clusterIP访问, 则不经过DNS, 可以访问通
$ curl 192.168.32.77:80
404 page not found
-- 2. 通过svc不带namespace的name访问, 则经过DNS, 访问不通, 底层其实经过一次拼接, 完整域名是: heapster.default.svc.cluster.local 访问不通
$ curl heapster:80
curl: (6) Could not resolve host: heapster
-- 3. 通过svc带namespace的name访问, 则经过DNS, 访问通, 底层其实经过2次拼接, heapster.kube-system.default.svc.cluster.local 访问不通, heapster.kube-system.svc.cluster.local 访问通了
$ curl heapster.kube-system:80
404 page not found
-- 4. 通过svc带namespace的完整域名访问, 则经过DNS, 访问通, 底层不经过拼接
$ curl heapster.kube-system.svc.cluster.local:80
404 page not found
容器内部DNS配置的生成
容器内部/etc/resolv.conf
:
$ cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 192.168.0.10
options ndots:5
nameserver 192.168.0.10
记录是如何生成的?- 本质上
192.168.0.10
是dnssvc的clusterIp:
[root@iZ2ze8h8q419hf1fze66dkZ ~]$ k get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 192.168.0.10 <none> 53/UDP,53/TCP,9153/TCP 272d
nameserver 192.168.0.10
记录是何时生成的?- 是在创建pod时, 由kubelet注入pod内部
// TODO: 是如何注入pod内部的?
// TODO: pod内部访问公网, 是如何实现的? 如何禁止pod内部访问公网?