Kubernetes Service
定义了这样一种抽象:逻辑上的一组 Pod,一种能够访问它们的策略 —— 一般被称为微服务。这一组 Pod 可以被 Service 访问到,一般是经过selector
实现的。
举例:考虑一个图片处理 backend,它运行了3个副本。这些副本是可互换的 —— frontend 不需要关心它们调用了哪一个 backend 副本。 然而组成这一组 backend 程序的 Pod 实际上可能会发生变化,frontend 客户端不必知道,并且也不需要跟踪这一组 backend 的状态。Service 定义的抽象可以解耦这种关联。
Service能够提供负载均衡的能力,可是使用上存在以下限制
web访问的service服务示例图
此类型会提供一个集群内部的虚拟IP(与pod不在同一网段),以供集群内部的pod之间通信使用。clusterIP
也是kubernetes service
的默认类型,主要需要以下几个组件的协同工作
apiservice
:在创建service
时,apiserver
接收到请求以后将数据存储到etcd
中。kube-proxy
:k8s的每个节点中都有该进程,负责实现service功能,这个进程负责感知service,pod的变化,并将变化的信息写入本地的iptables
中iptables
:使用NAT等技术将virtuallp
的流量转至endpoint
中NodePort
模式除了使用clusterip
外,也将service
的port映射到每个node的一个指定内部的port上,映射的每个node的内部port都一样。为每个节点暴露一个端口,通过nodeIP+nodeport
可以访问你这个服务,同时服务依然会有cluster
类型的ip+port
。内部通过clusterip
方式访问,外部通过nodeport
方式访问
loadbalancer
在nodeport
基础上,k8s可以请求底层云平台创建一个负载均衡器,将每个node作为后端,进行服务分发,该模式需要底层云平台(例如GCE)支持
lngress
是一种http
方式的路由转发机制由lngress controller
和http
代理服务器组合而成,lngress controller
实例监控kubernetes api
实时更新http
代理服务器的转发规则。http
代理服务器有GCE load-balancer、haproxy、nginx
等开源方案
service
是一个抽象概念,定义了一个服务的多个pod逻辑合集和访问pod的策略,一般把service
称为微服务.举个例子一个a服务运行3个pod,b服务怎么访问a服务的pod,pod的ip都不是持久化的重启之后就会有变化。这时候b服务可以访问跟a服务绑定的service
,service
信息是固定的提前告诉b就行了,service
通过Label Selector
跟a服务的pod绑定,无论a的pod如何变化对b来说都是透明的
在Kubernetes
集群中,每一个 Node 运行一个kube-proxy
进程。kube-proxy
负责为 Service
实现了一种 VIP(虚拟 IP)的形式,而不是 ExternalName
的形式
从Kubernetes v1.0
开始,已经可使用 userspace
代理模式。Kubernetes v1.1
添加了 iptables 代理模式,在Kubernetes v1.2
中kube-proxy
的 iptables
模式成为默认设置。Kubernetes v1.8
添加了ipvs
代理模式
这种模式kube-proxy
会监视 Kubernetes master
对 Service
对象和 Endpoints
对象的添加和移除。 对每一个 Service
它会在本地 Node 上打开一个端口(随机选择)。 任何链接到代理端口
的请求,都会被代理到 Service
的backend Pods
中的某个上面(如 Endpoints
所报告的同样)。 使用哪一个 backend Pod
,是 kube-proxy
基于 SessionAffinity
来肯定的
它配置iptables
规则,捕获到达该 Service
的 clusterIP
(是虚拟 IP)和 Port 的请求,并重定向到代理端口,代理端口再代理请求到 backend Pod
默认状况下,userspace
模式下的kube-proxy
经过循环算法选择后端,默认的策略是,经过round-robin
算法来选择 backend Pod
这种模式,kube-proxy
会监视Kubernetes
控制节点对 Service
对象和 Endpoints
对象的添加和移除。 对每一个 Service
它会配置iptables
规则,从而捕获到达该Service
的clusterIP
和端口的请求进而将请求重定向到Service
的一组 backend
中的某个上面。对于每一个 Endpoints
对象,它也会配置 iptables
规则,这个规则会选择一个backend
组合。
默认的策略是kube-proxy
在 iptables
模式下随机选择一个backend
使用iptables
处理流量具备较低的系统开销,由于流量由Linux netfilter
处理,而无需在用户空间和内核空间之间切换。 这种方法也可能更可靠。
若是kube-proxy
在 iptables
模式下运行,而且所选的第一个Pod 没有响应,则链接失败。 这与userspace
模式不一样;在这种状况下kube-proxy
将检测到与第一个 Pod 的链接已失败,并会自动使用其余后端 Pod 重试。
咱们可使用Pod readiness
探测器 验证后端 Pod 是否能够正常工做,以便 iptables
模式下的kube-proxy
仅看到测试正常的后端。这样作意味着能够避免将流量经过kube-proxy
发送到已知已失败的Pod
在 ipvs
模式下kube-proxy
监视Kubernetes
服务Service
和端点Endpoints
调用 netlink
接口相应地建立 IPVS
规则, 并按期将 IPVS
规则与Kubernetes
服务Service
和端点Endpoints
同步。该控制循环可确保IPVS
状态与所需状态匹配。访问服务Service
时,IPVS
将流量定向到后端Pod之一
IPVS
代理模式基于相似于iptables
模式的 netfilter
挂钩函数,可是使用哈希表做为基础数据结构,而且在内核空间中工做。 这意味着,与 iptables
模式下的 kube-proxy
相比,IPVS
模式下的kube-proxy
重定向通讯的延迟要短,而且在同步代理规则时具备更好的性能。与其余代理模式相比,IPVS
模式还支持更高的网络流量吞吐量
IPVS
提供了更多选项来平衡后端Pod的流量
注意: 要在IPVS
模式下运行kube-proxy
必须在启动kube-proxy
以前使IPVS Linux
在节点上可用。 当kube-proxy
以IPVS
代理模式启动时,它将验证IPVS
内核模块是否可用。 若是未检测到IPVS
内核模块,则 kube-proxy
将退回到以iptables
代理模式运行
ClusterIP
:默认类型,自动分配一个仅Cluster
内部能够访问的虚拟IP
(只能在集群内部访问)
NodePort
:经过每一个 Node 上的 IP
和静态端口(NodePort)(范围30000-32767)
暴露服务。以ClusterIP
为基础NodePort
服务会路由到 ClusterIP
服务。经过请求<NodeIP>:<NodePort>
能够从集群的外部访问一个集群内部的 NodePort
服务ClusterIP
和路由规则会自动创建
LoadBalancer
:使用云提供商的负载均衡器,能够向外部暴露服务。外部的负载均衡器能够路由到 NodePort
服务和 ClusterIP
服务
ExternalName
创建一个dns
别名指到service name
上,主要是防止service name
发生变化,要配合dns插件使用