找回密码
 立即注册
首页 业界区 业界 Kubernetes Ingress:管理集群外部访问的入口网关 ...

Kubernetes Ingress:管理集群外部访问的入口网关

滥眩 昨天 19:15
1.jpeg

  在k8s之服务Service章节,我们详细的介绍了Service的组成以及相关的原理。Service可以将自身的服务暴露出去,给集群内部服务或者给外部服务去使用,或者将外部服务分装为一个service,供给集群内部服务使用。而今天介绍的ingress其实和service很类似,他都是将内部的服务暴露出来,给外界(包括集群内或集群外)去使用。只不过它两者工作的网络层级不同罢了。
1. Ingress引入

  上一章节介绍的LoadBalancer已经能够将k8s内部服务暴露到公网上去了,似乎就已经可以了,为什么还需要ingress呢?因为服务最终无非就是内部使用或者外部使用。内部使用有clusterIP或者nodeIP,外部使用LoadBalancer,为什么还需要一个ingress呢?从LoadBalancer的原理上我们可以看到,如果每使用一个LoadBalancer Service,就需要一个新的公网LB+IP或者域名,而这些都需要花钱(当然在商业的驱动下,引入ingress也并没有说能够降低成本,但是确实是带来了便捷)。
  这时候,ingress就出来了。Igress 是 Kubernetes 中定义“反向代理规则”的一种 API 对象,借助Ingress Controller(例如Nginx Ingress Controller)来执行反向代理。
2. Ingress是什么

  ingress一共由2个组件组成:

  • ingress资源对象:配置了相关http路由转发规则的合集。

    • 配置 Host(域名)Path(路径)  与后端 Service 的映射关系。
    • 它本身不处理流量,只是一个“配置清单”。
    • 通常不直接指定 Controller 名称,而是通过 spec.ingressClassName 间接关联
      1. spec:
      2.   ingressClassName: nginx-ingresclass # 指向IngressClass的名称
      3.   rules:
      4.   - host: example.com
      5.     http:
      6.       paths:
      7.       - path: /api
      8.         pathType: Prefix
      9.         backend:
      10.           service:
      11.             name: api-svc # 转发到哪个service
      12.             port:
      13.               number: 80  # service yaml文件中配置的port
      复制代码

  • ingressClass:ingres资源对象与ingress controller之间的桥梁。

      1. apiVersion: networking.k8s.io/v1
      2. kind: IngressClass
      3. metadata:
      4.   name: nginx-ingresclass   # Ingress资源定义中的spec.ingressClassName 一致
      5.   annotations:
      6.     ingressclass.kubernetes.io/is-default-class: "true"  # 将这个 IngressClass 标记为集群中的“默认 IngressClass
      7. spec:
      8.   controller: k8s.io/ingress-nginx  # 与下面ingress controller的启动参数一致
      复制代码

  • ingress controller:一个运行在集群中的 Pod(或多个 Pod),本质是一个反向代理pod + 控制器(Controller)

    • 反向代理:接收外部 HTTP/HTTPS 请求,根据规则转发到后端 Service 对应的 Pod。
    • 控制器(Controller) :持续监听 Kubernetes API,自动发现 Ingress、Service、Endpoints 的变化,并动态更新自身的代理配置(如 Nginx 配置)。
    • 启动时需声明自己自己的 controller​ 标识符(与 IngressClass 中的 spec.controller 匹配)。
      1. # Ingress Controller Deployment 的启动参数示例
      2. args:
      3.   - --controller-class=k8s.io/ingress-nginx  # 必须与 IngressClass.spec.controller 一致
      复制代码

