1. Kubernetes Service 基础概念解析
Kubernetes Service 是集群内部和外部的网络抽象层,它为一组功能相同的 Pod 提供稳定的访问入口。当 Pod 因扩缩容或故障重建导致 IP 变化时,Service 能保持访问端点不变,这是 Kubernetes 服务发现的核心机制。
Service 通过标签选择器(Label Selector)与 Pod 关联。例如以下定义创建了一个关联到所有带有 app.kubernetes.io/name: MyApp 标签的 Pod 的 Service:
yaml复制apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
关键字段说明:
port: Service 对外暴露的端口targetPort: Pod 实际监听的端口selector: 用于匹配后端 Pod 的标签
2. Service 类型深度剖析
2.1 ClusterIP 类型
默认的 Service 类型,分配一个集群内部可访问的虚拟 IP(Cluster IP)。这是最基础的 Service 类型,其他类型都是在其基础上扩展。
yaml复制apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP # 可省略,默认值
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
典型使用场景:
- 微服务间的内部通信
- 前端应用访问后端API
- 需要服务发现但不需要外部访问的服务
2.2 NodePort 类型
在 ClusterIP 基础上,在每个节点上开放一个静态端口(NodePort),将节点端口上的流量转发到 Service。
yaml复制apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
type: NodePort
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
nodePort: 30007 # 可选,范围30000-32767
端口分配策略:
- 如果未指定 nodePort,Kubernetes 会自动在 30000-32767 范围内分配
- 静态端口段(30000-30085)优先用于手动指定
- 动态端口段(30086-32767)用于自动分配
2.3 LoadBalancer 类型
在 NodePort 基础上,集成云平台的负载均衡器,将外部流量引导到集群节点。
yaml复制apiVersion: v1
kind: Service
metadata:
name: my-loadbalancer
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
云平台集成细节:
- AWS: 创建 ELB/ALB
- GCP: 创建 Network Load Balancer
- Azure: 创建 Azure Load Balancer
2.4 ExternalName 类型
将 Service 映射到外部 DNS 名称,用于集成集群外服务。
yaml复制apiVersion: v1
kind: Service
metadata:
name: my-external-service
spec:
type: ExternalName
externalName: my.database.example.com
3. 服务暴露实验详解
3.1 NodePort 服务暴露实验
实验目标:通过 NodePort 将应用暴露到集群外部
- 创建 Deployment
yaml复制apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
- 创建 NodePort Service
yaml复制apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
type: NodePort
selector:
app: web
ports:
- port: 80
targetPort: 80
nodePort: 30080
- 验证访问
bash复制# 获取节点IP
kubectl get nodes -o wide
# 通过任意节点IP+端口访问
curl http://<node-ip>:30080
3.2 LoadBalancer 服务暴露实验
实验目标:通过云平台负载均衡器暴露服务
- 创建 LoadBalancer Service
yaml复制apiVersion: v1
kind: Service
metadata:
name: web-lb
spec:
type: LoadBalancer
selector:
app: web
ports:
- port: 80
targetPort: 80
- 获取外部IP
bash复制kubectl get svc web-lb -w
- 通过负载均衡器访问
bash复制curl http://<external-ip>
4. 负载均衡机制深度解析
4.1 kube-proxy 工作原理
kube-proxy 是 Service 功能的核心组件,支持三种模式:
-
userspace 模式(已弃用)
- 流量经过用户空间代理
- 性能较差,仅用于历史兼容
-
iptables 模式(默认)
- 通过 iptables 规则实现负载均衡
- 无中间代理,性能较好
- 不支持会话保持等高级功能
-
IPVS 模式(推荐生产使用)
- 基于内核的IP虚拟服务器
- 支持多种负载均衡算法(rr, wrr, lc, wlc等)
- 性能最好,支持大规模集群
配置IPVS模式:
bash复制kubectl edit configmap -n kube-system kube-proxy
修改 mode: "ipvs"
4.2 负载均衡算法对比
| 算法 | 描述 | 适用场景 |
|---|---|---|
| Round Robin | 轮询分发请求 | 默认算法,后端性能相近 |
| Least Connection | 选择连接数最少的后端 | 后端处理能力差异大 |
| Source IP Hash | 根据源IP哈希选择后端 | 需要会话保持 |
配置示例:
yaml复制apiVersion: v1
kind: Service
metadata:
name: web-service
annotations:
service.kubernetes.io/ipvs-scheduler: "lc" # 最少连接
spec:
type: LoadBalancer
selector:
app: web
ports:
- port: 80
targetPort: 80
5. 高级配置与最佳实践
5.1 会话保持(Sticky Session)
配置客户端IP会话亲和性:
yaml复制apiVersion: v1
kind: Service
metadata:
name: web-sticky
spec:
type: LoadBalancer
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 3600 # 会话保持时间
selector:
app: web
ports:
- port: 80
targetPort: 80
5.2 多端口服务
一个Service可以暴露多个端口:
yaml复制apiVersion: v1
kind: Service
metadata:
name: multi-port
spec:
selector:
app: web
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
- name: https
protocol: TCP
port: 443
targetPort: 8443
5.3 外部流量策略
控制外部流量路由方式:
yaml复制apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
type: LoadBalancer
externalTrafficPolicy: Local # 保留客户端源IP
selector:
app: web
ports:
- port: 80
targetPort: 80
可选值:
Cluster: 默认,流量可能转发到其他节点Local: 只转发到本节点Pod,保留客户端IP
6. 常见问题排查指南
6.1 Service 无法访问排查步骤
- 检查Service是否存在:
bash复制kubectl get svc <service-name>
- 验证Endpoints是否正确:
bash复制kubectl get endpoints <service-name>
- 检查Pod标签是否匹配:
bash复制kubectl get pods --show-labels
- 测试ClusterIP连通性:
bash复制kubectl run test-$RANDOM --rm -ti --image=alpine -- sh
wget -qO- <cluster-ip>:<port>
- 检查kube-proxy日志:
bash复制kubectl logs -n kube-system <kube-proxy-pod>
6.2 NodePort 无法访问排查
- 检查节点防火墙规则
- 验证节点端口是否监听:
bash复制ss -tulnp | grep <node-port>
- 检查kube-proxy是否正常运行
- 验证云平台安全组规则
6.3 LoadBalancer 状态为Pending
- 检查云平台配额
- 验证云提供商集成是否正常
- 查看Service事件:
bash复制kubectl describe svc <service-name>
7. 性能优化建议
-
大规模集群使用IPVS模式
bash复制
kubectl edit configmap -n kube-system kube-proxy设置
mode: "ipvs" -
合理设置会话保持时间
yaml复制sessionAffinityConfig: clientIP: timeoutSeconds: 1800 # 30分钟 -
避免使用HostNetwork
yaml复制spec: hostNetwork: false # 默认值 -
监控Service性能指标
- kube-proxy同步延迟
- 每个Service的规则数量
- 连接建立时间
-
定期清理未使用的Service
bash复制
kubectl delete svc <unused-service>
通过本实验,我们深入理解了Kubernetes Service的各种暴露方式及其负载均衡机制。实际生产环境中,建议根据具体需求选择合适的Service类型,并遵循最佳实践进行配置。对于关键业务服务,建议结合监控和告警系统,确保服务发现和负载均衡机制始终正常运行。
