Service是kubernetes最核心的概念,通过创建Service,可以为一组具有相同功能的POD(容器)应用提供统一的访问入口,并且将请求进行负载分发到后端的各个容器应用上。
在Kubernetes中,在受到RC调控的时候,Pod副本是变化的,比如发生迁移或者伸缩的时候。这对于Pod的访问者来说是不可接受的。
Kubernetes中的Service是一种抽象概念,它定义了一个Pod逻辑集合以及访问它们的策略,Service同Pod的关联同样是居于Label来完成的。Service的目标是提供一种桥梁, 它会为访问者提供一个固定访问地址,用于在访问时重定向到相应的后端,这使得非 Kubernetes原生应用程序,在无须为Kubemces编写特定代码的前提下,轻松访问后端。
Service同RC一样,都是通过Label来关联Pod的。当你在Service的yaml文件中定义了该Service的selector中的label为app:my-web,那么这个Service会将Pod–>metadata–>labeks中label为app:my-web的Pod作为分发请求的后端。
当Pod发生变化时(增加、减少、重建等),Service会及时更新。这样一来,Service就可以作为Pod的访问入口,起到代理服务器的作用,而对于访问者来说,通过Service进行访问,无需直接感知Pod。
Kubernetes分配给Service的固定IP是一个虚拟IP,并不是一个真实的IP,在外部是无法寻址的。在真实的系统实现上,Kubernetes是通过Kube-proxy组件来实现的虚拟IP路由及转发。所以在之前集群部署的环节上,我们在每个Node上均部署了Proxy这个组件,从而实现了Kubernetes层级的虚拟转发网络。
NodePort模式,Kubernetes将会在每个Node上打开一个端口并且每个Node的端口都是一样的,通过:NodePort的方式Kubernetes集群外部的程序可以访问Service。
NodePort每个 Node节点的端口有很多(0~65535),NodePort案例演练配置实战,如图所示,选择外部网络:
通过Node IP+31455端口访问,如图所示:
Nginx Service配置代码如下:
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "nginx",
"namespace": "default",
"selfLink": "/api/v1/namespaces/default/services/nginx",
"uid": "6a84483a-5262-11e8-8969-000c292f77da",
"resourceVersion": "613764",
"creationTimestamp": "2021-05-08T01:52:08Z",
"labels": {
"app": "nginx"
}
},
"spec": {
"ports": [
{
"name": "tcp-30080-80-p7s3q",
"protocol": "TCP",
"port": 30080,
"targetPort": 80,
"nodePort": 31455
}
],
"selector": {
"app": "nginx"
},
"clusterIP": "172.17.188.189",
"type": "LoadBalancer",
"sessionAffinity": "None"
},
"status": {
"loadBalancer": {}
}
}
LoadBlancer Service 是 kubernetes 深度结合云平台的一个组件;当使用 LoadBlancer Service 暴露服务时,实际上是通过向底层云平台申请创建一个负载均衡器来向外暴露服务。
目前 LoadBlancer Service 支持的云平台已经相对完善,比如国外的 GCE、DigitalOcean,国内的 阿里云,私有云 Openstack 等等,由于 LoadBlancer Service 深度结合了云平台,所以只能在一些云平台上来使用。
LoadBalancer会分配ClusterIP,分配NodePort,并且通过Cloud Provider来实现LB设备的配制,并且在LB设备中配置中,将:NodePort作为Pool Member,LB设备依据转发规则将流量转到节点的NodePort。
kubectl expose deployment nginxv1 --port=8081 --target-port=80 --type=LoadBalancer
LoadBalancer,在NodePort基础上,Kubernetes可以请求底层云平台创建一个负载均衡器,将每个Node作为后端,进行服务分发。 ClusterIP模式会提供一个集群内部的虚拟IP(与Pod不在同一网段),以供集群内部的pod之间通信使用。ClusterIP是Kubernetes service的默认类型;
为了实现上图的功能,需要以下几个组件的协同工作:
for I in etcd kube-apiserver kube-controller-manager kube-scheduler; do systemctl restart $I; systemctl enable $I; done
然后实战ClusterIP案例演练配置,如图所示:
基于Cluster IP访问80端口,首先要在各个NODE节点配置访问Cluster IP网段的路由,执行命令如下:
ip route add 172.17.188.0/24 dev docker0
#ip route del 172.17.188.0/24 dev docker0