Kubernetes Service/Pod DNS 记录的添加时机

在这里插入图片描述

通过Service访问Pod

众所周知,我们给一些pod创建好Service之后,就可以通过service访问pod了。
在这里插入图片描述
从Kubernetes集群内通过service访问pod有两种办法:

  1. 通过Service的ClusterIP
    如上图所示,我们访问Service的ClusterIP时,请求会被路由到后端的Endpoint(Pod)上。
    因为种种原因,Service的ClusterIP是有可能变化的,这样一来,对调用方来说,就麻烦了。
    所以我们通常不会直接使用ClusterIP来访问一个服务。
  2. 通过Service的名字
    除了IP外,更常见的一种访问方式是通过Service的name,还是上面的例子,假设我们的namespace是default,那么在Kubernetes集群内可以这样访问:my_service.default.svc.cluster.local
    这其实是一个DNS域名,访问时被Kubernetes的DNS组件解析成了Service的ClusterIP。
    和普通DNS工作原理是一样的。
    这样一来,不管service的ClusterIP变不变,都不会影响调用方了。
    那么,问题来了:

这个DNS记录是怎么维护的?

肯定得有个DNS server来干这个活儿,在你的k8s上执行以下这个命令:

gaoyang@IT-C02XQ1HFJG5H standalone % kubectl get pod -A | grep dns
kube-system        coredns-6b9cfd868c-fjmz5                         1/1     Running   0          16d
kube-system        coredns-6b9cfd868c-x7wrx                         1/1     Running   0          16d

这个位于kube-system namespace内的叫做coredns的pod就是kubernetes内置的DNS server。
所有关于service和dns的事情都是他做的。

CoreDNS的工作原理示意图如下:
在这里插入图片描述

  1. 新建Kubernetes集群时,自动创建CoreDNS的pod(其实是个Deployment)和service
  2. CoreDNS建立到api server的长连接(websocket),监听集群中service的相关事件
  3. 用户创建pod时,kubernetes会自动在pod中把name server设置为CoreDNS的地址,例如下面的nameserver地址被设置成了22.10.0.10,
kubectl -n lemming exec -it standalone-0 -- cat /etc/resolv.conf
search lemming.svc.cluster.local svc.cluster.local cluster.local
nameserver 22.10.0.10
options ndots:5

这个22.10.0.10其实就是CoreDNS对应的service的地址

kubectl get svc -A | grep dns
kube-system        kube-dns                           ClusterIP      22.10.0.10   
  1. 用户创建service时
  2. kubernetes根据service的selector找到其对应的endpoint(pod),然后将这些信息写入到etcd中
  3. kubernetes将这个创建service的事件通知给CoreDNS
  4. CoreDNS从ETCD中得到service和endpoint相关的信息,并根据这些信息创建DNS记录
  5. 从集群内的pod中访问service时,pod会去找coredns把service的域名翻译成IP,然后剩下的就和直接通过ClusterIP访问没什么区别了

StatefulSet的DNS

现在让我们来来考虑一下StetefulSet的问题。
我们都知道,statefulset会为每一个pod创建一个固定的DNS记录(DNS解析后的IP是pod的IP,而不是service的ip)。但是StatefulSet的文档中明确要求我们先得自己创建一个headless类型的service,才能保证每个pod拥有一个dns记录。pod的dns域名长这样:my_pod.my_service.default.svc.cluster.local
这个结果其实是statefulset和headless service共同作用的结果:statefulset指定了pod的名字,headless service(其实真正干活的是coredns)给这个被指定了名字的pod创建了一个DNS记录。
当然,如果只有headless service,没有statefulset的情况下,pod也是会被创建一个DNS记录的,只不过记录的最前面pod名字的部分是一个随机的字符串。
所以关于上面的第6和第7步,其实是:
CoreDNS监听到service创建的事件后,会判断这是不是一个headless service,如果是的话,就从etcd中找到headless service对应的endpoint的ip,给每一个endpoint都创建一条记录。
因为headless service是没有ClusterIP的,所以直接请求headless service时,返回的其实是一个endpoint ip的列表。

更进一步,对于headless pod的DNS记录,CoreDNS并不是一监听到service创建的事件就会给每个endpoint创建一条DNS记录,如果我们的pod还没启动完,此时通过dns就能访问的话,就会出错了。
所以,CoreDNS真正给Endpoint创建DNS记录的时机是CoreDNS监听到Endpoint(pod)的状态变成ready时,才会创建。
而Pod的ready状态又是由Kubernetes的readiness probe 探针决定的。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值