kubernetes in action读书笔记之客户端与pod通信,pod与pod通信
Service
Service的作用
pod具有临时性,重启之后,ip就会变化,通过创建一个service,一个IP稳定不变的资源对象,可以实现访问一组pod的时候可以不用记录更新pod的ip,而只需要记住这组pod对应的service的ip即可(有DNS用DNS也行,后面再说),以此来实现一组pod能够提供稳定的外部入口。
大体的过程可以是:请求发送向一个service,kubernetes服务代理截获请求并随机挑选一个pod进行转发。(kubernetes也支持同一个客户端每次都转发向同一个pod,通过修改sessionAffinity为clusterIp即可实现)
集群内部的服务发现
问题来了,如果说service可以保持稳定不变的ip,当一个pod想访问另一个的pod的时候,如何知道对方的所属的service ip和端口是什么?本能的就会想到去API server查询,通过server_name查询对应的ip和port,这其实就和DNS功能一样了,Kubernetes在服务发现上提供了两种方式:
- 通过环境变量,让一个pod能够发现其他的service
- 通过DNS服务,类似kube-dns服务
第一种方式是在pod启动的时候,通过api server获取当前系统有哪些service,将service名称和对应的ip写入pod的环境变量中;
第二种就是DNS服务,每次pod创建的时候,会在pod内的/etc/resove.conf文件写入DNS的地址;两种方式都能找到service的ip,重点说一下DNS的请求过程,最简单的流程如下:
步骤:
- pod A请求service B
- 通过resolve.conf找到对应的集群内的DNS,转发给DNS
- DNS返回service B的ip
- 请求转发至service B
- 在service B随机分配到一个end point
- 请求转发到对应end point的pod上
以上,是一个集群内pod通过service请求集群内其他pod的过程,如果集群内的pod向请求集群外部的服务,应该如何实现?在一般场景下访问www.baidu.com,可以通过类似的两类方法:在外部服务有域名在DNS注册的情况下,可以在pod内访问外部服务的域名,如果没有域名,也可以写ip+端口来进问;在集群内部,还有另一种方法来实现集群外部服务访问:end point
end point也是一种kubernetes资源,从yaml的描述可以看出end point定义了一组pod ip和svc的关系,endpoint中的两个关键的字段:name代表所属哪一个service,subsets代表对应到哪些pod的ip;