但凡觉得哪块说有问题,欢迎评论区留言探讨,谢谢
K8s Service 是 Kubernetes 集群中用于暴露应用程序的一种资源对象:
一、概念与作用:
- Service 可以将一组具有相同功能的 Pod(容器组)定义为一个逻辑分组,并为其提供一个统一的访问入口。通过 Service,无论后端的 Pod 如何变化,如被销毁或重新创建,客户端都可以通过这个固定的入口来访问应用,而无需关心具体 Pod 的 IP 地址和端口。
二、类型
2.1、ClusterIP
ClusterIP:默认类型,在集群内部提供一个虚拟的 IP 地址,用于集群内的 Pod 之间进行通信,外部无法直接访问。
apiVersion: v1
kind: Service
metadata:
name: logger-agent-svc
labels:
app: logger-agent-svc # 跟Deployment的 matchLabels: apps: logger-agent-svc关联
spec:
type: ClusterIP
ports:
- name: http
protocol: TCP
port: 5006
targetPort: 5006
selector:
apps: logger-agent-pod
2.2、NodePort
NodePort:在每个节点上分配一个端口,通过该端口可以从集群外部访问服务,访问方式为<NodeIP>:<NodePort>
。
apiVersion: v1
kind: Service
metadata:
name: xxx-svc
labels:
app: xxx-svc
spec:
type: NodePort
ports:
- name: tcp #service端口名称,不能重复
protocol: TCP
nodePort: 30004 #Service对外暴露端口
port: 9000 #是Service内部监听的端口号,Pod需要监听这个端口来接收从Service转发的流
targetPort: 9000 # targetPort是指定Pod端口的名称或端口号,Service接收到流量后,会将流量转发到Pod的这个端口复
selector:
apps: xxx-pod
2.3、LoadBalancer
LoadBalancer:用于向外部暴露服务,通常会创建一个外部负载均衡器,将流量分发到后端的 Pod 上,适用于需要对外提供服务的场景。
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
用以下命令查看Service
的状态,以获取负载均衡器的外部 IP 地址:
kubectl get services
输出可能如下所示:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service LoadBalancer 10.100.100.10 192.168.1.100 80:32345/TCP 5m
- 在上述例子中,如果是在公有云环境中使用k8s,通常 k8s 会自动创建并配置云负载均衡器资源,然后将其与
LoadBalancer
类型的服务关联,此时通过http://192.168.1.100
访问,流量会经过云负载均衡器,按照后端 Pod 节点资源情况进行负载均衡请求分发。 - 但如果是在私有云或本地环境中,情况有所不同。如果没有额外配置负载均衡器,仅仅依靠 k8s 本身,直接请求
http://192.168.1.100
是无法实现按照 Pod 节点资源情况进行负载均衡请求的。若要实现负载均衡,可能需要手动部署和配置诸如 Nginx、HAProxy 等开源负载均衡软件,或者使用专门的硬件负载均衡设备,并将其与 Kubernetes 集群进行适当的配置和集成,才能实现根据 Pod 节点资源情况来负载均衡请求。
2.4、ExternalName:
ExternalName:将服务映射到一个外部的 DNS 名称,而不是一个集群内部的 IP 地址,主要用于访问集群外部的服务。如下:(集群内部可以通过mysql-ex访问外部的mysql)
apiVersion: v1
kind: Service
metadata:
name: mysql-ex
labels:
app: mysql-ex
spec:
type: ExternalName
externalName: mysql.cluster.xxxx.cn
三、负载均衡策略
3.1、ClusterIP 服务的负载均衡
1、轮询是默认策略之一
在 Kubernetes 里,对于 ClusterIP 类型的服务,kube - proxy 是实现负载均衡的重要组件。当使用 iptables 或 IPVS 模式时,轮询是默认的负载均衡策略之一。以 iptables 模式为例,它会把传入的请求依次分发到后端的各个 Pod 上。例如,若有一个 ClusterIP 服务关联了 3 个 Pod(Pod A、Pod B、Pod C),第一个请求会被导向 Pod A,第二个请求会被导向 Pod B,第三个请求会被导向 Pod C,之后的请求再按照这个顺序循环分配。
2、基于随机的策略
kube - proxy 在某些情况下也会采用随机策略。这种策略会随机选择一个后端 Pod 来处理请求,这样做能避免因特定顺序导致的某些 Pod 负载过高的问题,使得各个 Pod 的负载更加均匀。
3.2、NodePort 服务的负载均衡
与 ClusterIP 类似
NodePort 服务本质上是在 ClusterIP 服务的基础上,在每个节点上开放一个端口以对外暴露服务。所以,其负载均衡策略和 ClusterIP 服务类似,同样会采用轮询、随机等策略,将外部请求通过节点端口分发到后端的 Pod 上。
3.3、LoadBalancer 服务的负载均衡
依赖云服务提供商
当使用 LoadBalancer 类型的服务时,负载均衡主要依赖于云服务提供商提供的负载均衡器(如 AWS 的 ELB、GCP 的 Cloud Load Balancing 等)。这些云服务提供商的负载均衡器支持多种负载均衡算法,不只是轮询。
- 加权轮询:根据后端 Pod 的性能、资源配置等因素为每个 Pod 分配不同的权重,权重高的 Pod 会被分配更多的请求。例如,某个 Pod 所在的节点资源充足、性能较好,就可以为其分配较高的权重,让它处理更多的请求。
- 最少连接数:会将新的请求分配给当前连接数最少的 Pod,以此确保各个 Pod 的负载相对均衡。这种策略在处理长连接请求时非常有效,能避免某些 Pod 因连接过多而出现性能瓶颈。