想象你走进一座巨大的地铁换乘枢纽。站厅里没有检票员逐人确认目的地,但天花板上挂满了清晰的指示牌:“3号线站台 →”“A出口 → 写字楼”“B出口 → 高铁站”。人流根据指示牌,自动分流到对应的列车与出口。这些指示牌本身不会移动任何人,但它们定义了“谁该往哪走”。Kubernetes 集群的边界上,也有这样一套指路牌系统——它就是 Ingress。 在 Kubernetes 世界里,每个 Pod 像一座独立的“小房子”,Service 是房子门前的“巷道路标”,让集群内部能互相找到。可当外部用户要访问你的 AI 服务时,光靠巷道路标不够——他需要的是城市级的交通枢纽。Ingress 就是这座枢纽:它站在集群门口,看一眼访客请求里的“目的地”(域名和路径),再把访客准确引导到对应的 Service 门口。而真正站在门口执行引导的“工作人员”,叫 Ingress Controller。 这篇文章会带你从零理解 Ingress 的工作原理、Controller 选型、路由规则、HTTPS 安全接入、网络策略,最后用一个 AI 推理服务的实战案例把知识串联起来。学完后,你就能为任何 AI 服务设计一套清晰、安全、可扩展的对外网络方案。
对 AI 从业者而言,Ingress 是模型服务从“能跑”走向“能对外提供服务”的必经之门。掌握它,你就能独立完成 AI 应用的部署上线、流量治理与安全加固。
目录
可视化演示
本节配有交互动效(进入视口后自动加载,约 3KB)。
地铁站台初识:什么是 Ingress
走进一座地铁站,站厅里最显眼的不是列车,而是那些悬挂的指示牌:“开往机场的 3 号线”“通往高铁站的 A 出口”。这些指示牌不会推动任何人,但所有乘客都依赖它们完成换乘。Kubernetes 集群的边界上,Ingress 就是这块指示牌。它本身只是 API 资源对象,静静描述着“来自哪个域名的哪个路径,应该去哪个 Service”。
Ingress 不是 Service 的替代品,而是它的“上级引导系统”。Service 像是在每栋楼门口写“这里住着张三”的铭牌,解决的是集群内部服务发现;Ingress 则是整个园区的大门口闸机,站在流量进入的第一站,根据访客要拜访的“部门”(域名 + 路径),把他指向正确的楼栋(Service)。如果说 Service 是四层负载均衡(基于 IP 和端口),Ingress 就是七层负载均衡(基于 HTTP 内容)。
一个最基础的 Ingress 规则,可以抽象成下面的映射关系:
回到地铁比喻:指示牌再清晰,也得有广播系统告知乘客。Ingress 是那块“写好的指示牌”,而真正执行指路的广播员是 Ingress Controller——下一节我们就去见见这位调度员。
- 路由映射Ingress 核心动作是“查表”,输入是访客请求的 host 与 path。
- 优先级排序当多条规则同时命中时,host 精确匹配 > path 精确 > path 前缀,避免歧义。
换乘调度员:Ingress Controller 选型
指示牌不会自动喊话,地铁站需要一位“换乘调度员”——他站在站厅中央,读着指示牌上的规则,把每一位乘客精准送上正确的列车。在 Kubernetes 里,这位调度员就是 Ingress Controller。它是一个独立运行的 Pod/Deployment,持续监听集群中 Ingress 资源的变化,并把规则翻译成实际的反向代理配置。
选型时,最常见的候选人有两个。第一位是 Ingress-NGINX,它是社区最主流的方案,基于 NGINX 实现七层路由,生态成熟、资料丰富、性能稳定,适合大多数生产环境。第二位是 Traefik,它配置更简洁,原生支持动态更新和中间件(如限流、熔断),适合微服务架构和云原生场景。如果集群跑在云上,还可以选用云厂商的 Ingress 方案(如阿里云 ALB Ingress),它们与云负载均衡深度集成,但会绑定厂商。
选型时看三点:一是团队熟悉度,NGINX 背景的团队选 Ingress-NGINX 上手最快;二是功能需求,需要灰度发布、自定义插件时看 Traefik;三是云环境绑定程度,纯粹自建集群则优先开源方案。对于 AI 服务来说,Ingress-NGINX 配合注解(annotation)足以完成 90% 的流量治理需求。
Controller 的工作本质可以这样描述:
站厅里有了调度员,乘客开始有序进站。但调度员需要一套清晰的“指路牌规则”,才能知道每个人该去哪——这就是 Ingress 路由规则的编写艺术。
- 监听资源Controller 通过 API Server 持续 watch Ingress 对象的创建、更新、删除。
- 生成配置把 Ingress 规则翻译成 NGINX/Traefik 的 server/location 配置。
- 路由流量外部请求到达 Controller 后,按其配置转发到对应 Service。
指路牌规则:host 与 path 路由
地铁枢纽的指路牌不能只写“往左走”,得写明“去机场的乘客请上 3 号线,去高铁站的乘客请走 A 出口”。Ingress 路由规则同样需要两把钥匙:host(域名)和 path(路径)。host 决定“这是哪个网站的请求”,path 决定“这个网站里的哪个功能”。两者组合后,指向一个 backend——也就是真正的 Service。
实际编写时,一个典型的 Ingress 配置长这样:
这段配置的意思很直白:当访客访问 ai.example.com/api/xxx 时,进入 ai-api-service;访问 ai.example.com/ui/xxx 时,进入 ai-ui-service。rewrite-target 注解把路径中的 /api 前缀剥掉,让后端服务收到的请求路径干净如初。路径匹配规则可以抽象为:
指路牌越来越清晰,但还有一个关键问题:访客直接乘坐的“列车”会经过一段加密隧道,只有通过安检的乘客才能进入站台——这就是 HTTPS 与 TLS 的世界。
- host 匹配请求的
Host头必须与规则中的host完全一致。 - path 匹配请求 URI 的路径部分命中 path 模式(精确或前缀)。
- backend 指向命中后把流量转发给对应 Service 的指定端口。
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ai-demo-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2spec: rules: - host: ai.example.com http: paths: - path: /api(/|$)(.*) pathType: ImplementationSpecific backend: service: name: ai-api-service port: number: 8080 - path: /ui(/|$)(.*) pathType: ImplementationSpecific backend: service: name: ai-ui-service port: number: 80
安检闸机:TLS 与 HTTPS 接入
当地铁站升级安保,所有乘客进站前都要通过安检闸机:刷证件、验身份、确认是本人。HTTPS 接入集群时,TLS 终止就是这台安检闸机——它在 Ingress Controller 上完成证书校验和加密解密,把 HTTPS 明文化为集群内部的 HTTP 流量。原始请求经过控制器转发到后端,解密后的流量在集群内安全传输。
配置 TLS 需要两个步骤。第一步,把证书和私钥存入 Kubernetes Secret;第二步,在 Ingress 的 tls 字段中引用这个 Secret,并声明哪些 host 使用该证书。典型配置片段如下:
TLS 终止的业务含义是“边缘解密,内部明文”。外部访客看到的是 https://,而集群内部仍然用普通 HTTP 通信。这样设计既减少了后端服务的加解密开销,也让证书管理集中在入口处。可以用一个简洁的关系描述:
过了安检,乘客进入站台。但要防止乘客走错车厢、进入禁区,还需要车厢隔离门——这就是集群内部的网络策略。
- 证书存储证书与私钥以 Secret 形式保存在集群中。
- TLS 声明Ingress 的 tls 段绑定 host 与 Secret。
- 链路解密Ingress 终止 TLS 后,内部转发使用 HTTP。
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ai-demo-ingressspec: tls: - hosts: - ai.example.com secretName: ai-tls-secret rules: - host: ai.example.com http: paths: - path: / pathType: Prefix backend: service: name: ai-api-service port: number: 8080
车厢隔离门:NetworkPolicy 网络策略
想象地铁车厢之间有一道道隔离门:只有持特定车票的乘客才能进入对应车厢。这就是 NetworkPolicy 的角色——它不是 Ingress 的替代,而是 Ingress 的“内层防线”。Ingress 管“谁能进站”,NetworkPolicy 管“进站后能去哪节车厢”。在 AI 服务架构中,推理服务可能需要访问数据库,但绝不希望前端直接访问数据库 Pod。此时用 NetworkPolicy 把数据库“隔离”起来。
一个典型的网络策略如下:
这个策略的含义是:只有带有 app=ai-api 标签的 Pod 才能访问 MySQL 的 3306 端口。其他所有 Pod(包括外部流量)一律被拒绝。这就是“默认拒绝、按需放行”的安全模型。它的决策逻辑可以表示为:
隔离门装好了,站台秩序井然。现在,让我们把这些零散的知识组合起来,来一场真正的“实战出发”。
- 选择目标
podSelector决定策略保护哪些 Pod。 - 来源限制
from内声明允许的来源(标签选择器或命名空间)。 - 端口限制
ports限定允许的协议与端口。
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: db-allow-only-apispec: podSelector: matchLabels: app: mysql policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: ai-api ports: - protocol: TCP port: 3306
实战出发:AI 服务对外暴露全流程
所有的知识最终都要串联成一条真实路线。想象你是一位 AI 工程师,刚训练好一个图像识别模型,要把它部署到 Kubernetes 并对外提供服务。你设计了两个入口:/api 走模型推理接口,/ui 走演示前端页面;同时要求全程 HTTPS,数据库只能被推理服务访问。这就是 Ingress + TLS + NetworkPolicy 的联合演练。
部署流程可以拆解为四步:第一步,创建推理服务与前端服务的 Deployment/Service;第二步,准备域名证书并创建 Secret;第三步,编写 Ingress 规则,将 ai.example.com/api 指向推理服务,将 /ui 指向前端;第四步,编写 NetworkPolicy,只允许推理服务访问数据库。整个链路如下:
最佳实践方面,建议用 ingressClassName 指定 Controller,避免集群中多个 Controller 冲突;生产环境优先使用 cert-manager 自动签发证书;网络策略秉持“默认拒绝”原则逐步放行;排障时用 kubectl describe ingress 和 kubectl logs 查看问题。这条完整的“地铁线路”就此贯通——从入站安检到车厢隔离,AI 服务的对外网络方案一目了然。
- 入口路由Ingress 按 host/path 分发流量。
- 安全加密TLS 在入口完成解密。
- 内网隔离NetworkPolicy 限制 Pod 间访问。
AI 应用场景
AI 推理服务多租户网关
阶段:模型部署上线与流量治理
解决的问题:传统方式是给每个模型单独分配公网 IP 和 LoadBalancer,成本高、管理混乱。Ingress 用一个入口域名(如 api.example.com),通过不同 path(/model-a、/model-b)把请求路由到不同模型服务,还可在 Controller 层配置限流与灰度。
具体案例:某 AI 公司同时上线三个模型:GPT 类对话、图像生成、语音识别。它们分别运行在不同 Deployments 中。通过 Ingress 配置三条 path 规则,外部客户只用一个 API 域名即可访问全部模型,配合 Nginx Ingress 的 limit-rps 注解做按模型限流,保障高优先级模型的服务质量。
数据隔离的微服务安全管控
阶段:服务间通信与安全加固
解决的问题:AI 系统中,模型推理服务需要访问特征数据库,但前端应用不应直达数据层。只靠 Ingress 无法控制集群内 Pod 之间的流量,必须配合 NetworkPolicy 建立“默认拒绝、最小授权”的内网边界。
具体案例:某推荐系统包含 feature-store、recall-api、rank-model 三个服务。安全团队用 NetworkPolicy 声明:rank-model 只能访问 feature-store 的 8080 端口,recall-api 只能访问 rank-model 的 8501 端口。任何横向移动请求都会被集群网络拒绝,即使某 Pod 被攻破,攻击面也被限制在单节点。
HTTPS 自动化的模型市场平台
阶段:模型对外发布与合规
解决的问题:模型市场需要为每个模型提供独立的 HTTPS 访问地址,手动申请证书并维护是巨大负担。Ingress 配合 cert-manager 实现证书自动签发与续期,让每个模型域名自动获得 TLS 证书。
具体案例:某企业内部模型平台为每个团队提供 team-x.model.example.com 子域名。每次创建新 Ingress 时,cert-manager 自动向 Let's Encrypt 申请证书并注入 Secret;用户访问时全程 HTTPS,证书到期前自动续期,平台零人工干预。
Python 演示
import reimport timefrom dataclasses import dataclassfrom typing import List, Optional # 模拟 k8s Service 后端@dataclassclass BackendService: name: str port: int # 模拟一条 Ingress path 规则@dataclassclass PathRule: path: str path_type: str # Prefix 或 Exact backend: BackendService # 模拟一条 Ingress host 规则@dataclassclass HostRule: host: str paths: List[PathRule] class IngressSimulator: def __init__(self) -> None: self.rules: List[HostRule] = [] self.default_backend: Optional[BackendService] = None def add_rule(self, rule: HostRule) -> None: self.rules.append(rule) def match(self, host: str, path: str) -> Optional[BackendService]: best_score = -1 result: Optional[BackendService] = None for rule in self.rules: if rule.host != host: continue # host 不匹配则跳过 for pr in rule.paths: if pr.path_type == "Exact" and pr.path == path: score = 3 # 精确匹配得分最高 elif pr.path_type == "Prefix" and path.startswith(pr.path): score = 2 # 前缀匹配次之 else: continue if score > best_score: best_score = score result = pr.backend return result def route(self, host: str, path: str) -> str: backend = self.match(host, path) if backend is None: return "404 Not Found; no rule matched" return f"200 OK; -> {backend.name}:{backend.port}" def main() -> None: sim = IngressSimulator() sim.add_rule(HostRule( host="ai.example.com", paths=[ PathRule("/api", "Prefix", BackendService("ai-api-service", 8080)), PathRule("/ui", "Prefix", BackendService("ai-ui-service", 80)), ], )) sim.add_rule(HostRule( host="test.example.com", paths=[ PathRule("/api", "Exact", BackendService("ai-test-service", 9090)), ], )) requests = [ ("ai.example.com", "/api/v1/predict"), ("ai.example.com", "/ui/index.html"), ("bad.example.com", "/api/v1/predict"), ("test.example.com", "/api"), ("test.example.com", "/api/v2"), ] for host, path in requests: start = time.perf_counter() resp = sim.route(host, path) cost_ms = (time.perf_counter() - start) * 1000 print(f"REQ {host}{path}") print(f"RESP {resp} ({cost_ms:.2f} ms)\n") if __name__ == "__main__": main()
@dataclass用 Python 数据类模拟 Kubernetes 资源对象,让代码结构清晰。self.rules: List[HostRule] = []保存所有 Ingress 规则,相当于集群中的 Ingress 资源列表。if rule.host != host: continue模拟 host 完全匹配:域名不一致直接跳过。elif pr.path_type == "Prefix" and path.startswith(pr.path)模拟 path 前缀匹配(如/api命中/api/v1/predict)。score = 3` / `score = 2用得分模拟 Ingress 的匹配优先级:精确 > 前缀。def route(...)模拟 Ingress Controller 的请求分发入口,返回后端地址或 404。
常见误区
误区“我创建了一个 Ingress 对象,集群就能自动路由了,不用装任何额外组件。”
正解Ingress 只是一份“指路牌声明”,本身没有任何执行能力。真正干活的是 Ingress Controller——一个独立部署的 Pod。就像地铁里的指示牌不会自己喊话,必须有广播员(Controller)把它念出来。没有 Controller 的集群里创建 Ingress,kubectl 不报错,但流量完全不会路由。
为何常见:初学者看到文档里“创建 Ingress 即可暴露服务”,误以为 Ingress 是自带动能的组件,忽略了 Controller 是独立安装的这一前提。
误区“Ingress 也就是个带域名的 LoadBalancer,跟 NodePort 区别不大。”
正解Ingress 是七层(HTTP/HTTPS)负载均衡,它能识别域名、路径、请求头甚至 Cookie;而四层负载均衡只认 IP 和端口。最直观的区别是:Ingress 能把同一个 IP 的请求按 Host 头分发到不同 Service,四层方案做不到。相当于地铁站的指路牌能区分“去机场的人”和“去高铁站的人”,而普通电梯只知道把人送到某楼层。
为何常见:因为 Service 的 LoadBalancer 类型看起来也有类似“入口”的作用,容易混淆四层与七层的分工。
误区“Ingress 配了证书,后端 Service 也得配证书,否则链路不安全。”
正解恰恰相反,TLS 终止(TLS termination)恰恰意味着“在 Ingress 处解密,内部走明文 HTTP”。这是设计选择而非缺陷:集群内部网络通常是受信网络,明文传输可以降低后端加解密开销。就像地铁安检在入口做一次证件核验,进入站台后无需每个车厢再查一遍身份证;内部通信依旧快速高效。
为何常见:对“加密链路”的直觉理解是“全程加密”,但云原生架构更强调“边缘加密、内部可信”的边界模型。
误区“有了 NetworkPolicy 就不需要 Ingress 了,反正都控制访问。”
正解两者分工完全不同。Ingress 是站在集群入口的“门卫”,管外部流量如何进来;NetworkPolicy 是站台内的“隔离门”,管 Pod 之间谁能互访。Ingress 管不了 Pod 间的横向流量,NetworkPolicy 也管不了域名路径路由。正确的姿势是“Ingress 负责入口路由,NetworkPolicy 负责内部最小授权”,二者互补叠加以构建纵深防御。
为何常见:两者名字里都有“网络访问控制”的影子,初学者容易把它们划上等号。
误区“pathType 随便写,反正都是前缀匹配,`/api` 肯定能命中 `/api/v1/predict`。”
正解pathType 有 Exact、Prefix、ImplementationSpecific 三种,语义差别很大。Exact 完全等值匹配,/api 不会命中 /api/v1/predict;Prefix 也要注意边界规则——/api 是否能命中 /api/v1 取决于 Controller 的具体实现。此外,Nginx Ingress 还会受 rewrite-target 注解影响。建议写规则时用 kubectl describe ingress 检查实际生成的规则,或直接使用 ImplementationSpecific 加正则。
为何常见:直觉上认为路径天然带“模糊匹配”,但 Kubernetes 对 pathType 的定义非常严谨,差一点就匹配不上。
面试题
Q1. 在 Kubernetes 中,Ingress 资源本身的主要作用是什么?
- A.直接转发流量到后端 Pod
- B.声明流量路由规则的 API 对象← 正确答案
- C.替代 Service 完成集群负载均衡
- D.自动创建云负载均衡器
答案:B。Ingress 只是一个声明式 API 对象,描述路由规则,本身不转发流量(选项 A 错)。它需要 Ingress Controller 执行,所以称“路由规则声明”最准确。Ingress 不替代 Service,而是依赖 Service 做 backend;它也不直接创建云负载均衡器,那是 Controller 或云提供商的行为。
Q2. 关于 Ingress 与 Service 的关系,下列哪种说法正确?
- A.Ingress 可以完全替代 Service
- B.Service 负责四层负载均衡,Ingress 负责七层路由← 正确答案
- C.Ingress 只支持 TCP/UDP 转发
- D.Service 必须暴露 NodePort 才能被 Ingress 使用
答案:B。Ingress 工作在七层(HTTP/HTTPS),基于域名与路径路由,Service 默认是四层负载均衡。两者是“入口路由”与“服务暴露”的分工关系(B 对)。Ingress 不能替代 Service,因为后端的负载均衡仍由 Service 完成;Ingress 不支持 TCP/UDP 转发;Service 用 ClusterIP 类型也可作为 Ingress 的 backend,不强制 NodePort。
Q3. 以下哪个组件是真正执行 Ingress 路由规则的“调度员”?
- A.kube-proxy
- B.Ingress Controller← 正确答案
- C.CoreDNS
- D.etcd
答案:B。Ingress Controller 监听 Ingress 资源并生成反向代理配置,是真正的流量转发执行者。kube-proxy 负责 Service 的 iptables/IPVS 规则;CoreDNS 负责集群 DNS 解析;etcd 是存储组件,均不承担 Ingress 路由职责。
Q4. 在 Ingress 规则中,host 字段的作用是什么?
- A.指定后端 Service 的名字
- B.匹配请求的域名,决定流量归属← 正确答案
- C.设置集群节点的 IP 地址
- D.定义 Pod 的 DNS 策略
答案:B。host 字段用于匹配请求的 Host 头,即“哪个域名该走这条规则”。它与 Service 名字无关(A 错);与节点 IP 无关(C 错);也不影响 Pod DNS(D 错)。
Q5. 下列哪种 pathType 表示“/api 精确匹配 /api,但不会匹配 /api/v1”?
- A.Prefix
- B.Exact← 正确答案
- C.Wildcard
- D.Regex
答案:B。Exact 要求路径完全一致,/api 只精确匹配 /api。Prefix 是前缀匹配,/api 可命中 /api/v1。Kubernetes 没有 Wildcard 和 Regex 这两个标准 pathType 值。
Q6. 关于 Ingress-NGINX 的 rewrite-target 注解,下列说法正确的是?
- A.可以修改转发到后端的请求路径← 正确答案
- B.与 pathType 无关,仅作用于注解层面← 正确答案
- C.常用场景是剥离 /api 前缀后再转发← 正确答案
- D.不配置时后端会收到完整原始路径← 正确答案
答案:ABCD。rewrite-target 是 Nginx Ingress 的注解,负责路径重写(A 对)。它与 pathType 相互独立,一个管匹配、一个管转发后的路径(B 对)。rewrite-target: /$2 配合正则路径可剥离 /api 前缀(C 对)。如果不配置,后端默认收到原始路径(D 对),这正是很多初学者踩坑点。
Q7. 关于 TLS 终止,下列说法正确的是?
- A.Ingress 将 HTTPS 解密后,以明文 HTTP 转发给后端← 正确答案
- B.TLS 终止之后,后端必须重新加密传输
- C.证书需要存放在后端 Pod 内
- D.配置 TLS 后,Ingress 就不再支持 HTTP 访问
答案:A。TLS 终止(termination)指 Ingress 在入口完成解密,集群内部转发使用明文 HTTP(A 对)。后端不需要再加密(B 错)。证书存放在 Secret 中,由 Ingress 挂载,不是 Pod 内置(C 错)。Ingress 若未配置强制跳转规则,HTTP 访问仍可能被接受(D 不完全正确)。
Q8. 关于 NetworkPolicy 的默认行为,正确的理解是?
- A.没有 NetworkPolicy 时,默认允许所有 Pod 互访← 正确答案
- B.一旦对 Pod 应用 NetworkPolicy,未匹配的流量默认被拒绝← 正确答案
- C.NetworkPolicy 只能控制四层端口,不能基于域名过滤← 正确答案
- D.NetworkPolicy 可以完全替代 Ingress 的路由功能
答案:ABC。Kubernetes 默认“无策略即放行”(A 对);一旦有策略选中某 Pod,未放行的流量将被拒绝,体现“默认拒绝”模型(B 对)。NetworkPolicy 基于 IP、端口、标签选择器工作,不解析域名(C 对)。它不能做七层路由,不能替代 Ingress(D 错)。
Q9. 生产环境中,最推荐用哪种方式实现 HTTPS 证书的自动签发与续期?
- A.每年手动创建 Secret 并更新 Ingress
- B.使用 cert-manager 配合 Let's Encrypt← 正确答案
- C.把证书 Base64 硬编码到 Ingress YAML
- D.关闭 HTTPS 以降低运维成本
答案:B。cert-manager 是云原生标准的证书自动管理方案,自动申请、校验、注入 Secret、到期续期(B 对)。手动更新既繁琐又易错(A 错);证书不应直接硬编码在 Ingress 中,应存于 Secret,且明文 Base64 有安全风险(C 错);关闭 HTTPS 不可接受(D 错)。
Q10. 当同一个 Ingress 对象上一方面 host 精确匹配,另一方面 path 前缀匹配,匹配优先级如何判定?
- A.永远按创建时间先后判定
- B.host 完全匹配优先于 path 精确匹配
- C.先按 host 匹配,再在多条 path 中选精确匹配优先← 正确答案
- D.随机选择可用规则
答案:C。Kubernetes Ingress 先筛选出 host 匹配的规则;若有多条 path 命中,则精确匹配(Exact)优先于前缀匹配(Prefix)。这个顺序保证了访问 ai.example.com/api 时不会错误命中 / 的兜底规则。