一、service的基本操作
(一)创建service
命令创建
创建service的命令kubectl export暴露服务。怎么暴露呢。
格式:
kubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP|SCTP] [--target-port=number-or-name] ernal-ip=external-ip-of-service] [--type=type] [options]
(1)port是service的端口,target-port是容器的端口。
1)pod的端口是固定的,service的pod使用众所周知的端知名端口
2)如果没有指定的情况下(默认情况下),Service所需的端口号则从Pod中的containerPort复制而来
(2)name是service的名称。如果不指定的情况下,则默认和控制器的名称一样。
(3)type有clusterIp(只能集群内访问、默认)、nodeport(提供给集群外部访问)。
1)nodeport映射的端口在不指定的情况下,默认情况下,端口范围只能是 30000-32767
例子:
kubectl expose deployment nginx-deploy --name=serivce-nginx --port=80 --target-port=80 --type=NodePort
备注:
service的IP是动态生成的。通过kubectl get svc查看
配置文件定义Service
除了使用kubectl expose命令创建service,我们也可以通过配置文件定义service,再通过kubectl create命令进行创建。
(1)service资源清单文件
1)Service定义中的关键字段是ports和selector。
本例中ports定义部分指定了Service所需的虚拟端口号为8081,由于与Pod容器端口号8080不一样,所以需要再通过targetPort来指定后端Pod的端口号。
selector定义部分 设置的是后端Pod所拥有的label:app=webapp。
例如对于前面的webapp应用,我们可以设置一个service,代码如下:
2)service类型:
(二)修改service
kubectl edit deployment nginx-deploy
- 修改默认的clusterIP类型,修改为NodePort
如果修改为NodePort,需要加一个节点的映射端口选项nodePort:端口范围只能是 30000-32767
(三)查看service
kubectl get svc (-n 名称空间)
二、负载分发策略
目前Kubernetes提供了两种负载分发策略:RoundRobin和SessionAffinity,具体说明如下:
RoundRobin:轮询模式,即轮询将请求转发到后端的各个Pod上。
SessionAffinity:基于客户端IP地址进行会话保持的模式。
即第1次将某个客户端发起的请求转发到后端的某个Pod上,之后从相同的客户端发起的请求都将被转发到后端相同的Pod上。
在默认情况下,Kubernetes采用RoundRobin模式对客户端请求进行负载分发,但我们也可以通过设置service.spec.sessionAffinity=ClientIP来启用SessionAffinity策略。这样,同一个客户端IP发来的请求就会被转发到后端固定的某个Pod上了。
通过Service的定义,Kubernetes实现了一种分布式应用统一入口的定义和负载均衡机制。
三、各种类型service的使用
(一)无头service
默认方式,根据是否生成ClusterIP又可以分为普通Service和Headless Service两类。
无头IP只能使用clusterip类型,但是没有cluster ip,而是将解析的IP解析到后端的pod之上。
该服务不会分配cluster ip,也不会通过kube-proxy做反向代理和负载均衡。而是通过DNS提供稳定的网络ID来访问,DNS会将headless service的后端直接解析为pod ip列表。主要供statefulset使用。
在某些场景中,开发人员可能不想使用Service提供的负载均衡功能,而希望自己来控制负载均衡策略,针对这种情况,k8s提供了HeadLiness Service,这类Service不会分配ClusterIP,如果想要访问Service,只能通过service的域名进行查询。
(二)NodePort类型的Service
在之前的样例中,创建的Service的IP地址只有集群内部可以访问,如果希望Service暴露给集群外部使用,那么就要使用到另外一种类型的Service,称为NodePort类型。NodePor的工作原理其实就是将service的端口映射到Node的一个端口上,然后就可以通过NodeIp:NodePort来访问service了。
(三)LoadBalancer类型的Service
LoadBalancer和NodePort很相似,目的都是向外部暴露一个端口,区别在于LoadBalancer会在集群的外部再来做一个负载均衡设备,而这个设备需要外部环境支持的,外部服务发送到这个设备上的请求,会被设备负载之后转发到集群中。
(四)ExternalName类型的Service
ExternalName类型的Service用于引入集群外部的服务,它通过externalName属性指定外部一个服务的地址,然后在集群内部访问此Service就可以访问到外部的服务了。