1. 课程导入与流量入口全景
在 Kubernetes 中,Pod 的 IP 会随重建而变化,Service 虽然提供了稳定的虚拟 IP,但 ClusterIP 只在集群内部可达,NodePort 又要求每个服务占用一个高位端口。当业务需要把多个域名、多条路径统一暴露到集群外,并希望按域名和路径做路由、TLS 卸载、灰度发布时,就需要一个专门的“流量入口层”。本课程讨论的正是这一层:从 Ingress 到 Gateway API,如何把集群外部的请求可靠、可观测、可治理地送进集群内部的服务。
一、流量入口要解决的核心问题
把外部流量接入集群,本质上要回答四个问题。第一是寻址:外部客户端只知道域名或负载均衡器地址,如何映射到集群内某个 Service 的某个端口。第二是路由:同一个入口地址下,如何按 Host 头、URL 路径、请求头等条件把流量分发到不同后端。第三是安全:TLS 证书在哪里终止,是否需要在入口层做重定向、限流、鉴权。第四是可运维性:入口资源由谁定义、由谁实现、出问题时如何定位是配置错误还是后端不可用。
Kubernetes 的设计思路是把“声明”和“实现”分离。用户声明“我要把 shop.example.com/api 转发到 api-svc:8080”,而真正监听端口、加载证书、转发 TCP 连接的,是运行在集群里的数据面组件。理解这条分界线,是理解 Ingress 与 Gateway API 差异的前提。
二、Ingress 与 Gateway API 的定位差异
Ingress 是 Kubernetes 早期提供的入口抽象,它用一份 Ingress 资源描述路由规则,由 Ingress Controller(如 ingress-nginx、Traefik、HAProxy Ingress)负责实现。它的优点是简单、生态成熟;局限也很明显:路由表达能力有限,高级能力(超时、重试、流量切分、TCP/UDP 暴露)通常要靠各控制器自己的 Annotation 实现,导致配置不可移植;同时 Ingress 把“基础设施由谁管”和“应用路由由谁管”混在同一份资源里,多团队协作时容易冲突。
Gateway API 是新一代的入口标准,它把职责拆成三层角色:基础设施提供者负责 GatewayClass 和 Gateway(监听器、端口、TLS),集群运维负责把 Gateway 与命名空间绑定,应用开发者只写 HTTPRoute、GRPCRoute 等路由资源并引用 Gateway。这种面向角色的模型让权限边界更清晰,路由能力也更强,例如原生支持按权重切分流量、按请求头匹配、跨命名空间引用后端。
上图把两条路径放在同一张全景里:无论使用 Ingress 还是 Gateway API,请求都要经过“外部客户端 → 负载均衡/VIP → 数据面 → Service → Pod”这条链路;区别在于控制面声明资源的粒度和职责划分。Ingress 把入口与路由压在一份资源里,Gateway API 则把入口(Gateway)与路由(HTTPRoute)拆开,并引入 GatewayClass 表示具体实现。
三、学习路径
本课程按“先建立模型,再动手实现,最后做工程化”的顺序推进。建议的学习路径如下:
- 概念与模型:理解 Ingress、IngressClass、Ingress Controller 的关系,理解 GatewayClass、Gateway、HTTPRoute 的层级与角色模型。
- 环境搭建:准备一个可用的 Kubernetes 集群,部署 ingress-nginx 与 Envoy Gateway,验证数据面 Pod 正常运行。
- 基础路由:用 Ingress 和 HTTPRoute 分别实现基于 Host 与 Path 的路由,观察请求命中哪个后端。
- TLS 与安全:配置 Secret 证书、HTTPS 监听器、HTTP 到 HTTPS 重定向。
- 高级流量治理:权重切分、请求头匹配、超时与重试、跨命名空间引用。
- 可观测与排障:查看控制器日志、访问日志、资源状态条件,定位 404、502、503 的常见原因。
四、实验环境搭建
推荐使用 kind 或 minikube 创建本地集群,便于反复销毁重建。以下示例使用 kind 创建一个单节点集群,并部署 ingress-nginx 作为第一个数据面。示例中的版本号与镜像地址属于教学示例,实际使用时请以官方文档为准。
# 1. 创建集群(示例:kind v0.20+)
kind create cluster --name gateway-lab
# 2. 确认节点与核心组件就绪
kubectl get nodes
kubectl get pods -n kube-system
# 3. 部署 ingress-nginx(示例清单)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
# 4. 等待控制器就绪
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=180s
# 5. 查看 IngressClass
kubectl get ingressclass
部署完成后,应能看到名为 nginx 的 IngressClass,以及 ingress-nginx-controller Pod 处于 Running 状态。如果 Pod 一直处于 Pending 或 CrashLoopBackOff,优先检查节点资源、镜像拉取和端口占用。随后可以部署一个测试应用,用最小化的 Ingress 验证链路是否打通:
# 部署示例后端
kubectl create deployment web --image=nginx:1.25 --replicas=2
kubectl expose deployment web --port=80 --target-port=80
# 最小 Ingress 示例
cat <<'EOF' | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
spec:
ingressClassName: nginx
rules:
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
EOF
# 验证
kubectl get ingress web-ingress
curl -H "Host: web.example.com" http://localhost/
当 curl 返回 nginx 欢迎页时,说明“客户端 → 数据面 → Service → Pod”这条链路已经打通。如果返回 404,通常是 Host 或 Path 不匹配;返回 503,通常是 Service 没有可用 Endpoint,可用 kubectl get endpoints web 确认。
五、本课程要建立的判断力
学完本课程,你应当能够回答:给定一个“把多个域名暴露到集群外并做灰度”的需求,应该选 Ingress 还是 Gateway API;如果选 Gateway API,GatewayClass、Gateway、HTTPRoute 分别由谁维护;当请求返回 404 或 502 时,应该先看哪一层。这些判断力比记住某条命令更重要,也是后续每一章反复训练的目标。