首页 / Kubernetes (k8s) 入门教程 / Ingress 七层路由

Kubernetes (k8s) 入门教程

Ingress 七层路由

本教程共 65 篇 · 第 28 篇 · 更新于 2026-08-14 · 约 15 分钟阅读

KubernetesIngressIngressClass七层路由networking.k8s.io/v1TLS

本节目标:掌握用 Ingress 做 HTTP/HTTPS 七层路由。看懂路径匹配、基于名称的虚拟主机、TLS 终止,以及 IngressClass 和 Ingress 控制器的关系。所有示例对齐 networking.k8s.io/v1

Service 解决了集群内部的访问。可流量从哪进集群?NodePort 和 LoadBalancer 只能做四层(IP+端口)转发,看不到 URL 路径和域名。想按 /api/web 把请求分给不同服务,得靠七层路由——这就是 Ingress(入口)。

Warning

全程用 networking.k8s.io/v1。老的 extensions/v1beta1 早已废弃,别在新配置里出现。当前 Ingress API 已被冻结,但仍是 GA、稳定可用,官方建议新项目优先考虑 Gateway API。

28-1 Ingress 是什么

Ingress 把集群外的 HTTP 和 HTTPS 流量,按你定义的规则映射到集群内的 Service。它理解 URI、主机名、路径这些 Web 概念,能做:

  • 给服务分配外部可访问的 URL。
  • 对流量做负载均衡。
  • 终止 TLS(也就是 HTTPS 卸载)。
  • 基于名称的虚拟主机(一个 IP 托管多个域名)。

要注意:Ingress 只管 HTTP/HTTPS。想暴露别的协议,还是得回到 NodePort 或 LoadBalancer。

28-2 光写 Ingress 没用,得有控制器

这是新手最常见的误解:我创建了 Ingress,为什么没生效?

因为 Ingress 只是”规则声明”,真正干活的是 Ingress 控制器。常见的实现有 NGINX Ingress Controller、Traefik、HAProxy 等。它们读取 Ingress 规则,然后去配置背后的负载均衡器或代理。

Note

只创建 Ingress 资源,集群里没有对应的 Ingress 控制器,等于写了张纸条却没人执行。部署集群时得先把控制器装上。

28-3 一个最小的 Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
spec:
  ingressClassName: nginx
  defaultBackend:
    service:
      name: my-service
      port:
        number: 80

它把什么都没收到的流量,兜底转给 my-service。这里 ingressClassName: nginx 指明用哪个控制器实现。

如果省略 ingressClassName,集群里得有一个被标记为”默认”的 IngressClass,否则新建会出问题。

28-4 规则由 host、path、backend 组成

每条 HTTP 规则包含三样东西:

  1. 可选的 host:不写就匹配所有域名;写了就只对该主机名生效。
  2. 路径列表 paths:每个路径指向一个后端 Service(通过 service.nameservice.port)。
  3. backend:即”Service + 端口”的组合,流量最终转去哪。

路径必须声明 pathType,有三种:

  • Exact:精确匹配,区分大小写。
  • Prefix:按 / 分段的前缀匹配,区分大小写。
  • ImplementationSpecific:匹配逻辑交给具体的 IngressClass 决定。
Tip

Prefix 匹配是按路径元素逐段匹配的。比如 /foo/bar 能匹配 /foo/bar/baz,但匹配不了 /foo/barbaz。写路径时这个斜杠陷阱要留心。

28-5 扇出:一个 IP 分流到多个服务

扇出(fanout)是 Ingress 的经典用法:同一个 IP 进来,按路径分给不同 Service,省下一堆负载均衡器。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-fanout
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: foo.bar.com
      http:
        paths:
          - path: /foo
            pathType: Prefix
            backend:
              service:
                name: service1
                port:
                  number: 4200
          - path: /bar
            pathType: Prefix
            backend:
              service:
                name: service2
                port:
                  number: 8080

访问 foo.bar.com/foo 进 service1,访问 foo.bar.com/bar 进 service2。一条规则,两个后端,清晰。

28-6 基于名称的虚拟主机

一个 IP 想同时托管 first.bar.comsecond.bar.com?靠 host 字段区分即可:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: name-virtual-host
spec:
  ingressClassName: nginx
  rules:
    - host: first.bar.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: service1
                port:
                  number: 80
    - host: second.bar.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: service2
                port:
                  number: 80

主机名还支持通配符,比如 *.foo.com 能匹配 bar.foo.com,但只覆盖一个 DNS 标签,匹配不了 baz.bar.foo.com

28-7 配置 TLS 终止

想让 Ingress 支持 HTTPS,先准备一个包含证书和私钥的 Secret:

apiVersion: v1
kind: Secret
metadata:
  name: testsecret-tls
  namespace: default
data:
  tls.crt: base64编码的证书
  tls.key: base64编码的私钥
type: kubernetes.io/tls

然后在 Ingress 里引用它:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-example
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - https-example.foo.com
      secretName: testsecret-tls
  rules:
    - host: https-example.foo.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: service1
                port:
                  number: 80

Ingress 只支持 443 这一个 TLS 端口,且 TLS 在入口处终止——到后端 Service 和 Pod 的流量是明文的。证书里的 CN(全限定域名)得和 hosts 对上。

Warning

tls 里的 hosts 必须和 rules 里的 host 精确匹配。默认规则(不写 host)配不了 TLS,因为那得给所有可能的子域名都发证。

28-8 IngressClass 是什么

Ingress 可以由不同控制器实现,配置各异。IngressClass 就是用来描述”这一套规则交给哪个控制器、用啥参数”的资源。

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: external-lb
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"
spec:
  controller: example.com/ingress-controller

把它标成 is-default-class: "true",以后 Ingress 不写 ingressClassName 就自动归它管。

Warning

一个集群里最多只能有一个默认 IngressClass。要是标了两个,准入控制器会拒绝创建任何没显式写 ingressClassName 的 Ingress。

28-9 多个路径都匹配怎么办

当多条路径同时匹配一个请求,优先级规则是:路径最长的赢;如果长度还一样,则 Exact 类型优先于 Prefix 类型。这套规则让你可以放心地写细粒度路由而不必担心被粗粒度抢走。

28-10 Ingress 与 Service 的分工

记住一张图:Service 负责把一组 Pod 收敛成一个稳定地址;Ingress 负责在集群边缘,按域名和路径把外部 HTTP 流量引入正确的 Service。

两者配合,才构成完整的对外服务能力。Ingress 本身不直接连 Pod,它始终是”指到 Service,再由 Service 指到 Pod”。

下章退一步看更底层的东西:Kubernetes 的网络模型长什么样,CNI 插件在其中扮演什么角色。