摘要:kubernetes service 的底层模型是endpoints服务端点。有了它,底层的ipvs才能够进行运行并且关联。
kubernetes service 的底层模型是endpoints服务端点。有了它,底层的ipvs才能够进行运行并且关联。
kubernetes中的service,它定义了一组Pod的逻辑集合和一个用于访问它们的策略。一个service的目标pod集合通常是由label selector来决定的。
endpoints是一组实际服务的端点集合。一个endpoint是一个可访问的服务端点,即一个状态为running的pod的访问端点。一般pod都不是独立的存在,所以一组pod的端点合在一起称为endpoints。只有被service selector匹配选中并且状态为running的pod,才会被加入到和service同名的endpoints中。
查看endpoints的名称:
kubectl api-resources | grep -i endpoints
可以看到endpoints服务端点的缩写是ep。
endpoint是service和pod之间的关联,服务模型中,上层是服务名称,然后这个service的标签选择器label selector去匹配标签。最底层会有多个后端的pod,并且每个后端的pod都有标签,这样的pod都会被service的标签所匹配到。当匹配完成以后,会出现一个endpoints的同名对象。这个同名对象是自动被创建的,这个对象需要被保存的信息就是我们当前service的标签选择器匹配到的pod,它的IP地址和端口,我们叫端点。这就是当前endpoints service和pod之间的关联。
对于我们当前的endpoints的对象来说,并不是就一种分类,而是有两种分类:
①:自动关联体系:配置selector,这个是默认的类型。
②:手动关联体系:无配置selector
自动关联体系就是定义了service,它就会自动创建一个endpoints,这种叫做自动关联体系。
手动关联体系就是创建了service, 它并没有创建端点对象,而是需要手动完成端点对象的书写。
出现这种偏差,主要在于当前的service是不是去定义了pod的标签选择器。
①:自动关联体系:也就是它配置了label selector。kubernetes内部通过service发起请求,然后请求会被导向到对应分配的pod,分配的逻辑原理是基于ipvs,基于ipvs的rr算法nat模式,这是当前ipvs的一个特性,或者是分配的一个特性。这个ipvs能够创建成功,当service被定义了一个标签选择器以后,标签选择器会动态地监测当前符合需求的pod,并且将这些pod的IP抓取到一个新的资源对象,也就是这个endpoints对象里,这个对象名会跟service的名字是同名的。kubelet只需要将当前的endpoints维护到当前所在节点的 ipvs规则里即可。这是分成两步的,当我们创建了service以后,service去匹配符合的pod,将pod的信息抓取到另外一个endpoints对象里。service要维护的是endpoints对象,它的动态性或者合理性是:必须要是现在满足要求的最新的pod地址列表或者端点。然后每个节点的kubelet再去把端点信息同步到自己节点的ipvs规则里面去,这样就完成了对应的同步。
②:手动关联体系:就是没有配置selector。kubernetes集群内部的应用通过service发起请求,service最终通过ipvs将请求分散到后端的服务。这个服务可以是pod,也可以是kubernetes集群以外的,也可以是kubernetes集群以内的服务,只要它的地址能够连通就行,需要管理员手动创建一个同名的endpoints对象去维护端点的地址,在endpoints中配置外部服务的访问地址,然后让每个节点kubelet去同步到ipvs的规则列表里面。这种管理员手动创建的操作,具有灵活性。
service和endpoints之间的关联,分成两种:
1.自动关联体系:定义了标签选择器。
它会自动创建一个同名的endpoints资源对象。这个资源对象内部主要存在的、存储的是符合要求的pod端点信息,比如IP和端口信息。
①:标签的子集运算
②:pod是就绪状态
这就是匹配对象,也是限制了它只能基于这样的方式去存在我们的访问。
2.手动关联体系:没有定义标签选择器,也不会创建同名的endpoints资源对象,需要管理员手动创建。
它的匹配对象是管理员手动填写的地址信息,或者称作端点信息。这个端点信息,只要是我们当前的pod或者需要去访问这个service,本身目标能够触达的地址段或者地址空间都是没问题的。
它的灵活性非常强。
~~~我是华丽的分隔线~~~
kubernetes进入容器:
service的资源清单文件中有选择器,属于自动关联体系,就意味着当前的service创建完成以后它会自动出现一个同名的endpoints。
使用资源清单创建service:
kubectl create -f service-xxx.yaml
查看endpoints:
kubectl get endpoints -n $nanespace_name
自动关联体系创建出服务后,会出现一个相同名称的endpoints对象,并且它的端点信息已经记录到endpoints对象。
查看端点信息中对应的pod:
kubectl get pod -n $namespace_name -o wide
Pod是就绪状态,它就会被添加到端点对象中去。
Pod是就绪状态,端点对象中的端点信息会自动更新。
手动关联体系:
基于无selector资源清单文件创建endpoints:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
ports:
- protocol: TCP
port: 6666
targetPort: 80
---
apiVersion: v1
kind: Endpoints
metadata:
name: nginx
namespace: default
subnets:
- addresses:
- ip: x.x.x.x(物理节点ip)
ports:
- port: 80
基于资源清单文件创建service:
kubectl create -f service-xxx.yaml
验证创建的无selector标签选择器的服务:
kubectl get svc -n $namespace_name
接下来创建一个与服务service同名的endpoints:
kubectl create -f endpoints-xxx.yaml
没有标签选择器,所以它的背后不会自动创建一个端点值。
查看服务端点:
kunectl get endpoints -n $namespace_name
必须有标签选择器,service才会创建服务端点。如果没有标签选择器,必须手动创建。否则负载均衡集群后端没有真实服务器。
查看ipvs规则:
ipvsadm -Ln
查看到服务端口是6666的规则下,没有服务端点。
必须手动创建资源对象:
如果endpoints需要跟踪多个IP地址(多个pod、容器或者域名),可以在:
-addresses:
-ip: x.x.x.x
-ip: x.x.x.x
进行指定多个IP地址。
再次执行ipvsadm命令进行查看:
ipvsadm -Ln
可以查看到服务端点值被写入到ipvs负载均衡规则里。
docker run --name nginx -p 80:80 -d $image_url/nginx:$tag
这时候再对service进行访问,可以访问到。
相当于使用docker run命令创建出来了这个service后端的真实服务器或者服务端点。
这个后端的真实服务器或者叫服务端点是由我们自己去控制的。
如果通过kubernetes官方标准的有标签选择器的服务,是不能将这种nginx的真实服务器添加到负载均衡的调度队列里面的。但是自己自定义添加无标签选择器的端点值,是可以完成添加操作的,这就是无标签选择器label selector手动关联体系灵活性的体现。
service跟pod之间的关联是endpoints服务端点,分成两种类型:
①:有标签选择器的自动关联体系。
②:无标签选择器的手动关联体系。
一叶成鸣,大业成名
鼓励的话语:忍耐并不是软弱的表现,而是一种智慧和力量的体现。在面对困境和屈辱时只有选择忍耐才能够保存实力、积蓄力量最终实现自己的梦想和追求。屡战屡败,屡败屡战。败而复起,厚积薄发!
来源:澳辉侃科技