# 参考:
详解k8s 4 种类型 Service_51CTO博客_k8s service类型 // 图画的不错
# 功能:
service:略
endpoint:记录service对应的pod的相关信息(主要是pod_ip)
其实endpoint和service并没有本质的区别,service和endpoint都只是数据库中的一条数据。
# service分类:cluster_ip,node_port,headless_service,load_balance,external_name
# cluster_ip: 会分配一个service_ip。网络请求时,先从dns上获取的ip是 service_ip,然后通过本机iptable 转到pod_ip
# headless_service 与普通service相比,少了一个service_ip,网络请求时,直接从dns上获取pod_ip。
# node_port: 在普通service的基础上,再分配一个node_port。集群外可以直接请求主机ip_port,然后转发到pod_ip
# load_balance 用户实现集群外对集群内的访问。load_balance是在node_port上加了一个负载均衡的属性。相应的控制器发现这个属性之后
会创建一个负载均衡器。当请求负载均衡器时,会将流量转到node_port,然后通过node_port转到pod_ip
# external_name 将集群外的地址映射到dns。用户集群内的pod访问集群外的服务
补充: external_name引入外部服务时只能通过域名的方式引入,但是很多情况下,外部服务没有域名,只是简单的ip_port
业界常用的做法是手动创建一个没有selector的service,由于没有selector,controller-manager不会给这个service创建
endpoint。于是需要手动创建一个和service同名的endpoint,在endpoint中手动填写外部服务的ip_port。这样就实现了
service和endpoint的手动绑定。endpoint中引入的ip_port就会被添加到dns,于是就可以实现集群内到外部服务的访问。
# endpoint的使用方式:
方式1:通过service创建endpoint
方式2:手动直接创建endpoint,同时需要创建同名service并且selector为空,可以用来引用集群外的ip,当然也可以引用集群内的ip
# annotation:service.alpha.kubernetes.io/tolerate-unready-endpoints
可以容忍没有ready状态的pod,也就是说如果pod没有就绪,只要pod有ip,那么ip就会被保存在endpoints
在新版本中,这个annotation已经不建议使用,但是依然能够生效。新版本中,可以通过spec.PublishNotReadyAddresses实现。
# spec.PublishNotReadyAddresses
功能同上:annotation:service.alpha.kubernetes.io/tolerate-unready-endpoints
# 问:从代码的角度来开,endpoint有什么用?
答:dns会使用endpoint。endpoint记录了域名和ip之间的关系,dns通过监控endpoint,将这种关系同步到dns
# 问:无头service是啥,是为了解决什么问题?
答:如果spec.clusterIp = None,则service就是一个headless服务,无头服务对应的ip也是pod_ip,不是外网ip,无头service和正常的service代理的都是集群内的pod。无头service只是把代理的ip从iptable转到了dns。
正常的service都有一个service_ip,然后通过service_ip自动转到pod_ip,但是有时候用户想直接请求pod_ip。例如k8s中部署了一个3个节点的etcd服务,这个etcd需要自己实现选举功能。那么在选举的过程中就需要直接请求另外两个pod_ip。
# 为什么无头service可以没有端口,会发生什么;为什么其他service需要端口?
// 无头服务可以没有端口,也只有无头服务可以没有端口,这个结论是从代码上得到的,不知道会发生什么 -> len( service.spec.ports ) == 0
# 问:无头service的pod_ip是固定的的吗?
答:自己好好想想,怎么可能是固定的ip。例如一个deployment有3个副本,配置了一个无头service,pod每次重启name都会发生变化,根本就不可能固定。
所以pod_ip是否固定和无头service没有关系。
# 问:statefulset和无头service有什么关系
答:从controller-manager的代码上看,他们俩并没有什么关系,statefulset的在生成pod的name时,也没有用到无头service
但是statefulset明确要用无头service,不知道为啥。
# 问:无头service怎么访问?
答:无头service只是去掉了service ip,然后将pod_ip放到了dns,但是域名依然不变(域名就是他的name),所以直接请求无头service的name就可以了
dns会自动解析成pod_ip
# 问:无头service能实现负载均衡吗?
答:不知道。但是从理论上来说,无头service的网络通信原理就是dns,如果dns能实现负载均衡,那么无头service就能实现负载均衡。
# 问:pod的ip是endpoint生成的吗?
答:pod ip的分配和endpoint没有半毛钱的关系,endpoint就是数据库中的一条记录。endpoint controller通过informer来收集pod ip,然后将pod ip写
入到endpoint。
# 问:如果手动创建一个endpoint,这个endpoint的name是随便取的,不创建他的同名service,会发生什么?
答:不知道。不知道dns是否是直接监控endpoint来更新dns,还是通过监控service再去找endpoint。
如果直接监控endpoint,那么就会在dns保存这个手动创建的endpoint的信息
如果是通过service,那么集群中只是多了一条脏数据,其他的什么也不会发生。
有机会可以测试一下。