主题
Service和Ingress配置
课程目标
通过本课程的学习,你将能够:
- 理解Service的概念、类型和工作原理
- 掌握Service的配置和管理方法
- 理解Ingress的概念和工作原理
- 配置不同类型的Ingress规则(路径路由、HTTPS等)
- 选择合适的Ingress控制器
- 排查Service和Ingress的常见故障
前置要求:已完成《Pod和Deployment管理》课程,了解Pod的基本操作
一、为什么需要Service
1.1 Pod访问的问题
在上一节课中,我们学会了创建和管理Pod。但直接访问Pod存在以下问题:
| 问题 | 说明 | 影响 |
|---|---|---|
| Pod IP不固定 | Pod重启后IP会改变 | 无法通过固定IP访问 |
| 多Pod负载均衡 | Deployment通常有多个Pod副本 | 需要手动分配流量 |
| 服务发现 | 需要知道后端Pod的IP和端口 | 应用配置复杂 |
Service的作用:
- 为一组Pod提供统一的访问入口(固定IP和端口)
- 实现负载均衡,自动分发流量到多个Pod
- 提供DNS名称,支持通过域名访问
- 自动感知Pod变化,动态更新后端列表
1.2 Service工作原理
┌─────────────────────────────────────────────────────────────┐
│ Service │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Pod 1 │ │ Pod 2 │ │ Pod 3 │ │
│ │ 10.0.1.2 │ │ 10.0.1.3 │ │ 10.0.1.4 │ │
│ │ app=nginx │ │ app=nginx │ │ app=nginx │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ │ │
│ ┌───────────▼───────────┐ │
│ │ Service: nginx-svc │ │
│ │ IP: 10.96.123.45 │ │
│ │ Port: 80 │ │
│ └───────────┬───────────┘ │
│ │ │
│ ┌───────────▼───────────┐ │
│ │ kube-proxy │ │
│ │ (负载均衡/流量转发) │ │
│ └───────────┬───────────┘ │
└──────────────────────────┼──────────────────────────────────┘
│
┌──────▼──────┐
│ Client │
└─────────────┘工作流程:
- 用户访问Service的IP:Port
- kube-proxy根据规则将流量转发到后端Pod
- 在多个Pod之间进行负载均衡
- 当Pod变化时,自动更新转发规则
二、Service类型详解
2.1 Service类型对比
| 类型 | 访问范围 | 适用场景 | 生产环境使用 |
|---|---|---|---|
| ClusterIP | 集群内部 | 微服务间通信 | ⭐⭐⭐⭐⭐ |
| NodePort | 节点IP+端口 | 开发测试、小型应用 | ⭐⭐ |
| LoadBalancer | 外部负载均衡IP | 云环境生产应用 | ⭐⭐⭐⭐⭐ |
| ExternalName | 外部域名 | 访问外部服务 | ⭐⭐⭐ |
2.2 ClusterIP(默认类型)
特点:
- 分配一个集群内部IP(Cluster IP)
- 只能在集群内部访问
- 通过Service DNS名称访问
适用场景:
- 微服务架构中的内部服务通信
- 前端访问后端API
- 数据库、缓存等中间件访问
实战配置:
yaml
apiVersion: v1
kind: Service
metadata:
name: backend-api
namespace: production
spec:
type: ClusterIP
selector:
app: backend
tier: api
ports:
- name: http
port: 80 # Service端口
targetPort: 8080 # Pod端口
protocol: TCP访问方式:
bash
# 方式1:通过Cluster IP访问
curl http://10.96.123.45:80
# 方式2:通过DNS名称访问(推荐)
curl http://backend-api.production.svc.cluster.local:80
curl http://backend-api.production:80
curl http://backend-api:80 # 同命名空间内2.3 NodePort
特点:
- 在每个节点上开放一个固定端口(30000-32767)
- 通过节点IP:NodePort访问
- 会自动创建ClusterIP
端口范围:
- 默认范围:30000-32767
- 可以自定义(需要在apiserver配置中修改)
实战配置:
yaml
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
type: NodePort
selector:
app: web
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # 可选,不指定则自动分配访问方式:
bash
# 获取NodePort
kubectl get svc web-service
# 输出:
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# web-service NodePort 10.96.123.45 <none> 80:30080/TCP 10s
# 访问方式:任意节点IP + NodePort
curl http://<node-ip>:30080注意事项:
- 端口范围受限(30000-32767)
- 不推荐使用于生产环境(没有负载均衡)
- 适合开发和测试环境
2.4 LoadBalancer
特点:
- 在云环境中自动创建云负载均衡器
- 分配外部可访问的IP地址
- 会自动创建NodePort和ClusterIP
适用场景:
- 云环境(AWS、阿里云、腾讯云等)
- 需要外部访问的生产应用
- 需要云负载均衡器的场景
实战配置:
yaml
apiVersion: v1
kind: Service
metadata:
name: production-api
annotations:
# 阿里云负载均衡配置示例
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: "lb-xxxx"
spec:
type: LoadBalancer
selector:
app: api
ports:
- port: 80
targetPort: 8080
sessionAffinity: ClientIP # 会话保持查看外部IP:
bash
kubectl get svc production-api
# 输出:
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# production-api LoadBalancer 10.96.123.45 47.100.XX.XX 80:31234/TCP 10s
# 直接通过外部IP访问
curl http://47.100.XX.XX2.5 ExternalName
特点:
- 不创建ClusterIP
- 将Service映射到外部DNS名称
- 用于访问集群外部服务
适用场景:
- 访问外部数据库
- 访问第三方API
- 服务迁移过渡期
实战配置:
yaml
apiVersion: v1
kind: Service
metadata:
name: external-mysql
namespace: production
spec:
type: ExternalName
externalName: mysql.example.com # 外部数据库域名使用方式:
bash
# Pod内访问时,就像访问集群内Service一样
mysql -h external-mysql.production -u user -p
# 实际会解析到 mysql.example.com2.6 Service类型选择决策树
需要外部访问?
├── 否 → 使用 ClusterIP
└── 是 → 在云环境?
├── 是 → 使用 LoadBalancer
└── 否 → 开发测试?
├── 是 → 使用 NodePort
└── 否 → 使用 Ingress(下节课讲解)三、Service的配置和管理
3.1 创建和查看Service
创建Service:
bash
kubectl apply -f service.yaml查看Service:
bash
kubectl get services
kubectl describe service my-service3.2 Service的高级配置
3.2.1 会话亲和性
保持客户端请求总是发送到同一个Pod:
yaml
spec:
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 108003.2.2 端口范围
NodePort类型的Service可以指定端口范围:
yaml
spec:
ports:
- port: 80
targetPort: 8080
nodePort: 30000
protocol: TCP3.2.3 服务质量等级
设置Service的服务质量等级:
yaml
spec:
qualityOfService: Guaranteed四、Ingress的概念和工作原理
4.1 Ingress的基本概念
Ingress 是Kubernetes中用于管理外部访问的API对象,它提供了:
- HTTP/HTTPS路由:基于URL路径和主机名的路由
- SSL/TLS终止:处理HTTPS请求的加密和解密
- 负载均衡:在多个后端服务之间分发流量
4.2 Ingress的工作原理
Ingress需要 Ingress控制器 来实现其功能,常用的Ingress控制器包括:
- nginx-ingress:基于Nginx的控制器
- traefik:轻量级的Ingress控制器
- contour:基于Envoy的控制器
- istio:服务网格中的Ingress功能
五、Ingress的配置
5.1 基本Ingress配置
配置示例:
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: example.com
http:
paths:
- path: /app
pathType: Prefix
backend:
service:
name: my-service
port:
number: 805.2 HTTPS配置
配置示例:
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
tls:
- hosts:
- example.com
secretName: tls-secret
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 805.3 路径重写
配置示例:
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: example.com
http:
paths:
- path: /api(/|$)(.*)
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080六、不同类型的Ingress控制器
6.1 Nginx Ingress Controller
特点:
- 功能丰富,支持多种配置选项
- 性能稳定,适合生产环境
- 配置灵活,支持多种注解
安装命令:
bash
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install nginx-ingress ingress-nginx/ingress-nginx6.2 Traefik Ingress Controller
特点:
- 轻量级,资源占用少
- 自动发现服务
- 支持多种后端存储
安装命令:
bash
helm repo add traefik https://traefik.github.io/charts
helm install traefik traefik/traefik6.3 Contour Ingress Controller
特点:
- 基于Envoy,性能优异
- 支持gRPC和WebSocket
- 配置管理简单
安装命令:
bash
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install contour bitnami/contour七、Service和Ingress的最佳实践
7.1 Service最佳实践
- 使用ClusterIP作为默认类型:只在需要外部访问时使用NodePort或LoadBalancer
- 合理设置标签选择器:确保Service能正确关联到目标Pod
- 使用命名空间隔离:不同环境的服务使用不同的命名空间
- 设置合理的会话亲和性:根据应用需求选择合适的会话亲和性策略
- 监控Service的健康状态:定期检查Service的可用性
7.2 Ingress最佳实践
- 使用专用的Ingress控制器:根据应用需求选择合适的Ingress控制器
- 配置HTTPS:为所有外部访问启用HTTPS
- 使用路径前缀:合理规划路径前缀,避免冲突
- 设置合理的超时时间:根据应用响应时间设置合适的超时
- 监控Ingress的流量:定期分析Ingress的访问日志
- 使用IngressClassName:明确指定使用的Ingress控制器
7.3 性能优化
- 使用NodePort时选择合适的端口范围:避免端口冲突
- 配置Ingress的负载均衡算法:根据应用特性选择合适的算法
- 启用连接复用:减少连接建立的开销
- 设置合理的缓冲区大小:根据流量特性调整缓冲区大小
八、实战案例
8.1 多服务通过Ingress暴露
场景:一个应用包含前端和后端服务,通过Ingress统一暴露
配置示例:
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 80808.2 配置HTTPS和SSL证书
场景:为应用配置HTTPS访问和自动SSL证书
配置示例:
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: secure-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- secure.example.com
secretName: secure-tls
rules:
- host: secure.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: secure-service
port:
number: 80九、常见问题和解决方案
9.1 Service无法访问
问题原因:
- Pod标签不匹配
- Pod未就绪
- 网络策略限制
- 防火墙规则阻止
解决方案:
- 检查Pod标签是否与Service选择器匹配
- 查看Pod的状态,确保Pod已就绪
- 检查网络策略是否允许流量
- 检查防火墙规则是否阻止Service端口
9.2 Ingress无法访问
问题原因:
- Ingress控制器未安装
- Ingress配置错误
- 后端Service不可用
- DNS解析问题
解决方案:
- 确保Ingress控制器已正确安装
- 检查Ingress配置是否正确
- 验证后端Service是否可用
- 检查DNS解析是否正确配置
9.3 负载均衡不均匀
问题原因:
- 会话亲和性配置导致
- Pod健康状态不一致
- 负载均衡算法不适合
解决方案:
- 调整会话亲和性配置
- 确保所有Pod都处于健康状态
- 选择合适的负载均衡算法
十、课程总结
本课程详细介绍了Kubernetes中Service和Ingress的概念、配置和最佳实践。通过学习本课程,您应该能够:
- 理解Service的不同类型和工作原理
- 熟练配置和管理Service
- 理解Ingress的概念和工作原理
- 配置不同类型的Ingress规则
- 选择合适的Ingress控制器
- 应用Service和Ingress的最佳实践
Service和Ingress是Kubernetes中实现服务暴露和外部访问的核心组件,掌握它们对于构建和管理Kubernetes应用至关重要。在实际应用中,您需要根据具体场景选择合适的Service类型和Ingress配置,以确保应用的可用性、安全性和性能。
课后练习
- 创建一个ClusterIP类型的Service,关联到现有的Pod
- 创建一个NodePort类型的Service,暴露应用到节点端口
- 安装Nginx Ingress控制器
- 创建一个Ingress资源,配置基于路径的路由
- 为Ingress配置HTTPS访问
- 测试Service和Ingress的访问情况
- 分析Ingress的访问日志
通过这些练习,您将更加熟悉Service和Ingress的配置和管理,为实际应用部署打下坚实的基础。