graph LR  A[Ingress] -- spec.ingressClassName --> B(IngressClass)  B -- spec.controller --> C[Ingress Controller]  C -- 监听并实现 --> A  C -- 转发流量 --> D[Service → Pod]  当启动一个ingresss Controller的时候,会Watch所有的Ingress资源,然后对每个 Ingress,检查:

  • 是否有 spec.ingressClassName
  • 如果有,找到对应的 IngressClass
  • 检查该 IngressClass.spec.controller​ 是否等于自己(k8s.io/ingress-nginx)
  • 如果匹配则处理这个 Ingress(生成相关的反向代理规则),否则则忽略
  Ingress能够提供从集群外部到集群内服务的http和https路由,是一组路由规则的集合。以下是一个ingress的请求例子。如果大家知道nginx的话,会发现ingress的原理是不是和nginx很类似。本质上来说ingress controller​[注] 就是一个反向代理的服务(运行在pod上,基于Nginx、Traefik或者其他组件),然后基于路由规则,扮演着集群内部的“智能路由”角色。
  互联网的网络流量,通过云产商的LB(或者Nodeport)转发到Ingress Controller上,然后Ingress Controller则会根据Ingress的路由定义,将又转发到Service,然后Service再转发到了pod中的服务。
  1. @startuml
  2. skinparam componentStyle rectangle
  3. skinparam defaultTextAlignment center
  4. skinparam wrapWidth 200
  5. package "外部网络" {
  6.   [客户端\n(Client)] as client
  7. }
  8. cloud "云平台 / 网络基础设施" {
  9.   [负载均衡器\n(LoadBalancer)] as lb
  10. }
  11. package "Kubernetes 集群" {
  12.   [Ingress Controller\n(Pod)] as ingress_controller
  13.   package "Ingress 资源\n(定义多条路由规则)" {
  14.     [Ingress\n(multi-rule-ingress)] as ingress_resource
  15.   }
  16.   package "Service 层" {
  17.     [ClusterIP Service\n(web-svc)] as web_svc
  18.     [ClusterIP Service\n(api-svc)] as api_svc
  19.     [ClusterIP Service\n(shop-svc)] as shop_svc
  20.   }
  21.   package "工作负载" {
  22.     [Pod\n(web-app-1)\napp=web] as web_pod1
  23.     [Pod\n(web-app-2)\napp=web] as web_pod2
  24.     [Pod\n(api-app-1)\napp=api] as api_pod1
  25.     [Pod\n(api-app-2)\napp=api] as api_pod2
  26.     [Pod\n(shop-app-1)\napp=shop] as shop_pod1
  27.   }
  28. }
  29. ' ===== 数据流向 =====
  30. client --> lb : 请求 1:\nhttps://example.com/
  31. client --> lb : 请求 2:\nhttps://example.com/api/v1/users
  32. client --> lb : 请求 3:\nhttps://shop.example.com/
  33. lb --> ingress_controller : 所有请求转发至\nIngress Controller\n(通过 LB IP/NodePort)
  34. ingress_controller --> ingress_resource : 读取 Ingress 规则\n匹配 Host/Path
  35. ' 规则1: example.com/ -> web-svc
  36. ingress_resource --> web_svc : 规则1:\nhost: example.com\npath: / -> web-svc
  37. ' 规则2: example.com/api/ -> api-svc
  38. ingress_resource --> api_svc : 规则2:\nhost: example.com\npath: /api/ -> api-svc
  39. ' 规则3: shop.example.com/ -> shop-svc
  40. ingress_resource --> shop_svc : 规则3:\nhost: shop.example.com\npath: / -> shop-svc
  41. ' Service 到 Pod 的流量
  42. web_svc --> web_pod1
  43. web_svc --> web_pod2
  44. api_svc --> api_pod1
  45. api_svc --> api_pod2
  46. shop_svc --> shop_pod1
  47. ' ===== 配置与选择器关系(虚线)=====
  48. ingress_controller ..> ingress_resource : 监听并动态加载\nIngress 配置
  49. web_svc ..> web_pod1 : selector:\napp=web
  50. web_svc ..> web_pod2 : selector:\napp=web
  51. api_svc ..> api_pod1 : selector:\napp=api
  52. api_svc ..> api_pod2 : selector:\napp=api
  53. shop_svc ..> shop_pod1 : selector:\napp=shop
  54. note right of ingress_resource
  55.   **Ingress 多路由规则示例**:
  56.   - 规则1: host=example.com, path=/      → web-svc
  57.   - 规则2: host=example.com, path=/api/  → api-svc
  58.   - 规则3: host=shop.example.com, path=/ → shop-svc
  59. end note
  60. note left of lb
  61.   LoadBalancer 由云平台创建,
  62.   将所有外部 HTTP/HTTPS 流量
  63.   统一导入 Ingress Controller。
  64. end note
  65. legend
  66.   **数据流转说明**:
  67.   1. 客户端发起不同 Host/Path 的请求
  68.   2. LB 将所有请求转发给 Ingress Controller
  69.   3. Ingress Controller 根据 Ingress 资源中的多条规则匹配
  70.   4. 不同规则路由到不同的 ClusterIP Service
  71.   5. 各 Service 负载均衡到对应标签的 Pod
  72. endlegend
  73. @enduml
复制代码
Ingress 本身只是一个规则配置(一个资源对象),必须配合 Ingress Controller(如 Nginx、Traefik)才能工作。LoadBalancer 通常用于暴露 Ingress Controller 本身(通过 Service of type=LoadBalancer),而 Ingress Controller 再根据 Ingress 规则将流量分发到不同的内部 Service。
3. Ingress匹配规则

  Ingress支持很多匹配规则,以下是相关常用的匹配规则:
匹配维度规则类型说明示例注意事项Host(域名)
精确匹配完全匹配指定域名​host: example.com​ → 仅匹配 example.com区分大小写;必须是合法 DNS 名单级通配符仅支持前缀 *.,匹配任意一级子域名​host: "*.example.com"​ → 匹配 foo.example.com​,不匹配 a.b.example.com不支持 example.* 或多级通配省略 host匹配所有 Host(包括 IP 直接访问)无 host 字段 → 任何域名都进入该 rule生产环境慎用,易造成路由冲突Path(路径)
​pathType: Prefix前缀匹配(最常用)​path: /api​ → 匹配 /api​、/api/v1​、/api/不匹配 /apis;路径区分大小写​pathType: Exact完全相等匹配​path: /api​ → 仅匹配 /api​,不匹配 /api/路径末尾 / 视为不同路径高级匹配正则表达式(需 annotation)部分 Controller(如 Nginx)支持通过 annotation 启用正则​nginx.ingress.kubernetes.io/use-regex: "true"​ + path: /v[0-9]+依赖具体实现,非标准功能匹配优先级
Host 优先先匹配 Host,再在匹配的 Host 下匹配 Path​shop.example.com/api​ 不会匹配 api.example.com/apiHost 不匹配则整条 rule 跳过Path 最长前缀优先在同一 Host 下,更长的路径优先匹配​/api/v1​ 比 /api 优先避免路径重叠导致意外路由4. 总结

  Ingress 是 Kubernetes 中管理外部访问集群服务的核心机制,主要用于 HTTP/HTTPS 流量的七层路由。它本身只是一个 API 资源,定义了基于主机名(host)和路径(path) 的路由规则,将请求转发到后端 Service。但 Ingress 要真正生效,必须部署对应的 Ingress Controller(如 Nginx、Traefik、ALB 等)。Controller 会监听 Ingress 资源变化,动态生成反向代理配置(如 Nginx 配置),并自动重载以应用新规则。
5. 脚注

[注]
ingress controller

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册