四. Service介绍
1. 基本感念
service 是一组具有相同 label pod 集合的抽象,集群内外的各个服务可以通过 service 进行互相通信,当创建一个 service 对象时也会对应创建一个 endpoint 对象,endpoint 是用来做容器发现的,service 只是将多个 pod 进行关联,实际的路由转发都是由 kubernetes 中的 kube-proxy 组件来实现,因此,service 必须结合 kube-proxy 使用,kube-proxy 组件可以运行在 kubernetes 集群中的每一个节点上也可以只运行在单独的几个节点上,其会根据 service 和 endpoints 的变动来改变节点上 iptables 或者 ipvs 中保存的路由规则。
Service 所针对的 Pods 集合通常是通过selector来确定的。Service 在 Kubernetes 中是一个 REST 对象,和 Pod 类似。 像所有的 REST 对象一样,Service 定义可以基于 POST 方式,请求 API server 创建新的实例。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
Service存在的意义
- 防止Pod失联(服务发现)
- 定义一组Pod访问策略(负载均衡)
Pod和Service关系
- 通过Service实现pod的负载均衡
- pod与Service通过label、select关联
2. service 的工作原理
endpoints controller 是负责生成和维护所有 endpoints 对象的控制器,监听 service 和对应 pod 的变化,更新对应 service 的 endpoints 对象。当用户创建 service 后 endpoints controller 会监听 pod 的状态,当 pod 处于 running 且准备就绪时,endpoints controller 会将 pod ip 记录到 endpoints 对象中,因此,service 的容器发现是通过 endpoints 来实现的。而 kube-proxy 会监听 service 和 endpoints 的更新并调用其代理模块在主机上刷新路由转发规则。
3. service 的负载均衡
上文已经提到 service 实际的路由转发都是由 kube-proxy 组件来实现的,service 仅以一种 VIP(ClusterIP) 的形式存在,kube-proxy 主要实现了集群内部从 pod 到 service 和集群外部从 nodePort 到 service 的访问,kube-proxy 的路由转发规则是通过其后端的代理模块实现的,kube-proxy 的代理模块目前有四种实现方案,userspace、iptables、ipvs、kernelspace,其发展历程如下所示:
- kubernetes v1.0:services 仅是一个“4层”代理,代理模块只有 userspace
- kubernetes v1.1:Ingress API 出现,其代理“7层”服务,并且增加了 iptables 代理模块
- kubernetes v1.2:iptables 成为默认代理模式
- kubernetes v1.8:引入 ipvs 代理模块
- kubernetes v1.9:ipvs 代理模块成为 beta 版本
- kubernetes v1.11:ipvs 代理模式 GA
4. Service的四种类型
- ClusterIP: 默认类型,自动分配一个仅cluster内部可以访问的虚拟ip
- NodePort: 在clusterIP基础上为service在每台机器上绑定一个端口,这样就可以通过Nodeip:port方式来访问该服务。(对外访问应用使用)
- Loadbalance: 在NodePort基础上,接触cloud provider创建一个外部负载均衡器,并将请求转发到nodeip:port(对外访问应用使用,公有云)
- externalName: 把集群外部的服务引入到集群内部,在集群内中直接使用,没有任何类型的代理被创建