一、为什么我的Ingress总是不工作?
最近在帮朋友排查一个Kubernetes集群的问题,他的服务通过Ingress暴露后总是返回404。这让我想起刚接触Kubernetes时,自己也经常被Ingress配置搞得焦头烂额。今天我们就来聊聊这些常见的坑,以及如何优雅地避开它们。
先来看一个典型的错误配置示例(使用Nginx Ingress Controller):
# 错误示例:缺少关键注解导致路由失效
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: broken-ingress
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
这个配置看起来很正常对吧?但实际会出问题,因为它缺少了关键的nginx.ingress.kubernetes.io/rewrite-target注解。当你的服务路径和Ingress路径不一致时,这个注解必不可少。
二、Ingress控制器的核心配置要点
2.1 注解的正确使用方式
不同的Ingress控制器有不同的注解系统。以Nginx Ingress为例,这些注解就像给控制器的小纸条,告诉它该如何处理请求:
# 正确配置示例:带注解的Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: working-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /api/(.*)
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
这里有几个关键点:
rewrite-target确保路径重写正确ssl-redirect强制HTTPS跳转- 正则捕获组
(.*)配合$1使用
2.2 多路径配置的陷阱
很多人在配置多个路径时会遇到路由冲突问题:
# 有问题的多路径配置
paths:
- path: /static
pathType: Prefix
backend: {...}
- path: /static/images
pathType: Prefix
backend: {...}
这种配置会导致/static/images的请求可能被第一个路径规则捕获。正确的做法是:
# 正确的多路径配置顺序
paths:
- path: /static/images
pathType: Prefix
backend: {...}
- path: /static
pathType: Prefix
backend: {...}
记住:更具体的路径要放在前面!
三、TLS配置的常见坑
SSL证书配置不当会导致各种奇怪的问题。来看一个完整的TLS配置示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-demo
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 443
常见问题包括:
- 忘记创建对应的Secret
- 证书过期没有自动续期
- 主机名不匹配(证书是给www域名但访问的是非www)
四、调试Ingress问题的实用技巧
当Ingress不工作时,可以按照这个检查清单排查:
- 检查Ingress控制器Pod是否运行正常:
kubectl get pods -n ingress-nginx
- 查看Ingress控制器的日志:
kubectl logs -n ingress-nginx <ingress-pod-name>
- 检查Ingress资源状态:
kubectl describe ingress my-ingress
- 验证Service是否存在且Endpoints正确:
kubectl get svc,ep my-service
- 使用临时Pod进行网络测试:
kubectl run -it --rm debug --image=busybox -- sh
wget -O- http://my-service
五、高级配置场景解析
5.1 流量切分与金丝雀发布
通过注解可以实现精细的流量控制:
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "20"
这会将20%的流量路由到该Ingress,非常适合渐进式发布。
5.2 自定义错误页面
当后端服务不可用时,可以配置友好的错误页:
annotations:
nginx.ingress.kubernetes.io/default-backend: default-http-backend
nginx.ingress.kubernetes.io/custom-http-errors: "503,502"
六、最佳实践总结
经过多次踩坑,我总结了这些经验:
- 始终检查
kubectl describe ingress的输出 - 使用注解时要查阅对应控制器的文档
- 复杂的路由规则先在测试环境验证
- 监控Ingress控制器的指标和日志
- 考虑使用Service Mesh作为更高级的流量管理方案
记住,Kubernetes的配置就像做菜 - 看起来简单的食谱,细节决定成败。希望这些经验能帮你少走弯路!
评论