手把手教你用Nginx Ingress Controller给K8s服务挂上域名(含Traefik/Contour对比)
2026/6/14 2:11:54 网站建设 项目流程

从零构建生产级Kubernetes Ingress网关:Nginx Controller实战与选型指南

当你第一次在Kubernetes集群中部署服务时,最令人困惑的问题之一就是:"外部用户如何访问我的应用?" 三年前我刚接触K8s时,曾天真地以为只需创建一个Deployment,世界就能自动访问我的服务。直到面对NodePort的随机端口、LoadBalancer的天价账单,以及各种Ingress方案的术语轰炸,才明白服务暴露原来是个技术活。本文将带你绕过我踩过的坑,用最实用的方式掌握Ingress的核心玩法。

1. 为什么需要Ingress Controller?

想象你正在运营一个电商平台,前端、订单、支付等服务都部署在Kubernetes集群中。如果直接用NodePort暴露服务,用户需要记住:

  • 商品服务:node1:30001
  • 支付服务:node2:30002
  • 推荐服务:node3:30003

这显然不现实。而LoadBalancer方案虽然能提供固定IP,但当你有20个微服务时,云厂商的账单会让你心跳加速。这就是Ingress Controller的价值所在——它像一位智能门卫,通过域名和路径区分流量,只需一个入口IP就能路由所有服务。

主流Ingress方案对比

方案协议层典型实现适用场景性能损耗
NodePortL4Kube-proxy开发测试环境15-20%
LoadBalancerL4云厂商SLB生产环境独立服务10-15%
IngressL7Nginx/Traefik生产环境多服务路由5-8%

提示:L4负载均衡基于IP+端口,L7则能识别HTTP/HTTPS协议内容,实现基于域名、URL路径的路由

2. 部署Nginx Ingress Controller

2.1 Helm安装方案(推荐)

对于大多数生产环境,Helm是最便捷的部署方式。以下命令将创建一个专属命名空间并安装最新稳定版:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update helm install ingress-nginx ingress-nginx/ingress-nginx \ --namespace ingress-nginx \ --create-namespace \ --set controller.replicaCount=3 \ --set controller.nodeSelector."kubernetes\.io/os"=linux \ --set defaultBackend.nodeSelector."kubernetes\.io/os"=linux

关键参数说明:

  • replicaCount=3:确保高可用,至少部署3个副本
  • nodeSelector:限定节点调度范围
  • 默认会创建LoadBalancer类型的Service(云环境自动分配公网IP)

2.2 裸金属环境部署

如果没有云厂商的LoadBalancer,可以使用HostNetwork模式直接绑定节点网络:

# nginx-ingress-daemonset.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: ingress-nginx-controller spec: template: spec: hostNetwork: true containers: - name: controller ports: - containerPort: 80 hostPort: 80 - containerPort: 443 hostPort: 443

部署后,直接访问节点IP的80/443端口即可,但要注意:

  • 需要确保节点有固定IP
  • 同一节点只能运行一个Ingress Pod
  • 建议配合nodeSelector定向调度

3. 配置Ingress路由规则

3.1 基础域名路由

假设我们有两个服务需要暴露:

  • 前端服务:frontend-svc(端口8080)
  • API服务:api-svc(端口3000)

对应的Ingress配置如下:

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: main-ingress spec: rules: - host: "shop.example.com" http: paths: - path: / pathType: Prefix backend: service: name: frontend-svc port: number: 8080 - host: "api.example.com" http: paths: - path: / pathType: Prefix backend: service: name: api-svc port: number: 3000

3.2 高级路径重写

某些前端框架可能需要路径重写:

annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 rules: - http: paths: - path: /api(/|$)(.*) backend: service: name: api-svc port: number: 3000

这会将/api/users重写为/users转发到后端服务

4. TLS证书配置

4.1 自动证书签发(Let's Encrypt)

使用cert-manager实现自动化HTTPS:

# 安装cert-manager helm install cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --version v1.8.0 \ --set installCRDs=true # 创建ClusterIssuer apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: email: admin@example.com server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: nginx

然后在Ingress中添加注解:

metadata: annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" spec: tls: - hosts: - shop.example.com secretName: shop-tls

4.2 自定义证书

如果有自购证书,可直接创建Secret:

kubectl create secret tls custom-tls \ --cert=fullchain.pem \ --key=privkey.pem \ --namespace=default

在Ingress中引用:

spec: tls: - hosts: - shop.example.com secretName: custom-tls

5. 性能优化实战技巧

5.1 调优参数示例

在Helm values.yaml中配置:

controller: config: # 保持长连接 keep-alive: "75" keep-alive-requests: "100" # 缓冲区优化 proxy-buffer-size: "16k" proxy-buffers-number: "4" # 超时设置 proxy-read-timeout: "60" proxy-send-timeout: "60"

5.2 监控与日志

启用Prometheus监控:

controller: metrics: enabled: true serviceMonitor: enabled: true

查看实时日志:

kubectl logs -n ingress-nginx \ -l app.kubernetes.io/name=ingress-nginx \ --tail=100 -f

6. 多Ingress Controller选型

当Nginx不能满足需求时,可以考虑:

Traefik优势

  • 自动服务发现
  • 内置Dashboard
  • 更轻量级

Contour特点

  • 基于Envoy构建
  • 支持gRPC原生路由
  • 更精细的流量策略

部署Traefik示例

helm install traefik traefik/traefik \ --namespace traefik \ --create-namespace \ --set ports.websecure.http.tls.enabled=true \ --set dashboard.enabled=true

选择建议:

  • 需要丰富功能选Nginx
  • 追求易用性选Traefik
  • 处理gRPC流量选Contour

7. 常见故障排查

问题1:Ingress规则不生效

  • 检查Controller日志是否有错误
  • 确认Ingress Class配置正确
  • 验证后端服务Endpoints是否健康

问题2:HTTPS证书异常

  • 检查cert-manager Pod状态
  • 查看Certificate资源事件
  • 验证DNS解析是否正确

诊断命令

# 查看Ingress状态 kubectl get ingress -o wide # 检查后端服务 kubectl describe svc my-service # 测试端口连通性 kubectl run -it --rm debug \ --image=nicolaka/netshoot -- bash curl -v http://service:port

记得第一次配置Ingress时,我因为忘记在DNS解析中添加记录,花了三小时排查"为什么访问返回404"。现在每次部署新服务,都会先确认:

  1. DNS解析是否生效
  2. Service端口是否匹配
  3. Ingress注解是否正确

这些经验让我再也没犯过同样的错误。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询