Kubernetes Ingress 从零到一:为你的微服务打造统一的流量大门

2026/01/19 k8s 共 5462 字,约 16 分钟

Kubernetes Ingress 从零到一:为你的微服务打造统一的流量大门

在 Kubernetes 的世界里,我们通过 Service 将一组 Pod 暴露为一个网络服务。然而,Service 的 ClusterIP 类型仅在集群内部可访问,NodePortLoadBalancer 类型虽然能提供外部访问,但在管理多个服务、SSL/TLS 终结、基于域名的虚拟主机等复杂场景下显得力不从心。这时,我们就需要 Ingress 来扮演集群“统一流量入口”的角色。

一、什么是 Ingress?为什么需要它?

简单来说,Ingress 是 Kubernetes 中管理外部访问集群内部服务的 API 对象。它本身并不直接处理流量,而是通过一组你定义的规则(路由规则),将 HTTP/HTTPS 流量路由到集群内部相应的 Service。

你可以把 Ingress 想象成集群的“智能门卫”或“流量调度中心”。它的核心价值在于:

  1. 统一入口:为多个后端服务提供一个单一的访问端点(IP 或域名),无需为每个服务都分配外部 IP。
  2. 基于规则的路由:可以根据请求的 主机名(Host)URL 路径(Path) 将流量分发到不同的后端服务。
  3. 负载均衡:在多个后端 Pod 实例间自动分配流量。
  4. SSL/TLS 终结:在 Ingress 层面统一处理 HTTPS 加密和解密,减轻后端服务的负担。
  5. 成本效益:相比为每个服务使用 LoadBalancer 类型(在云平台上通常会产生额外费用),一个 Ingress 可以代理数十上百个服务,成本更低。

重要概念区分

  • Ingress: 一组路由规则的集合,是 Kubernetes 的一种资源类型(kind: Ingress)。
  • Ingress Controller: 负责实际读取并执行 Ingress 规则的 Pod。它是流量的真正处理者。常见的实现有 Nginx Ingress Controller、Traefik、HAProxy Ingress 等。你必须先部署一个 Ingress Controller,Ingress 资源才能生效。

二、Ingress 的工作原理

下图清晰地展示了 Ingress 的工作流程:

