1. 为什么需要Ingress-nginx刚开始接触Kubernetes时我总被一个问题困扰如何优雅地把集群内的服务暴露给外部访问试过NodePort发现端口管理是个噩梦用过LoadBalancer又受限于云厂商的收费方案。直到遇到Ingress-nginx才发现这才是生产环境该有的解决方案。简单来说Ingress-nginx就像集群的智能门卫。想象你住在一个有多个住户的小区集群内的多个服务如果给每家都单独开个大门NodePort不仅浪费资源还不安全。Ingress-nginx相当于在小区门口设了个统一的接待处根据访客要找的人域名或路径准确引导到对应住户家。它的核心价值在于单入口管理所有外部流量通过80/443端口进入内部再根据规则分发七层路由能力能识别HTTP/HTTPS协议内容实现基于域名、URL路径的精细路由TLS终结可以在入口统一处理HTTPS加密减轻后端服务压力流量管控支持限速、重定向、灰度发布等高级功能2. 快速搭建Ingress-nginx环境2.1 安装部署实战第一次部署时踩过不少坑这里分享验证过的稳定方案。建议使用Helm 3安装比手动YAML省心很多# 添加官方仓库 helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update # 安装到ingress-nginx命名空间 helm install ingress-nginx ingress-nginx/ingress-nginx \ --namespace ingress-nginx \ --create-namespace \ --set controller.service.typeNodePort \ --set controller.service.nodePorts.http30080 \ --set controller.service.nodePorts.https30443关键参数说明controller.service.type生产环境建议用LoadBalancer测试环境用NodePortnodePorts.http/https指定固定NodePort避免端口随机分配安装完成后检查Pod状态kubectl get pods -n ingress-nginx -l app.kubernetes.io/nameingress-nginx应该看到controller容器处于Running状态。2.2 验证基础功能做个快速测试确保组件正常工作# 创建测试服务 kubectl create deployment demo --imagenginx kubectl expose deployment demo --port80 # 创建Ingress规则 cat EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: demo spec: rules: - host: demo.test http: paths: - path: / pathType: Prefix backend: service: name: demo port: number: 80 EOF本地修改hosts文件添加记录节点IP demo.test访问 http://demo.test:30080 应该能看到Nginx欢迎页。3. 多域名路由实战配置3.1 基础域名路由实际项目中经常需要同时管理多个域名。假设我们有两个服务官网服务website-svc端口80API服务api-svc端口8080对应的Ingress配置如下apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: multi-domain spec: rules: - host: www.example.com http: paths: - path: / pathType: Prefix backend: service: name: website-svc port: number: 80 - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: api-svc port: number: 8080这个配置实现了访问 www.example.com 流量到官网服务访问 api.example.com 流量到API服务自动处理路径前缀匹配和流量转发3.2 路径重写技巧有时候后端服务的路径前缀与外部暴露的不一致比如希望访问 /shop 时实际请求发送到 /。这时候就需要路径重写annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - host: store.example.com http: paths: - path: /shop(/|$)(.*) pathType: Prefix backend: service: name: shop-svc port: number: 80这个配置会把/shop → //shop/products → /products4. HTTPS安全加固方案4.1 自动证书管理现代网站没有HTTPS简直寸步难行。用Cert-Manager可以自动申请和续期Lets Encrypt证书apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: adminexample.com privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: nginx --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tls-demo annotations: cert-manager.io/cluster-issuer: letsencrypt-prod spec: tls: - hosts: - www.example.com secretName: example-tls rules: - host: www.example.com http: paths: - path: / pathType: Prefix backend: service: name: website-svc port: number: 80关键点先部署cert-manager详见官方文档创建ClusterIssuer定义证书颁发机构Ingress中通过tls字段指定域名和证书存储的Secret注解cert-manager.io/cluster-issuer触发证书申请4.2 强制HTTPS跳转有了证书后应该强制所有HTTP请求跳转到HTTPSannotations: nginx.ingress.kubernetes.io/force-ssl-redirect: true nginx.ingress.kubernetes.io/ssl-redirect: true5. 高级流量管理技巧5.1 基于权重的灰度发布需要上线新版本时可以通过权重逐步切流annotations: nginx.ingress.kubernetes.io/canary: true nginx.ingress.kubernetes.io/canary-weight: 30 spec: rules: - host: api.example.com http: paths: - path: / backend: service: name: api-v2 port: number: 8080这样30%的流量会路由到api-v2服务剩余70%继续走默认后端。5.2 按Header路由更精细化的控制可以通过请求头实现annotations: nginx.ingress.kubernetes.io/canary: true nginx.ingress.kubernetes.io/canary-by-header: X-Env nginx.ingress.kubernetes.io/canary-by-header-value: test只有包含X-Env: test头的请求才会被路由到新版本。6. 常见问题排查指南6.1 连接超时问题如果遇到504 Gateway Timeout重点检查后端服务是否健康kubectl get endpoints service-name确保有正常的Endpoint列表Ingress到Service的网络连通性kubectl port-forward service/service-name 8080:80本地访问8080端口测试nginx控制器日志kubectl logs -n ingress-nginx controller-pod-name6.2 配置不生效当修改Ingress后规则没有更新检查Ingress资源状态kubectl get ingress kubectl describe ingress name查看nginx配置是否同步kubectl exec -n ingress-nginx controller-pod-name -- cat /etc/nginx/nginx.conf常见错误包括注解拼写错误路径类型(pathType)配置不当端口定义不匹配7. 性能优化建议生产环境部署时这几个参数调优很关键controller: config: # 保持长连接 keep-alive: 75s # 工作进程数 worker-processes: 4 # 每个worker的最大连接数 max-worker-connections: 2048 resources: requests: cpu: 500m memory: 512Mi limits: cpu: 2000m memory: 2Gi监控指标建议请求吞吐量RPS平均响应时间5xx错误率证书过期时间8. 真实案例分享最近帮一个电商客户迁移到Ingress-nginx他们原有架构是10个独立域名混合使用NodePort和云负载均衡器证书手动管理经常过期迁移后实现统一入口点节省了7个云LB费用通过注解实现自动HTTPS路径重写简化了前端配置基于Header的灰度发布流程关键转折点是解决了WebSocket的长连接问题annotations: nginx.ingress.kubernetes.io/proxy-read-timeout: 3600 nginx.ingress.kubernetes.io/proxy-send-timeout: 3600 nginx.ingress.kubernetes.io/websocket-services: ws-svc
K8s实战:利用Ingress-nginx实现多域名服务暴露与流量管理
1. 为什么需要Ingress-nginx刚开始接触Kubernetes时我总被一个问题困扰如何优雅地把集群内的服务暴露给外部访问试过NodePort发现端口管理是个噩梦用过LoadBalancer又受限于云厂商的收费方案。直到遇到Ingress-nginx才发现这才是生产环境该有的解决方案。简单来说Ingress-nginx就像集群的智能门卫。想象你住在一个有多个住户的小区集群内的多个服务如果给每家都单独开个大门NodePort不仅浪费资源还不安全。Ingress-nginx相当于在小区门口设了个统一的接待处根据访客要找的人域名或路径准确引导到对应住户家。它的核心价值在于单入口管理所有外部流量通过80/443端口进入内部再根据规则分发七层路由能力能识别HTTP/HTTPS协议内容实现基于域名、URL路径的精细路由TLS终结可以在入口统一处理HTTPS加密减轻后端服务压力流量管控支持限速、重定向、灰度发布等高级功能2. 快速搭建Ingress-nginx环境2.1 安装部署实战第一次部署时踩过不少坑这里分享验证过的稳定方案。建议使用Helm 3安装比手动YAML省心很多# 添加官方仓库 helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update # 安装到ingress-nginx命名空间 helm install ingress-nginx ingress-nginx/ingress-nginx \ --namespace ingress-nginx \ --create-namespace \ --set controller.service.typeNodePort \ --set controller.service.nodePorts.http30080 \ --set controller.service.nodePorts.https30443关键参数说明controller.service.type生产环境建议用LoadBalancer测试环境用NodePortnodePorts.http/https指定固定NodePort避免端口随机分配安装完成后检查Pod状态kubectl get pods -n ingress-nginx -l app.kubernetes.io/nameingress-nginx应该看到controller容器处于Running状态。2.2 验证基础功能做个快速测试确保组件正常工作# 创建测试服务 kubectl create deployment demo --imagenginx kubectl expose deployment demo --port80 # 创建Ingress规则 cat EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: demo spec: rules: - host: demo.test http: paths: - path: / pathType: Prefix backend: service: name: demo port: number: 80 EOF本地修改hosts文件添加记录节点IP demo.test访问 http://demo.test:30080 应该能看到Nginx欢迎页。3. 多域名路由实战配置3.1 基础域名路由实际项目中经常需要同时管理多个域名。假设我们有两个服务官网服务website-svc端口80API服务api-svc端口8080对应的Ingress配置如下apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: multi-domain spec: rules: - host: www.example.com http: paths: - path: / pathType: Prefix backend: service: name: website-svc port: number: 80 - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: api-svc port: number: 8080这个配置实现了访问 www.example.com 流量到官网服务访问 api.example.com 流量到API服务自动处理路径前缀匹配和流量转发3.2 路径重写技巧有时候后端服务的路径前缀与外部暴露的不一致比如希望访问 /shop 时实际请求发送到 /。这时候就需要路径重写annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - host: store.example.com http: paths: - path: /shop(/|$)(.*) pathType: Prefix backend: service: name: shop-svc port: number: 80这个配置会把/shop → //shop/products → /products4. HTTPS安全加固方案4.1 自动证书管理现代网站没有HTTPS简直寸步难行。用Cert-Manager可以自动申请和续期Lets Encrypt证书apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: adminexample.com privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: nginx --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tls-demo annotations: cert-manager.io/cluster-issuer: letsencrypt-prod spec: tls: - hosts: - www.example.com secretName: example-tls rules: - host: www.example.com http: paths: - path: / pathType: Prefix backend: service: name: website-svc port: number: 80关键点先部署cert-manager详见官方文档创建ClusterIssuer定义证书颁发机构Ingress中通过tls字段指定域名和证书存储的Secret注解cert-manager.io/cluster-issuer触发证书申请4.2 强制HTTPS跳转有了证书后应该强制所有HTTP请求跳转到HTTPSannotations: nginx.ingress.kubernetes.io/force-ssl-redirect: true nginx.ingress.kubernetes.io/ssl-redirect: true5. 高级流量管理技巧5.1 基于权重的灰度发布需要上线新版本时可以通过权重逐步切流annotations: nginx.ingress.kubernetes.io/canary: true nginx.ingress.kubernetes.io/canary-weight: 30 spec: rules: - host: api.example.com http: paths: - path: / backend: service: name: api-v2 port: number: 8080这样30%的流量会路由到api-v2服务剩余70%继续走默认后端。5.2 按Header路由更精细化的控制可以通过请求头实现annotations: nginx.ingress.kubernetes.io/canary: true nginx.ingress.kubernetes.io/canary-by-header: X-Env nginx.ingress.kubernetes.io/canary-by-header-value: test只有包含X-Env: test头的请求才会被路由到新版本。6. 常见问题排查指南6.1 连接超时问题如果遇到504 Gateway Timeout重点检查后端服务是否健康kubectl get endpoints service-name确保有正常的Endpoint列表Ingress到Service的网络连通性kubectl port-forward service/service-name 8080:80本地访问8080端口测试nginx控制器日志kubectl logs -n ingress-nginx controller-pod-name6.2 配置不生效当修改Ingress后规则没有更新检查Ingress资源状态kubectl get ingress kubectl describe ingress name查看nginx配置是否同步kubectl exec -n ingress-nginx controller-pod-name -- cat /etc/nginx/nginx.conf常见错误包括注解拼写错误路径类型(pathType)配置不当端口定义不匹配7. 性能优化建议生产环境部署时这几个参数调优很关键controller: config: # 保持长连接 keep-alive: 75s # 工作进程数 worker-processes: 4 # 每个worker的最大连接数 max-worker-connections: 2048 resources: requests: cpu: 500m memory: 512Mi limits: cpu: 2000m memory: 2Gi监控指标建议请求吞吐量RPS平均响应时间5xx错误率证书过期时间8. 真实案例分享最近帮一个电商客户迁移到Ingress-nginx他们原有架构是10个独立域名混合使用NodePort和云负载均衡器证书手动管理经常过期迁移后实现统一入口点节省了7个云LB费用通过注解实现自动HTTPS路径重写简化了前端配置基于Header的灰度发布流程关键转折点是解决了WebSocket的长连接问题annotations: nginx.ingress.kubernetes.io/proxy-read-timeout: 3600 nginx.ingress.kubernetes.io/proxy-send-timeout: 3600 nginx.ingress.kubernetes.io/websocket-services: ws-svc