1. 概述
k8s 中的service是Pod的提供对外访问的入口。
1.1Service解决的问题
Pod和容器是不健壮的,可能因为故障随时销毁和重新创建,所以为了解决这个问题k8s使用了Service为访问一组Pod提供了入口和负载均衡。
- k8s中的Pod是不健壮的,Pod可能会随时销毁和创建
- Pod中的容器可能因为故障而崩溃
在 Kubernetes 集群中,每个 Pod 都具有内部 IP 地址。但是,Deployment 中的 Pod 可以随时加入和退出,而且它们的 IP 地址也不是固定的。因此,直接使用 Pod IP 地址毫无意义。通过 Service,您会获得稳定的 IP 地址,该 IP 地址在 Service 的生命周期内有效,即使成员 Pod 的 IP 地址发生变化也仍然有效。
Service 还提供负载平衡。客户端会调用单个稳定的 IP 地址,而且客户端请求在 Service 的成员 Pod 之间保持平衡。
2. Service类型
k8s提供了四种不同类型的Service以满足不同的使用场景,这五种类型分别为:
- ClusterIP
- NodePort
- LoadBalancer
- ExternalName
- Headless
2.1.每种类型的作用
类型 | 作用 | 是否有集群IP |
---|---|---|
ClusterIP | 集群内部访问 | 有 |
NodePort | 集群外部访问的 | 有 |
LoadBalancer | 通过LoadBalancer来访问,一般由云服务商提供很方便接入云服务提供商 | 有 |
ExternalService | 像访问k8s内部Service一样访问外部服务,比如接入的三方服务 | 有 |
Headless | 不需要服务均衡且无IP的服务,用于 | 无 |
3. 类型详解
3.1. ClusterIP
ClusterIP是k8s默认的Service类型,如果service的资源清单中没有指定type字段,默认这个service的类型就是ClusterIP.
关于ClusterIP我可以通过拆字来理解它,Cluster表示集群,IP表示我们通常理解的IP地址,那么两个结合起来就是集群的IP,那么就是只有集群内部才可以访问的一个IP服务。
3.1.1 ClusterIP 特性
-
默认Service类型且最通用,例如:在微服务场景中,一个系统可能会有很多服务部署在一个k8s集群中,而服务与服务之间又有内部调用,此时服务内部都会通过ClusterIP提供给的Service来进行通信。
-
k8s会为ClusterIP Service分配一个集群内部的IP,IP地址是你在初始化集群时指定的CIDR 地址池中的一个,因为这个IP可以理解为是虚拟的,所以这个IP就只有在集群内部才可以访问。
-
k8s集群外部不可以访问。
3.1.2 ClusterIP底层原理
ClusterIP是一个虚拟IP,是由k8s节点上的iptables或ipvs来管理的。
3.2 NodePort
NodePort就是节点上的端口,自然可以在集群外部访问集群内的资源。
节点是k8s中的一个关键组成,一般是物理机或虚拟机,NodePort就是节点上的端口。
NodePort是建立在clusterIP之上的在建立NodeProt Service的时会先创建ClusterIP。
如果你的物理机或虚拟机有公网带宽,那么你就可以通过公网IP+NodePort指定或随机的端口来访问你的服务。
3.3 LoadBalancer
在之前我们了解到NodePort可以在k8s集群外部访问k8s集群内服务资源,同时也可以在有公网IP和带宽的节点上开放公网访问。
这么看我们可以通过NodePort开放公网访问,ClusterIP开放集群内服务互相通信,如下图所示:
在实践中,使用这种架构也是可以的,但是会有一些不太好的地方:
- 每个Node都需要公网IP和公网带宽
- 每个Node都要开放一个端口
- 可能会将流量转发到不健康的Node上
这个时候LoadBalancer就可以派上用场了,LoadBalancer不用再Node节点上开放流量专用端口,公网IP和带宽。实践中,只需要LoadBalancer有公网IP和带宽就可以了。
下表是NodePort和LoadBalancer的对比:
NodePort | LoadBalancer |
---|---|
k8s为每个Node预留一个端口并将连接转发到Pod | 不需要每个Node预留端口 |
NodePort既可以通过Node IP+端口访问,有可能通过ClusterIP访问 | 只能通过Load Balancer 公网IP访问 |
端口不必须指定。如果不指定,k8s会随机选择一个端口(根据kubelet中端口的range来决定,默认为30000- 32767) | Load Balancere有自己唯一的公网IP地址并将所有的流量转发到服务 |
Node可能会处于不健康状态,那么如果流量入口指向了一个不健康的Node那么服务就会宕机 | LoadBalancer是在所有Node之上,它会将流量传播的健康的Node中并且会将不健康的机器暂时剔除负载均衡列表,等待Node恢复健康状态后再转发流量 |
3.4 ExternalService
3.5Headless
4. 访问Service
在k8s中,Service可以通过DNS name方式进行访问,根据同一个namespace和不同namespace可以分为两种方式:
- 同一个namespace
如果两个Pod在同一个namespace中,那么可以直接通过Service name来访问彼此,不需要指定namespace。
例如:你有两个服务器,一个前端服务和一个后端。前端服务Service name为usercenter-web, 另外有一个后端服务,Service name为usercenter-service, 它们都在default namespace中。前端usercenter服务想要访问后端usercenter服务,那么可以直接通过http://usercenter-service 来访问。
- 不同namespace
如果两个Pod在同一个集群但是不在同一个namespace下,那么可以通过FQDN(Fully Qualified Domain Name)来访问彼此。FQDN的格式为service_name.namespace.svc.cluster.local。
例如:现在你的前端usercenter服务在default namespace中,而你的后端usercenter服务在sales-business namespace中。前端usercenter服务想要访问后端usercenter服务,那么可以通过http://usercenter-service.sales-business.svc.cluster.local 。
4.1 CluseterIP
根据ClusterIP的特性我们知道,ClusterIP类型的Service只能在集群内部访问。相同namespace直接通过Service name进行访问,不同namespace通过FQDN来访问。
4.2 NodePort
可以在集群内外部进行访问。集群内部通过Service name或者FQDN进行访问;集群外部通过Node IP加端口进行访问。
4.3 LoadBalancer
通过LoadBalancer的公私网IP和端口进行访问。