Kubernetes Ingress实战:从基础配置到HTTPS高级应用
1. 项目概述
在Kubernetes集群中,Ingress作为服务发现的关键组件,承担着外部流量路由和负载均衡的重要职责。不同于传统的Service资源,Ingress提供了更灵活的路由规则定义能力,能够基于主机名、路径等条件将外部请求分发到不同的后端服务。本实战指南将深入解析Ingress的核心工作机制,并通过完整示例演示从基础配置到高级功能的实现过程,特别是HTTPS安全连接的配置细节。
作为K8s网络体系中的第七层代理,Ingress解决了生产环境中常见的几个痛点问题:
- 单个IP暴露多个服务
- 基于域名的路由分流
- 集中式SSL证书管理
- 统一入口的访问控制
2. 核心组件解析
2.1 Ingress Controller选型
Ingress功能实际由Controller实现,主流方案包括:
- Nginx Ingress Controller:最成熟的方案,支持定制注解
- Traefik:动态配置更新快,适合微服务架构
- HAProxy:高性能负载均衡,适合高并发场景
- ALB Ingress Controller:AWS原生集成方案
以Nginx Ingress为例,其架构包含:
- 监听K8s API的Control Loop
- 生成Nginx配置的Translator
- 动态加载配置的Nginx进程
2.2 Ingress资源定义
典型Ingress YAML包含三大核心配置:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: demo-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: tls: - hosts: - demo.example.com secretName: tls-secret rules: - host: demo.example.com http: paths: - path: /api pathType: Prefix backend: service: name: api-service port: number: 80关键字段说明:
rules.host: 虚拟主机域名paths.backend: 服务关联配置tls.secretName: SSL证书密钥
3. 完整部署实战
3.1 基础环境准备
先决条件:
- 运行中的K8s集群(v1.19+)
- kubectl配置正确上下文
- Helm工具(v3.0+)
安装Nginx Ingress Controller:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm install ingress-nginx ingress-nginx/ingress-nginx \ --namespace ingress-nginx \ --create-namespace \ --set controller.replicaCount=2验证安装:
kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx3.2 部署示例应用
创建测试Deployment和Service:
# api-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: api-server spec: replicas: 3 selector: matchLabels: app: api template: metadata: labels: app: api spec: containers: - name: api image: nginx:alpine ports: - containerPort: 80 --- # api-service.yaml apiVersion: v1 kind: Service metadata: name: api-service spec: selector: app: api ports: - protocol: TCP port: 80 targetPort: 80应用配置:
kubectl apply -f api-deployment.yaml -f api-service.yaml3.3 Ingress资源配置
创建基础Ingress路由:
# basic-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: api-ingress spec: rules: - host: api.demo.com http: paths: - path: / pathType: Prefix backend: service: name: api-service port: number: 80应用配置后测试:
kubectl apply -f basic-ingress.yaml # 获取Ingress外部IP INGRESS_IP=$(kubectl get svc ingress-nginx-controller -n ingress-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}') # 测试访问 curl -H "Host: api.demo.com" http://$INGRESS_IP4. HTTPS高级配置
4.1 证书准备
使用Let's Encrypt生成证书(示例):
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout tls.key -out tls.crt \ -subj "/CN=api.demo.com/O=demo"创建K8s Secret:
kubectl create secret tls tls-secret \ --cert=tls.crt \ --key=tls.key4.2 安全Ingress配置
更新Ingress启用HTTPS:
# tls-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: secure-ingress spec: tls: - hosts: - api.demo.com secretName: tls-secret rules: - host: api.demo.com http: paths: - path: / pathType: Prefix backend: service: name: api-service port: number: 80验证HTTPS访问:
curl -k https://api.demo.com --resolve api.demo.com:443:$INGRESS_IP4.3 自动证书管理
使用Cert-Manager实现自动化:
- 安装Cert-Manager:
helm install cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --version v1.8.0 \ --set installCRDs=true- 配置ClusterIssuer:
# letsencrypt-issuer.yaml apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: admin@demo.com privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: nginx- 更新Ingress注解:
annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod"5. 高级路由策略
5.1 路径重写配置
处理前端路由场景:
annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 rules: - http: paths: - path: /web(/|$)(.*) backend: service: name: web-service port: number: 805.2 流量切分配置
实现金丝雀发布:
# canary-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: api-canary annotations: nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "20" spec: rules: - host: api.demo.com http: paths: - path: / backend: service: name: api-service-v2 port: number: 805.3 跨域配置
支持前端跨域访问:
annotations: nginx.ingress.kubernetes.io/enable-cors: "true" nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS" nginx.ingress.kubernetes.io/cors-allow-origin: "*"6. 性能优化实践
6.1 连接参数调优
调整Nginx参数:
annotations: nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" nginx.ingress.kubernetes.io/proxy-body-size: "20m" nginx.ingress.kubernetes.io/upstream-keepalive-connections: "100"6.2 负载均衡策略
配置会话保持:
annotations: nginx.ingress.kubernetes.io/affinity: "cookie" nginx.ingress.kubernetes.io/session-cookie-name: "route" nginx.ingress.kubernetes.io/session-cookie-expires: "172800"6.3 监控集成
暴露Prometheus指标:
controller: metrics: enabled: true serviceMonitor: enabled: true7. 故障排查指南
7.1 常见问题分析
503 Service Unavailable
- 检查后端服务Endpoint状态:
kubectl get endpoints <service-name> - 验证Service selector匹配Pod标签
- 检查后端服务Endpoint状态:
404 Not Found
- 检查Ingress中
host和path配置 - 验证Controller日志:
kubectl logs -n ingress-nginx <controller-pod>
- 检查Ingress中
SSL证书错误
- 检查Secret是否存在:
kubectl get secret tls-secret - 验证证书有效期:
openssl x509 -in tls.crt -noout -dates
- 检查Secret是否存在:
7.2 诊断命令集合
获取Ingress事件:
kubectl describe ingress <ingress-name>检查Nginx配置:
kubectl exec -n ingress-nginx <controller-pod> -- cat /etc/nginx/nginx.conf实时监控日志:
kubectl logs -f -n ingress-nginx <controller-pod>8. 生产环境建议
高可用部署
- 至少部署2个Controller副本
- 使用PodAntiAffinity分散节点分布
- 配置HPA自动扩缩容
安全加固
- 限制Controller权限(RBAC)
- 启用ModSecurity WAF规则
- 定期轮换TLS证书
性能考量
- 根据QPS调整worker_processes
- 启用动态TLS记录大小
- 优化内核网络参数
版本管理
- 保持Controller版本与K8s版本兼容
- 测试环境先行验证配置变更
- 使用GitOps管理Ingress配置