第4课:Service服务发现和负载均衡
掌握Kubernetes中服务的暴露、发现和负载均衡机制
🎯 学习目标
- 理解Service的概念和核心功能
- 掌握不同类型Service的特点和应用场景
- 学习服务发现和负载均衡的实现原理
- 了解Ingress和Service的区别与联系
- 通过实践案例掌握Service的配置和管理
4.1 Service基础概念
🎯 什么是Service?
Service是Kubernetes中定义一组Pod的访问策略的抽象,它为一组Pod提供稳定的网络端点。Service实现了服务发现、负载均衡和会话保持等功能。
🏗️ Service工作原理图
Service
ClusterIP: 10.96.0.1
Service通过Selector关联Pod,并为客户端提供统一的访问入口
🔍 Service的核心功能
- 服务发现:通过DNS或环境变量发现服务
- 负载均衡:在多个Pod间分配流量
- 会话保持:支持基于客户端IP的会话亲和性
- 稳定网络标识:为Pod集合提供固定的IP和DNS名称
- 服务暴露:将服务暴露到集群内部或外部
4.2 Service类型详解
🌐 ClusterIP
默认类型,在集群内部IP上暴露服务。只能从集群内部访问。
# 创建ClusterIP类型的Service
kubectl expose deployment nginx --type=ClusterIP --port=80
🔗 NodePort
在每个节点的IP上暴露服务,通过固定端口访问。可以从集群外部访问。
# 创建NodePort类型的Service
kubectl expose deployment nginx --type=NodePort --port=80 --node-port=30080
🌍 LoadBalancer
在云提供商的负载均衡器上暴露服务。自动创建外部负载均衡器。
# 创建LoadBalancer类型的Service
kubectl expose deployment nginx --type=LoadBalancer --port=80
🚀 ExternalName
将服务映射到外部DNS名称。返回CNAME记录,不进行代理。
# 创建ExternalName类型的Service
kubectl create service externalname my-service --external-name=example.com
4.3 Service的YAML配置详解
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
type: ClusterIP
selector:
app: nginx
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
🔧 关键配置字段解析
selector
通过标签选择器选择要关联的Pod,是Service与Pod关联的核心机制。
ports
定义服务的端口配置,包括:
- port:Service暴露的端口
- targetPort:Pod上的目标端口
- nodePort:NodePort类型时节点上的端口
sessionAffinity
会话亲和性配置,支持None和ClientIP两种模式,实现会话保持功能。
4.4 服务发现机制
🌐 DNS服务发现
CoreDNS集成
Kubernetes集群默认使用CoreDNS作为DNS服务,为每个Service自动创建DNS记录。
DNS格式:服务名.命名空间.svc.cluster.local
环境变量服务发现
当Pod启动时,Kubernetes会为每个活跃的Service创建环境变量,Pod可以通过这些环境变量发现服务。
# 环境变量示例
NGINX_SERVICE_HOST=10.96.0.1
NGINX_SERVICE_PORT=80
4.5 负载均衡原理
⚖️ 负载均衡策略
轮询(Round Robin)
默认的负载均衡策略,按顺序将请求分发到不同的Pod。
会话亲和性(Session Affinity)
基于客户端IP的会话亲和性,确保来自同一客户端的请求始终发送到同一个Pod。
4.6 Ingress与Service的关系
🚪 Ingress是什么?
Ingress是Kubernetes中管理外部访问集群服务的API对象,它提供了HTTP和HTTPS路由、TLS终止、基于名称的虚拟主机等功能。
🔍 Service vs Ingress
| 特性 |
Service |
Ingress |
| 访问层级 |
L4(传输层) |
L7(应用层) |
| 路由能力 |
基于IP和端口 |
基于URL路径、主机名 |
| TLS支持 |
有限 |
完整支持 |
| 外部访问 |
NodePort、LoadBalancer |
单一入口点 |
4.7 实战操作示例
# 1. 创建Deployment
kubectl create deployment nginx --image=nginx:1.21 --replicas=3
# 2. 创建Service
kubectl expose deployment nginx --name=nginx-service --port=80 --target-port=80
# 3. 查看Service状态
kubectl get services
kubectl describe service nginx-service
# 4. 测试Service访问
kubectl run test --image=busybox --rm -it -- wget -O- http://nginx-service
# 5. 更新Service类型为NodePort
kubectl patch service nginx-service -p '{"spec":{"type":"NodePort"}}'
# 6. 查看NodePort端口
kubectl get service nginx-service
# 7. 删除Service
kubectl delete service nginx-service
# 8. 创建外部服务
kubectl create service externalname my-service --external-name=example.com
4.8 最佳实践和注意事项
💡 Service使用建议
- 合理选择Service类型:根据访问需求选择合适的Service类型
- 使用命名端口:为端口指定有意义的名称,提高可读性
- 配置资源限制:为Service后端的Pod设置适当的资源限制
- 使用标签选择器:通过标签组织和管理服务
- 考虑使用Headless Service:对于不需要负载均衡的场景
⚠️ 常见问题排查
- Service无法访问:检查selector配置、Pod状态、网络策略
- 负载均衡不均匀:检查Pod健康状态、会话亲和性配置
- 外部访问失败:检查NodePort范围、防火墙规则、云提供商配置
- DNS解析问题:检查CoreDNS状态、Service命名空间
4.9 进阶概念
🔗 Headless Service
不分配ClusterIP的Service,用于需要直接访问Pod的场景,如StatefulSet的服务发现。
apiVersion: v1
kind: Service
metadata:
name: headless-service
spec:
clusterIP: None
selector:
app: my-app
🔒 服务网格集成
考虑使用Istio等服务网格解决方案,提供更高级的流量管理、安全和可观测性功能。