外部用户
    |
    v (发起请求: https://shop.example.com/api/orders)
    |
[ Ingress Controller (运行在Pod中) ]
    | (读取 Ingress 规则)
    | (匹配规则: Host=shop.example.com, Path=/api/orders -> Service: order-service)
    |
    v (负载均衡)
[ Service: order-service ]
    |
    v (服务发现)
[ Pods: order-app-xxxx ] [ Pods: order-app-yyyy ]
  1. 用户访问 https://shop.example.com/api/orders
  2. DNS 将该域名解析到 Ingress Controller 服务的外部 IP(可能是 LoadBalancerNodePort 类型)。
  3. 请求到达 Ingress Controller Pod。
  4. Ingress Controller 查询集群中所有的 Ingress 资源,根据定义的规则进行匹配。
  5. 匹配到规则:主机头(Host)为 shop.example.com 且路径前缀为 /api/orders 的请求,应转发到名为 order-service 的 Kubernetes Service。
  6. Ingress Controller 将请求代理到 order-serviceorder-service 再通过其负载均衡机制,将请求最终转发到某个健康的 order-app Pod 上。

三、实战:部署 Nginx Ingress Controller 并配置规则

接下来,我们通过一个完整的例子,部署最流行的 Nginx Ingress Controller,并为其配置路由规则。

步骤 1:部署 Nginx Ingress Controller

我们使用官方维护的 Helm Chart 进行部署,这是最简便的方式。

首先,添加 Helm 仓库并更新:

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.type=LoadBalancer # 根据你的环境调整,例如 Minikube 可以用 NodePort

安装完成后,查看 Ingress Controller 的 Service,获取外部访问地址:

kubectl get svc -n ingress-nginx

输出类似如下,EXTERNAL-IP 就是入口地址(如果是 pending,在云平台需要等待片刻;本地环境如 Minikube 会用 NodePort)。

NAME                                 TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.96.100.10   192.168.1.100     80:32456/TCP,443:31445/TCP   5m

步骤 2:部署示例后端应用

我们创建两个简单的 Web 应用来模拟不同的服务。

应用 A (frontend-app):

# frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: frontend-app
  template:
    metadata:
      labels:
        app: frontend-app
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80
---
# frontend-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: frontend-service
spec:
  selector:
    app: frontend-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

应用 B (backend-api):

# backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: backend-api
  template:
    metadata:
      labels:
        app: backend-api
    spec:
      containers:
      - name: http-echo
        image: hashicorp/http-echo
        args: ["-text=Hello from Backend API!"]
        ports:
        - containerPort: 5678
---
# backend-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: backend-service
spec:
  selector:
    app: backend-api
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5678

应用配置:

kubectl apply -f frontend-deployment.yaml -f frontend-service.yaml
kubectl apply -f backend-deployment.yaml -f backend-service.yaml

步骤 3:创建 Ingress 资源定义规则

现在,我们来编写 Ingress 规则,实现:

  • 访问 myapp.example.com/myapp.example.com/web 时,路由到 frontend-service
  • 访问 myapp.example.com/api 时,路由到 backend-service
# example-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    # 可选注解:指定使用的Ingress Controller类型,如果集群有多个的话
    kubernetes.io/ingress.class: "nginx"
    # 可选注解:重写路径,将 /api 前缀去掉后再转发给后端
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.example.com # 你的域名,本地测试可以配置hosts文件指向Ingress IP
    http:
      paths:
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: backend-service
            port:
              number: 80
      - path: /
        pathType: Prefix # 默认路径,放在最后
        backend:
          service:
            name: frontend-service
            port:
              number: 80

应用 Ingress 规则:

kubectl apply -f example-ingress.yaml

步骤 4:测试验证

由于我们没有真实的 myapp.example.com 域名,可以通过修改本地 hosts 文件(/etc/hostsC:\Windows\System32\drivers\etc\hosts)进行测试。

将 Ingress Controller 的外部 IP 映射到我们的域名:

# 将 192.168.1.100 替换为你的实际 EXTERNAL-IP
192.168.1.100 myapp.example.com

然后使用 curl 命令测试:

  1. 测试根路径和/web路径(应返回Nginx默认页面):
    curl http://myapp.example.com/
    curl http://myapp.example.com/web
    
  2. 测试/api路径(应返回后端API信息):
    curl http://myapp.example.com/api
    # 预期输出:Hello from Backend API!
    

你也可以在浏览器中访问 http://myapp.example.com/api 查看结果。

四、进阶配置:HTTPS 与 TLS 证书

生产环境必须使用 HTTPS。Ingress 可以很方便地配置 TLS 证书。

1. 准备 TLS 证书

假设你已有一个域名 myapp.example.com 的 TLS 证书(tls.crt)和私钥(tls.key)。

2. 创建 Kubernetes Secret 存储证书

kubectl create secret tls myapp-tls-secret \
  --cert=tls.crt \
  --key=tls.key

3. 更新 Ingress 规则,指定 TLS 配置

修改之前的 example-ingress.yaml,在 spec 部分添加 tls 字段:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls: # TLS配置部分
  - hosts:
      - myapp.example.com
    secretName: myapp-tls-secret # 指向存储证书的Secret
  rules:
  - host: myapp.example.com
    http:
      paths:
      ... # 后面的paths规则与之前相同

应用更新后,Ingress Controller 就会在 443 端口上启用 HTTPS,并自动将 HTTP 请求重定向到 HTTPS。

五、总结与最佳实践

通过本文,你已经掌握了 Kubernetes Ingress 的核心概念和部署流程。总结一下关键点:

  1. 先 Controller,后规则: 确保 Ingress Controller 已成功运行,再创建 Ingress 资源。
  2. 路径顺序: 在定义多个 path 时,更具体的路径应放在前面,通用路径(如 /)放在最后,避免被意外覆盖。
  3. 注解(Annotations)是利器: 不同的 Ingress Controller 支持丰富的注解来实现高级功能(如限流、认证、CORS、重写等),请查阅对应 Controller 的文档。
  4. 生产环境务必使用 HTTPS: 利用 tls 配置和 Secret 管理证书。对于自动证书管理,可以集成 Cert-Manager 来自动签发 Let‘s Encrypt 证书。
  5. 监控与日志: 为 Ingress Controller 配置日志收集和监控(如 Prometheus Metrics),这对于排查流量问题至关重要。

Ingress 作为 Kubernetes 集群流量的“总闸门”,是微服务架构中不可或缺的一环。熟练掌握其配置与管理,能极大地提升应用的可访问性、安全性与可维护性。现在,就去为你集群中的应用配置一个统一的访问入口吧!

文档信息

Search

    Table of Contents