深入解析service
一、概念
Service主要用于提供网络服务,通过Service的定义,能够为客户端
应用提供稳定的访问地址(域名或IP地址)和负载均衡功能,以及屏蔽
后端Endpoint的变化,它是Kubernetes实现微服务的核心资源。
本章对Service的概念、负载均衡机制、多端口号、外部服务、暴露到集群外、
支持的网络协议、服务发现机制、Headless Service、端点分片和服务拓
扑等内容进行认识学习。
二、什么是service?
Service 是一种抽象概念,用于定义一组 Pod 的访问入口。它就像一个虚拟的代理,将来自外部的请求转发到后端 Pod 的集合中。
再理解一遍:Service是一个抽象层,它定义了一种访问和暴露一组运行在Pods中的应用的方法。Service能够提供负载均衡和服务发现,让客户端无需关心后端Pod的复杂性。
三、Service 的核心功能
服务发现与负载均衡
- Kubernetes Service 为一组具有相同标签(label)的 Pod 提供了一个稳定的网络入口点。通过定义 Service,Kubernetes 会在集群内部为 Service 分配一个固定的 ClusterIP,客户端只需通过这个 IP 地址就可以访问到背后的所有 Pod。
- Service 提供了一种抽象层,可以实现负载均衡,将客户端请求均匀地分布到后端关联的多个 Pod 上,从而提高系统的可靠性和性能。
服务抽象
-
Service 将一组具有相同功能的 Pod 抽象成一个单一的服务实体,隐藏了底层的 Pod 实例变化,如 Pod 的创建、销毁、扩容、缩容等操作都不会影响客户端对服务的访问。
网络代理: -
Kubernetes 通过 iptables 规则或者 kube-proxy 组件实现代理功能,透明地将到达 Service ClusterIP 的流量转发到后端的 Pod 上。
多类型暴露
- Kubernetes Service 支持多种类型的暴露方式,如 ClusterIP(仅集群内部访问)、NodePort(通过节点端口暴露到集群外部)、LoadBalancer(借助云提供商的负载均衡器暴露到公网)以及 ExternalName(将 Service 映射到外部 DNS 名称)。
健康检查与自动摘除
-
当 Service 与 Endpoint Controller 结合使用时,能够自动跟踪后端 Pod 的健康状态,并将不健康的 Pod 从服务负载均衡列表中移除,直到其恢复正常。
Session Affinity(会话保持): -
对于部分需要会话一致性的应用,Service 支持客户端 IP 会话保持,确保来自同一客户端的请求始终路由到相同的后端 Pod。
DNS 解析
- Kubernetes 为每个 Service 自动生成 DNS 记录,使得集群内部的其他 Pod 或 Service 可以通过域名而非 IP 地址来访问它。
四、Service 类型
Kubernetes 提供了四种类型的 Service:
ClusterIP: 默认的服务类型,将 Service 暴露在集群内部,只能在集群内部访问。
NodePort: 将 Service 暴露在所有节点的指定端口上,可以通过节点 IP 地址访问。
LoadBalancer: 创建一个外部负载均衡器,将 Service 暴露到外部网络。
ExternalName: 将 Service 映射到外部 DNS 名称上,无需创建负载均衡器。
示例代码:
- ClusterIP 示例:
apiVersion: v1
kind: Service
metadata:
name: internal-service
spec:
type: ClusterIP
selector:
app: MyApp
ports:
- name: http
port: 80
targetPort: 8080
- NodePort 示例:
apiVersion: v1
kind: Service
metadata:
name: nodeport-service
spec:
type: NodePort
selector:
app: MyApp
ports:
- name: http
port: 80
targetPort: 8080
nodePort: 30080
- LoadBalancer 示例:
apiVersion: v1
kind: Service
metadata:
name: load-balancer-service
spec:
type: LoadBalancer
selector:
app: MyApp
ports:
- name: http
port: 80
targetPort: 8080
# 可选,指定预设的负载均衡器IP
# loadBalancerIP: X.X.X.X
- ExternalName 示例:
apiVersion: v1
kind: Service
metadata:
name: external-database-service
spec:
type: ExternalName
externalName: some.database.example.com
五、Service 实现机制
1.Service 实现主要依赖两个组件:
Endpoints: Endpoints 是由 kube-proxy 维护的一个动态更新的资源,其中包含了后端 Pod 的服务地址和端口号信息。
Selectors: Selectors 是 Service 中定义的标签匹配规则,用于选择后端 Pod。
当客户端向 Service 发送请求时,kube-proxy 会根据 Service 的 Selectors 筛选出匹配的后端 Pod,并从 Endpoints 中获取这些 Pod 的服务地址和端口号信息。
然后,kube-proxy 会将请求转发到其中一个 Pod 上,具体选择哪个 Pod 取决于所使用的负载均衡算法。
2.Kubernetes 提供了多种负载均衡算法
Round Robin: 轮询算法,将请求均匀地分配到所有可用的后端 Pod 上。
Random: 随机算法,随机选择一个后端 Pod 进行转发。
Least Connections: 最少连接算法,将请求转发到连接数最少的 Pod 上。
Source IP: 源 IP 算法,根据客户端的 IP 地址将请求转发到特定的 Pod 上。
ExternalTraffic: 外部流量算法,将来自外部集群的流量转发到特定的 Pod 上。
六、Service 实战应用
1.Web 应用负载均衡
将多个 Web Pod 部署在 Service 后面,实现负载均衡,提升 Web 应用的性能和可用性。
对于Web应用,通常我们会创建多个副本(Pod)并通过Service实现负载均衡。以下是一个简化的示例,首先创建一个Deployment以部署多个Web应用Pod,然后创建一个Service进行负载均衡。
Deployment YAML示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-deployment
spec:
replicas: 3 # 设置三个副本
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-container
image: your-web-app-image:latest
ports:
- containerPort: 80 # 假设应用监听80端口
Service YAML示例:
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
type: ClusterIP # 或者 LoadBalancer,取决于是否需要公开到集群外部
selector:
app: web-app # 与Deployment的标签匹配
ports:
- port: 80 # Service监听的端口
targetPort: 80 # Pod上对应的目标端口
微服务架构:
2.微服务架构负载均衡
将微服务架构中的各个服务封装成 Service,实现服务发现和负载均衡,方便服务之间的调用和通信。
在微服务架构中,每个服务都会有自己的Service。例如,假设有一个订单服务(order-service)需要被其他服务调用:
订单服务Deployment YAML示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service-deployment
spec:
replicas: 3
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-container
image: your-order-service-image:latest
ports:
- containerPort: 8080 # 假设订单服务监听8080端口
订单服务Service YAML示例:
apiVersion: v1
kind: Service
metadata:
name: order-service-service
spec:
type: ClusterIP
selector:
app: order-service
ports:
- port: 8080 # Service监听的端口
targetPort: 8080 # Pod上对应的目标端口
3.数据库服务负载均衡()
将数据库 Pod 部署在 Service 后面,实现负载均衡,避免单个数据库 Pod 成为性能瓶颈。
对于数据库服务,虽然通常不会进行传统的负载均衡(因为大多数数据库不支持横向扩展写操作)
但在高可用场景下,可以将多个数据库Pod组成一个ReplicaSet,并通过Service对外暴露,但这里的负载均衡主要是为了故障转移和读操作分发。
MySQL主从副本StatefulSet YAML示例:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql-replicas
spec:
serviceName: mysql-service # 创建对应的Service
replicas: 3 # 例如,两主一从
...
MySQL服务Service YAML示例(仅针对读操作负载均衡):
apiVersion: v1
kind: Service
metadata:
name: mysql-service-read-only
spec:
type: ClusterIP
selector:
app: mysql-replicas
ports:
- port: 3306 # MySQL服务端口
sessionAffinity: ClientIP # 可以开启客户端IP会话保持,使得同一个客户端IP的读请求总是发送到同一个后端Pod
核心功能大总结
以上是对Kubernetes Service核心功能的表格,实际应用中,可以通过编写YAML文件来定义Service资源,比如:
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 8080
type: ClusterIP
sessionAffinity: ClientIP
在这个例子中,我们定义了一个类型为ClusterIP的服务web-service
,它选择标签为app=web
的Pod,并且启用了基于客户端IP的会话保持。