k8s-(九)Ingress-nginx动态路由配置与外部访问实战
1. Ingress-nginx动态路由配置实战
第一次接触Ingress-nginx时,我完全被它复杂的配置搞懵了。直到在实际项目中踩过几次坑后,才发现它的动态路由配置其实比传统Nginx方便得多。想象一下,你有个电商平台需要根据不同商品类别做路由分发:/electronics该走A服务,/clothing该走B服务。传统方式得手动改Nginx配置然后reload,而在Kubernetes里,只需要一个YAML文件就能自动生效。
动态路由的核心在于Ingress资源的rules配置。举个实际案例,这是我上周给物流系统做的路由规则:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: logistics-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: logistics.example.com
http:
paths:
- path: /tracking/(.*)
pathType: Prefix
backend:
service:
name: tracking-service
port:
number: 8080
- path: /warehouse/(.*)
pathType: Prefix
backend:
service:
name: warehouse-service
port:
number: 8081
这个配置实现了:
- 访问logistics.example.com/tracking/xxx 自动路由到tracking-service
- 访问logistics.example.com/warehouse/xxx 自动路由到warehouse-service
关键点在于pathType的三种类型:
- Prefix:前缀匹配(最常用)
- Exact:精确匹配
- ImplementationSpecific:依赖具体实现
实测发现个坑:当同时存在多条规则时,匹配顺序是从长到短。有次配置了/api和/api/v2两条规则,结果短的先匹配了,调了半天才发现是顺序问题。
2. 外部访问的完整链路解析
很多新手会困惑:为什么配了Ingress还是无法外部访问?这得从整个请求链路说起。上周帮同事排查问题时,我画了张链路图:
外部用户 -> 节点IP:NodePort -> Ingress Controller Service -> Ingress Controller Pod -> 目标Service -> 目标Pod
关键组件协作流程:
- NodePort Service:在集群所有节点开放端口(默认30000-32767)
- Ingress Controller:持续监听Ingress资源变更
- 目标Service:需要确保selector能匹配到后端Pod
常见问题排查步骤:
- 检查NodePort是否生效:
kubectl get svc -n ingress-nginx curl <节点IP>:<NodePort> - 验证Ingress配置是否注入:
kubectl exec -n ingress-nginx <ingress-controller-pod> -- cat /etc/nginx/nginx.conf - 测试后端服务是否可达:
kubectl port-forward svc/<target-service> 8080:80 curl localhost:8080
遇到过最头疼的问题是浏览器访问一直504,最后发现是后端Pod的readinessProbe配置错误,导致流量无法到达。建议新手一定要学会用kubectl describe ingress查看事件日志。
3. 生产环境最佳实践
经过多个项目的锤炼,我总结出这些实战经验:
高可用配置方案:
- 至少部署2个Ingress Controller副本
- 使用PodAntiAffinity避免副本集中在同一节点
- 资源限制建议:
resources: limits: cpu: "2" memory: 2Gi requests: cpu: "1" memory: 1Gi
性能调优参数:
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"
SSL证书配置:
- 创建TLS secret:
kubectl create secret tls my-tls \ --cert=path/to/cert.pem \ --key=path/to/key.pem - 在Ingress中引用:
spec: tls: - hosts: - mydomain.com secretName: my-tls
曾有个项目因为没加HSTS头导致安全评分不合格,后来通过这个annotation解决:
nginx.ingress.kubernetes.io/hsts: "max-age=63072000; includeSubdomains; preload"
4. 常见故障排查指南
遇到问题别慌,按这个checklist逐步排查:
问题1:访问返回502 Bad Gateway
- 检查后端服务是否正常运行
- 查看Ingress Controller日志:
kubectl logs -n ingress-nginx <pod-name> - 验证Service的selector是否匹配Pod标签
问题2:修改Ingress后配置不生效
- 检查Ingress Controller是否监听了正确namespace
- 查看Ingress资源事件:
kubectl describe ingress <ingress-name> - 手动删除Ingress Controller Pod触发重建
问题3:端口冲突无法绑定 修改kube-apiserver配置:
spec:
containers:
- command:
- kube-apiserver
- --service-node-port-range=1-65535
然后重启kubelet:
systemctl daemon-reload
systemctl restart kubelet
有个记忆深刻的案例:客户坚持要用80端口,但修改后仍然报错。后来发现是安全组没放行,白白折腾了半天。建议新手一定要先检查网络基础配置。
5. 进阶技巧:金丝雀发布配置
通过Ingress实现灰度发布简直不要太方便。这是我常用的金丝雀配置:
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "30"
nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
nginx.ingress.kubernetes.io/canary-by-cookie: "canary"
这个配置表示:
- 30%流量走金丝雀版本
- 带X-Canary头的请求走金丝雀
- 有canary cookie的走金丝雀
配合Helm可以实现更复杂的发布策略。有次上线新功能时,我们先给内部员工开启cookie,测试无误后再逐步放量,整个过程用户完全无感知。
6. 监控与日志收集方案
生产环境必须做好监控,推荐配置:
Prometheus监控:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "10254"
关键监控指标:
- nginx_connections_total
- nginx_requests_total
- upstream_response_latency
日志收集建议:
- 将访问日志输出到stdout
- 使用Fluentd或Filebeat收集
- 重要字段:
$remote_addr - $http_host - $request - $status $body_bytes_sent - $http_referer $http_user_agent - $request_time
曾经因为没监控,直到用户投诉才发现某个路由的延迟飙升。现在我们的告警规则是这样的:
- 5分钟内5xx错误率>1%
- 平均延迟>500ms
- 带宽使用>80%阈值
更多推荐
所有评论(0)