ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ingress-nginx 主机名路由(Host Based Routing)实战:单负载均衡器按域名分发到多后端服务

ingress-nginx 主机名路由(Host Based Routing)实战:单负载均衡器按域名分发到多后端服务 ingress-nginx 主机名路由Host Based Routing实战单负载均衡器按域名分发到多后端服务【免费下载链接】ingress-nginxIngress NGINX Controller for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/in/ingress-nginx本文以 ingress-nginx 控制器为对象讲解最常用的基于主机名Host的路由场景一个由 ingress-nginx 驱动的负载均衡器同时承载多个域名并将每个域名的流量路由到不同的 Kubernetes Service 后端。读完本文你将掌握 Ingress 资源在两个 Kubernetes API 版本v1beta1与networking.k8s.io/v1下的完整写法、ingressClassName与kubernetes.io/ingress.class注解的控制机制、外部 IP 获取与 DNS 配置流程并从源码层面理解控制器如何识别并接管一个 Ingress。场景概述ingress-nginx 适用于多种使用场景、多种云厂商环境并支持大量配置项。本文聚焦其中最典型的一个集群中已经存在两个type: ClusterIP的 HTTP 服务myservicea与myserviceb注意后端服务的类型必须是 ClusterIP由 ingress-nginx 通过 Service 的 ClusterIP 进行代理转发希望将域名myservicea.foo.org的流量路由到myservicea希望将域名myserviceb.foo.org的流量路由到myserviceb两个域名共享同一个由 ingress-nginx 创建的负载均衡器入口。这是 Kubernetes Ingress 最基础、也最常用的能力一个入口、多域名、多后端按 Host 字段分发。前置条件先安装 ingress-nginx在创建任何 Ingress 资源之前需要先完成 ingress-nginx 的安装。仓库中提供了不同场景的部署方式与说明部署总览与各云厂商方案可参考 docs/deploy/index.md裸金属集群baremetal的部署与注意事项可参考 docs/deploy/baremetal.md控制器启动参数如--ingress-class、--watch-ingress-without-class等会影响下文 Ingress 接管逻辑的 Flag可参考 docs/user-guide/cli-arguments.md。安装完成后集群中会运行一个或多个ingress-nginx 控制器实例并通常伴随一个负载均衡器类型的 Service详见下文获取外部 IP一节。面向 Kubernetes 1.19 集群的 Ingress 写法networking.k8s.io/v1beta1如果集群版本低于 1.19Kubernetes 1.18 及以下可以使用networking.k8s.io/v1beta1API 创建两个 Ingress 资源。示例中特意展示了两种指定控制器的方式便于对照第一个 Ingressingress-myservicea使用spec.ingressClassName: nginxingressClassName字段在 v1beta1 中已可被部分版本识别但在旧版本中仍以注解为主第二个 Ingressingress-myserviceb使用注解kubernetes.io/ingress.class: nginx声明使用共享的 ingress-nginx。apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: ingress-myservicea spec: ingressClassName: nginx rules: - host: myservicea.foo.org http: paths: - path: / backend: serviceName: myservicea servicePort: 80 --- apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: ingress-myserviceb annotations: # use the shared ingress-nginx kubernetes.io/ingress.class: nginx spec: rules: - host: myserviceb.foo.org http: paths: - path: / backend: serviceName: myserviceb servicePort: 80需要注意v1beta1版本中backend使用的是serviceName/servicePort这种扁平写法路径匹配行为也与此后的v1版本存在差异。面向 Kubernetes 1.19 集群的 Ingress 写法networking.k8s.io/v1如果集群版本在 1.19.x 及以上官方建议使用networking.k8s.io/v1API 创建 Ingress 资源。相比v1beta1v1版本的主要变化包括backend改为嵌套的service.nameservice.port.number或service.port.name结构每个path必须显式声明pathTypePrefix/Exact/ImplementationSpecific本文示例使用Prefix表示前缀匹配ingressClassName成为标准字段用于指定由哪个 IngressClass 对应的控制器接管。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-myservicea spec: rules: - host: myservicea.foo.org http: paths: - path: / pathType: Prefix backend: service: name: myservicea port: number: 80 ingressClassName: nginx --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-myserviceb spec: rules: - host: myserviceb.foo.org http: paths: - path: / pathType: Prefix backend: service: name: myserviceb port: number: 80 ingressClassName: nginx将上述 YAML 通过kubectl apply -f file应用后集群中会创建两个 Ingress 资源并由同一个 ingress-nginx 实例统一管理。控制器如何发现并接管 Ingressingress class 判定机制文档明确说明ingress-nginx 会自动发现所有带kubernetes.io/ingress.class: nginx注解、或声明了ingressClassName: nginx的 Ingress 资源。这一发现/接管判定在源码中有非常清晰的实现对应 internal/ingress/controller/store/store.go 中的GetIngressClass函数其判定优先级依次为spec.ingressClassName优先只要IgnoreIngressClass未开启且 Ingress 声明了ingressClassName控制器就会到 IngressClass 列表中查找同名对象并接管它kubernetes.io/ingress.class注解兼容当ingressClassName缺失时回退检查注解kubernetes.io/ingress.class其值必须与控制器配置的AnnotationValue默认为nginx一致无 class 的 Ingress可选如果开启了WatchWithoutClass控制器也会接管未声明任何 class 的 Ingress。相关常量定义在 internal/ingress/controller/ingressclass/ingressclass.goIngressKey kubernetes.io/ingress.class旧版注解键DefaultControllerName k8s.io/ingress-nginxIngressClass 资源中spec.controller的默认值DefaultAnnotationValue nginx注解的默认期望值。在 internal/ingress/controller/controller.go 中控制器在同步每个 Ingress 前都会调用GetIngressClass进行校验如果校验失败例如 class 不匹配该 Ingress 会被直接忽略记录 warning 日志不会被写入 NGINX 配置。因此如果发现创建的 Ingress 没有生效应首先检查ingressClassName或注解值是否与控制器实际监听的 class 一致。关键约束Ingress 与后端 Service 必须在同一命名空间需要注意Ingress 资源必须与它所引用的后端 Service 放在同一个 Namespace 中。Kubernetes Ingress 的backend.service.name只能引用同命名空间内的 ServiceIngress 不支持跨命名空间引用后端。这也意味着如果你的两个后端服务分别部署在不同 Namespace就需要分别在对应 Namespace 下创建各自的 Ingress 资源。获取负载均衡器外部 IP 并配置 DNSingress-nginx 部署后在众多云厂商环境中会自动创建对应的负载均衡器Load Balancer资源。此时你只需要做两件事获取负载均衡器的外部 IP在 DNS 服务商处为myservicea.foo.org和myserviceb.foo.org分别添加指向该 IP 的A 记录。获取外部 IP 的命令kubectl get services -n ingress-nginx输出中ingress-nginx-controller这个 Service类型通常为LoadBalancer的EXTERNAL-IP列即为入口 IP。将两个域名解析到该 IP 后访问http://myservicea.foo.org与http://myserviceb.foo.org就会被同一个 ingress-nginx 实例按 Host 分别路由到myservicea与myserviceb。主机名路由的底层原理从源码结构看ingress-nginx 在同步时会遍历每个 Ingress 的spec.rules将每个rule.Host生成为 NGINX 配置中的一个server 块同一个 Host 下的多个path则生成为该 server 块内的多个location 块。相关逻辑集中在 internal/ingress/controller/controller.go 附近host : rule.Host之后的 server/location 构建流程并会将 Host 统一转为小写进行归一化处理源码中通过toLowerCaseASCII处理见 internal/ingress/controller/controller.go保证匹配不区分大小写在写入模板前对同一 Host 下的 location 按路径长度降序排列以提高路径匹配的准确性如果两个 Ingress 声明了完全相同的host path组合控制器会报错并拒绝生成配置见 internal/ingress/controller/controller.go 的冲突检测避免出现二义性路由。因此本文示例最终会生成两个 server 块myservicea.foo.org、myserviceb.foo.org各自包含一个location /转发到对应后端。进阶Host Path 组合路由host based routing 可以和 path based routing 自由组合同一个 Host 下可以声明多个path分别路由到不同 Service。例如在myservicea.foo.org下同时提供/api与/static两个路径前缀。路径匹配的详细规则Prefix/Exact/ImplementationSpecific三种pathType的差异、正则表达式支持、路径优先级与告警事项可参考 docs/user-guide/ingress-path-matching.md。本地环境测试提示如果使用 minikube 等本地环境进行验证需要注意minikube 下获取外部 IP 的方式与云厂商略有差异通常需要借助minikube tunnel或将 Service 改为 NodePort 后通过节点 IP 访问。具体操作可结合 docs/deploy/baremetal.md 中关于裸金属/本地部署的说明进行。验证时可直接通过 curl 携带Host头测试curl -H Host: myservicea.foo.org http://负载均衡器IP/ curl -H Host: myserviceb.foo.org http://负载均衡器IP/如果返回各自后端的响应内容即说明 host based routing 已正确生效。小结本文完整覆盖了 ingress-nginx 主机名路由的基础用法从新旧两版 Kubernetes API 的 Ingress 写法到ingressClassName/kubernetes.io/ingress.class的接管判定逻辑含 源码级解析再到外部 IP 获取与 DNS 配置。掌握这一场景后你可以继续深入 docs/user-guide/nginx-configuration/annotations.md 学习重写、限流、认证等高级注解或通过 docs/user-guide/index.md 浏览完整的用户指南。【免费下载链接】ingress-nginxIngress NGINX Controller for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/in/ingress-nginx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表