Loading

K8S的Ingress

原文博客:https://nosae.top/posts/k8s的ingress

Ingress 是什么

Ingress 是 Kubernetes 中的 L7(应用层,HTTP/HTTPS)反向代理与路由入口。

上一篇介绍了 Service,它与 Ingress 的区别是,Service 负责 L4(传输层,TCP/UDP)集群内部服务发现与负载均衡,Ingress 负责 L7 路由、域名/路径转发,他们一般配合着来使用:

用户请求 → Ingress → Service → Pod

ingress-diagram

Ingress 这个 k8s 资源只是定义了路由规则,真正做反向代理的是 Ingress Controller。虽然 Ingress 是内置的资源,但 Ingress Controller 不是 k8s 内置的 contorller,而是可以根据需求自由选择的。比如官方维护的 ingress-nginx 和 aws-load-balancer-controller,还有第三方的 traefik 等,因此单纯创建 Ingress 并没有任何效果,还需要安装一个 Ingress Controller。

要注意,Ingress 只处理 L7 的协议(只支持 HTTP/HTTPS),创建一个 Ingress 并不会对外暴露任何端口,对外暴露端口是 NodePort 或 LoadBalancer 类型 Service 的工作。

Ingress 资源

一个最简单 Ingress 作为入门:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /testpath
        pathType: Prefix
        backend:
          service:
            name: test
            port:
              number: 80

在说 ingressClassName 字段之前先要介绍下 IngressClass 这个资源类型。一个集群中可以同时运行不同的 Ingress Controller。Ingress 将会选择其中一个 Ingress Controller 来处理,但它并不是直接指定 Controller 的名称或者是什么特殊的 id,而是通过 IngressClass 这个资源。IngressClass 绑定了一个特定的 Ingress Controller。比如下面的 IngressClass 绑定了 nginx ingress controller:

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: nginx
spec:
  controller: k8s.io/ingress-nginx

另外,IngressClass 还可以设置 spec.parameters。它的用处在于,对大多数 ingress controller(Nginx、Contour)来说,IngressClass 可能需要额外的参数来控制行为,例如:LoadBalancer 具体配置、网关定义、代理行为等,这些参数不写在 Ingress、也不写在 IngressClass 本身,而是写在一个独立的资源中,比如 ConfigMap、甚至是某些 controller 定义的 CRD。IngressClass 的 .spec.parameters 就是指向这个外部配置,比如:

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: nginx
spec:
  controller: k8s.io/ingress-nginx
  parameters:
    apiGroup: example.io
    kind: GlobalIngressConfig
    name: global-config

最后,Ingress 通过将 spec.ingressClassName 设置为 IngressClass 的 metadata.name 来指定要使用哪个 IngressClass,从而指定负责处理该 Ingress 的是哪个 Ingress Controller。

rules 和 backend

rules 用于指定路由规则,将匹配 path 的请求路由到指定的 backend,比如在上面例子中,请求路径匹配 /testpath 将被路由到名为 test 的 Service。另外,spec.defaultBackend 指定了不匹配任何 rule 的情况下的默认 backend。

除了以 Service 作为 backend 外,还可以使用 resource backend,这种 backend 一般是用将「对静态资源的请求」路由到「对象存储」backend 中。下面展示了 defaultBackend 和 reosurce backend 的示例用法:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-resource-backend
spec:
  defaultBackend:
    resource:
      apiGroup: k8s.example.com
      kind: StorageBucket
      name: static-assets
  rules:
    - http:
        paths:
          - path: /icons
            pathType: ImplementationSpecific
            backend:
              resource:
                apiGroup: k8s.example.com
                kind: StorageBucket
                name: icon-assets

path 类型

在上面的例子中注意到路由规则中的 path 下面还带一个 pathType,一共有三种 pathType:

  • Exact:完全匹配,也就是多一个 / 都不行,比如 /foo 只能匹配 /foo,不能匹配 /foo/
  • Prefix:基于 / 单词分割的前缀匹配,从表面上看就是请求路径最后有没有 / 都不会影响匹配结果
  • ImplementationSpecific:由 IngressClass(ingress controller)的具体实现决定,可能会实现成 Exact、Prefix 或是别的行为

Ingress 的类型

单 service

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

Ingress 创建后,Ingress Controller 一般会为 Ingress 分配对外暴露的 IP,此时通过该 IP 访问的所有请求,最终都会转发到名为 test 的 service 的 80 端口。注意,如果你没创建这个 service 的话,此时请求一般会返回 503 Service Unavailable。

多 service

就是多个 backend 的意思。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-fanout-example
spec:
  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

基于 host 的路由

基于 http 请求的 host header 来进行路由。

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

TLS

Ingress 通过使用一个包含 TLS 证书+私钥的 Secret 来支持 HTTPS 请求。Ingress 规范是 TLS 在 Ingress Controller 处终止,也就是 集群外 -> Ingress 的是 HTTPS 请求,而 Ingress -> Service -> Pod 的流量则是明文 HTTP。

如果一个 Ingress 配置了多个证书(多个 secret),那么 Ingress Controller 将会通过 TLS 的 SNI(Server Name Indication)字段来选择证书。SNI 是 TLS 握手协议中传输的一个字段,告诉服务器 "我想访问的是哪个域名"。

apiVersion: v1
kind: Secret
metadata:
  name: testsecret-tls
  namespace: default
data:
  tls.crt: base64 encoded cert
  tls.key: base64 encoded key
type: kubernetes.io/tls
---

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-example-ingress
spec:
  tls:
  # 注意这里是一个数组,可以配置多个hosts + secretName,即可以配置多个证书
  - 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 本身不能让你配置“高级负载均衡策略”。 你想要更智能的负载均衡(例如会话保持、动态权重)只能在 Service 的 LoadBalancer 层实现,Ingress 只做基本的转发策略。因为 Ingress 是 L7 路由入口,不是高级负载均衡器。Ingress 只做:

  • Path/Host 路由
  • TLS 终止
  • 基础反向代理
  • 基础健康检查

它不像 Istio、Nginx(这里是指 Nginx 本身,而不是 Nginx Ingress Controller)、Envoy 那样是高级 L7 网关。高级 LB 特性都在 Service 层,不在 Ingress 层:

Client
   |
   v
Ingress Controller (basic LB only)
   |
   v
Service (L4 LB from Kubernetes/cloud LB)
   |
   v
Pods
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example
  namespace: foo
spec:
  ingressClassName: nginx
  rules:
    - host: www.example.com
      http:
        paths:
          - pathType: Prefix
            backend:
              service:
                name: exampleService
                port:
                  number: 80
            path: /
posted @ 2025-12-12 00:43  NOSAE  阅读(7)  评论(0)    收藏  举报