K8S之Service
什么 是Service?
在kubernetes中,service是一个抽象的概念,一个 Pod
的逻辑分组,一种可以访问它们的策略 , 通常称为微服务。 这一组 Pod
能够被 Service
访问到,通常是通过 Label Selector
进行标签选择,选择出具有相同标签属性的pod组成的一个集合,以一个身份为用户提供服务访问。
需要注意的是,Pod是处于一个期望值的数量上的,有Pod被不断的销毁,同时也有新的Pod被创建,Pod的数量处于一个动态的平衡当中,维持着期望值的一个状态。
Service能够提供负载均衡的能力,但是仅支持四层负载(ipvs),没有器七层负载的能力(可以装插件实现)
Kube-proxy的作用
在k8s中,service的集群IP能够实现数据报文请求的转发,需要在node节点上部署的一个组件kube-proxy,具体来说kube-proxy实现的主要有几点:
- 实时监控API,获取service和pod的信息,来保持pod和虚拟IP的映射关系,获取新建或删除service和pod的指令
- 当有新的service建立,kube-proxy回调网络接口,构建IPVS规则
- kube-proxy会定期同步service和pod的转发规则,确保失效的转发及时更新
- 维护本地netfiller、PVS(新版默认)等内核组件,实现数据报文的转发规则
- 实现每个node节点上虚拟IP的发布和路由维护
Service存在的意义
- 防止Pod失联(服务发现)
- 定义一组Pod的策略(负载均衡)
- 支持ClusterIP、NondePort、LoadBalencer三种类型
Service和Kube-proxy之间的关系
kube-proxy其实就是管理service的访问入口,包括集群内Pod到Service的访问和集群外访问service。 kube-proxy管理sevice的Endpoints,该service对外暴露一个Virtual IP,也成为Cluster IP, 集群内通过访问这个Cluster IP:Port就能访问到集群内对应的service下的Pod。 service是通过Selector选择的一组Pods的服务抽象,其实就是一个微服务,提供了服务的LB和反向代理的能力,而kube-proxy的主要作用就是负责service的实现。 service另外一个重要作用是,一个服务后端的Pods可能会随着生存灭亡而发生IP的改变,service的出现,给服务提供了一个固定的IP,而无视后端Endpoint的变化。
Service服务的类型
Service 在 K8s 中有以下四种类型:
ClusterIp:默认类型,自动分配一个仅 Cluster 内部可以访问的虚拟 IP,集群内部对一种服务访问的代理IP ,说白了就是在集群内部访问的服务,不对外部开放,这点一定要注意。
NodePort:用来对集群外暴露Service,在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过 NodeIP(node节点IP)+NodePort 来访问该服务,外部用户访问集群的接口。
LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部负载均衡器,并将请求转发到NodeIP+NodePort,为若干个以NodeIP+NodePort为代表的集群节点做负载。
ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有 kubernetes 1.7 或更高版本的 kube-dns 才支持,通常我们会用core-dns。
kube-proxy的三种模式
Userspace Proxy 模式
Iptables Proxy 模式
IPVS Proxy 模式
- apiserver 用户通过kubectl命令向apiserver发送创建service的命令,apiserver接收到请求后将数据存储到 etcd 中
- kubernetes的每个节点都有kube-porxy进程,这个进程负责感知service,pod的变化,并将变化的信息写入本地的ipvs规则中
- ipvs使用NAT等技术将virtualIP的流量转至endpoint中
Headless Service
Headless Service即无头服务,说白了就是隐去了ClusterIP,即不能所负载均衡,如果说不想或者不需要做负载均衡的话,可以通过指定 Cluster IP(spec.clusterIP) 的值为 “None” 来创建 Headless Service 。kube-proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由。
需要注意的点:
- 没有ClusterIP,指向的IP都是PodIP
- 没有ClusterIP,因此不能被负载,只能内部使用
- 通过core-dns解析解析出来的都是具有podIP的Pod,也就是解析的Pod是唯一的
它的应用场景:通过coredns进行解析,结合StateFulSet控制器提供网络的唯一标识符