一、Service基本用法
一般来说对外提供服务的应用程序需要通过某种机制实现,对于容器应用最简单的方式就是通过TCP/IP机制以及监听IP和端口号实现。例如定义一个提供Web服务的RC,由两个Tomcat容器副本组成,每个容器都通过containerPort设置提供服务的端口号未8080。
apiVersion: v1
kind: ReplicationController
metadata:
name: webapp
spec:
replicas: 2
template:
metadata:
name: webapp
labels:
app: webapp
spec:
containers:
- name: webapp
image: tomcat:latest
ports:
- containerPort: 8080 #containerPort是pod内部容器的端口
[root@fangren-clouddev K8S_yaml]# kubectl get pods -l app=webapp -o yaml | grep podIP #获取Pod IP地址
# podIP: 10.244.0.249
# podIP: 10.244.0.248
可以通过PodIP和Container直接访问容器服务:
直接通过Pod的IP地址和端口号可以访问容器应用内服务,但是Pod的IP地址是不可靠的,例如
- 当Pod所在的Node发生故障,Pod将被Kubernetes重新调度到另一个Node,Pod的IP地址将发生变化
- 如果容器本身以分布式的部署方式,通过多个实例共同提供服务,就需要在这些实例的前端设置一个负载均衡器实现请求的分发
- Kuebernetes中的Service就是用于解决这些问题的核心组件
为了让客户端应用访问到两个Tomcat Pod实例,需要创建一个Service来提供服务
[root@fangren-clouddev K8S_yaml]# kubectl get servic
# webapp ClusterIP 10.97.220.40 <none> 8080/TCP 4s
# 系统新创建的Service,可以看到系统为其分配一个虚拟的IP地址(ClusterIP),
# Service所需的端口则从Pod中的containerPort复制而来
通过Service的IP地址和Service的端口好访问该Service:
对于Service地址10.97.220.40:8080的访问被自动负载分发到两个Pod之一: 10.244.0.249:8080或10.244.0.248:8080
可以通过配置文件创建Service:
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
ports:
- port: 8081 #Service所需的虚拟端口号
targetPort: 8080 #指定后端Pod的端口号
selector:
app: webapp
Service定义中的关键字段是ports和selector。ports定义部分指定了Service所需的虚拟端口号8081,由于与Pod容器端口号8080不一样,所以需要再通过targetPort来指定后端Pod的端口号。selector定义部分设置的是后端Pod拥有的label: app=webapp。
在提供服务的Pod副本集运行过程中,如果Pod列表发生了变化,则Kubernetes的Service控制器会持续监控后端Pod列表的变化,实时更新对应的后端Pod列表变化。
一个Service对应的“后端”由Pod的IP和容器端口号组成,即一个完整的"IP:Port"访问地址,这个在Kubernetes中叫做Endpoint。
Kuberbetes自动创建了与Service关联的Endpoint资源对象,这可以通过查询Endpoint对象进行查看。
- RoundRobin:轮询模式,即轮询将请求转发到后端的各个Pod上
- SessionAffinity:基于客户端IP地址进行会话模式保持模式,即第1次将某个客户端发起的请求转发到后端的某个Pod上,之后从相同客户端发其的请求都将被转发到后端相同的Pod上