BLOG | NGINX

使用 NGINX Ingress Controller 增强 TCP/UDP 负载均衡和 WAF 配置

NGINX-Part-of-F5-horiz-black-type-RGB
Amir Rawdat 缩略图
Amir Rawdat
Published March 31, 2021

尽管标准的 Kubernetes Ingress 资源非常适合部署和配置基本的 Ingress 负载均衡功能,但却没有实现生产级 Kubernetes 所需的定制特性。因而,非 NGINX 用户只能使用容易出错、难以使用、不安全且缺乏细粒度控制的Annotations、ConfigMap 和自定义模板。NGINX Ingress 资源是我们针对这一问题给出的解决方案。

NGINX Ingress 资源可用于基于NGINX 开源版或 NGINX Plus 的 NGINX Ingress Controller。该资源采用了一种原生、类型安全的缩进式配置风格,可简化 Ingress 负载均衡的实施。本文重点介绍了 NGINX Ingress Controller 1.11.0 推出的两个特性,它们有助于更轻松地配置 WAF 和负载均衡策略:

  • TransportServer 资源  – TransportServer 资源定义了 TCP、UDP 和 TLS 直通负载均衡的配置。我们添加了健康检查、状态报告,及以代码片段方式增强 TCP/UDP 负载均衡能力。
  • NGINX Ingress WAF 策略 – 在为 NGINX Ingress Controller 部署 NGINX App Protect 3.0 时,您可以利用 NGINX Ingress 资源将 WAF 策略应用于特定的 Kubernetes 服务。

增强的 TransportServer 资源

NGINX Ingress Controller 1.11.0 在以下方面扩展了 TransportServer (TS) 资源:

注: 1.11.0 版中 TransportServer 资源的增强功能还是开发中的预览版,最新版本已正式发布,可参考版本说明。

TransportServer 代码片段

NGINX Ingress Controller 1.8.0<.htmla> 中,我们支持为VirtualServer 和 VirtualServerRoute(VS 和 VSR)资源的配置代码片段,支持您为基于 HTTP 的客户端原生扩展 NGINX Ingress 配置。1.11.0 版引入了 TS 资源的代码片段,因此您可以轻松利用 NGINX 和 NGINX Plus 的全部功能来提供基于 TCP/UDP 的服务。例如,您可使用代码段添加 denyallow 指令,以使用 IP 地址和范围定义可以访问服务的客户端。

apiVersion: k8s.nginx.org/v1alpha1kind: TransportServer
metadata:
  name: cafe
spec:
  host: cafe.example.com
  serverSnippets: |
    deny  192.168.1.1;
    allow 192.168.1.0/24;
  upstreams:
  - name: tea
    service: tea-svc
    port: 80

健康检查

为了监控 Kubernetes 集群的运行状况,NGINX Ingress Controller 不能仅依赖 Kubernetes 自带的针对应用 Pod 运行状态的探测,还需密切关注与基于 TCP/UDP 的上游服务之间的网络状态,可使用基于业务请求异常的被动健康检查方式,或采用主动健康检查机制(仅 NGINX Plus)定期模拟请求探测 Endpoints 的健康状态。

健康检查对于异常应用的熔断和降级非常有用。您可以使用 TS 资源中 healthCheck 字段的参数自定义健康检查,如:探测间隔、探测超时时间,及探测随机延迟时间等。

此外,您还可在 NGINX Ingress Controller 上设置用于健康检查的上游服务和目标端口。当上游应用的健康状态由独立进程或子系统的listener发布时会非常有用。

使用 ingressClassName 支持多个 TransportServer 资源

当您更新并发布 TS 资源时,能验证配置是否正确且已生效是非常有用的。1.11.0 版为 TS 资源引入了 ingressClassName 字段 和状态报告。ingressClassName 字段可确保在运行多个部署的环境中,TS 资源由特定 Ingress Controller 部署进行处理。

要显示一个或所有 TS 资源的状态,请运行 kubectl get transportserver 命令;输出结果包括状态(ValidInvalid)、最近的更新原因及(对于单个 TS)自定义消息。

$ kubectl get transportserver  NAME      STATE   REASON           AGE
  dns-tcp   Valid   AddedOrUpdated   47m

$ kubectl describe transportserver dns-tcp
. . .
Status:
  Message:  Configuration for default/dns-tcp was added or updated
  Reason:   AddedOrUpdated
  State:    Valid

如果多个 TS 资源争用同一主机/监听器,则 NGINX Ingress Controller 将选择时间戳最早的 TS 资源,以确保在这种情况下获得确定的结果。

定义支持原生 NGINX App Protect 的 WAF 策略

NGINX Ingress 资源不仅有助于更轻松、更灵活地进行配置,而且还支持您将流量控制委派给不同的团队,并对拥有应用子路由的用户施加更严格的权限限制(如 VirtualServerRoute (VSR) 资源中所定义的)。通过让正确的团队获取正确的 Kubernetes 资源,NGINX Ingress 资源支持您对网络资源进行细粒度控制,并减少用户遭到入侵或黑客攻击时对应用造成的潜在损害。

1.11.0 版引入了原生 Web 应用防火墙 (WAF) Policy 对象,可将这些优势扩展到您 Kubernetes 部署中的 NGINX App Protect 配置。该策略利用 1.8.0 版中引入APLogConfAPPolicy 对象,并可连接到 VirtualServer (VS) 和 VSR 资源。这意味着安全管理员可以利用 VS 资源管理整个 Ingress 配置,同时通过引用 VSR 资源将安全职责委派给其他团队。

在下例中,waf-prod 策略应用于被路由到 webapp-prod 上游的用户。为了横跨不同团队拥有的命名空间委派 /v2 路由的安全职责,突出显示的 route 指令引用了 VSR 资源。

apiVersion: k8s.nginx.org/v1kind: VirtualServer
metadata:
  name: webapp
spec:
  host: webapp.example.com
  policies:
  - name: waf-prod 
  tls:
    secret: app-secret
  upstreams:
  - name: webapp-prod
    service: webapp-svc
    port: 80
  routes:
  - path: /v2
    route: test/test
  - path: /v1
    action:
      pass: webapp-prod

管理 test 命名空间的团队可以使用该命名空间中的 VSR 资源设置其自身的参数和 WAF 策略。

apiVersion: k8s.nginx.org/v1kind: VirtualServerRoute
metadata:
  name: test 
  namespace: test
spec:
  host: webapp.example.com
  upstreams:
  - name: webapp 
    service: webapp-test-svc
    port: 80
  subroutes:
  - path: /v2
    policies:
    - name: waf-test
    action:
      pass: webapp

本例按命名空间分隔租户,并对 test 命名空间中的 webapp-test-svc 服务实施不同的 WAF 策略。它说明了将资源委派给不同的团队并利用对象对其进行封装能够简化新功能的测试,而不会中断生产环境中运行的应用。

1.11.0 版还有哪些新特性?

Nginx Ingress Controller 1.11.0 的推出延续了我们提供灵活、强大且易于使用的生产级 Ingress Controller 的承诺。除了 WAF 和 TS 的改进外,1.11.0 版还包括以下增强特性:

更多 Annotation 校验

在 1.10.0 版中引入的 Annotation 校验改进<.htmla>的基础之上,我们将新增以下 Annotations 的校验:

注释验证
nginx.org/client-max-body-size必须是有效的偏移量
nginx.org/fail-timeout必须是有效的时间
nginx.org/max-conns必须是有效的非负整数
nginx.org/max-fails必须是有效的非负整数
nginx.org/proxy-buffer-size必须是有效的大小
nginx.org/proxy-buffers必须是有效的代理缓冲区规范
nginx.org/proxy-connect-timeout必须是有效的时间
nginx.org/proxy-max-temp-file-size必须是有效的大小
nginx.org/proxy-read-timeout必须是有效的时间
nginx.org/proxy-send-timeout必须是有效的时间
nginx.org/upstream-zone-size必须是有效的大小

如果在应用 Ingress 资源时 annotation 的值无效,则 Ingress Controller 将拒绝资源并从 NGINX 中删除相应的配置。

Policy 的状态信息

kubectl get policy 命令现在可以报告策略的状态(ValidInvalid)、(对于单个 TS)自定义消息及最近更新原因。

$ kubectl get policy  NAME              STATE   AGE
  webapp-policy     Valid   30s

$ kubectl describe policy webapp-policy
. . .
Status:
  Message:  Configuration for default/webapp-policy was added or updated
  Reason:   AddedOrUpdated
  State:    Valid

Istio 兼容

NGINX Ingress Controller 现在作为在 Istio 服务网格内部运行的应用的 Ingress controller。这支持用户在基于 Istio 的环境中继续使用 NGINX Ingress Controller 提供的高级功能,而无需采用变通方案。这一集成涉及以下两个要求:

  • 将 Istio sidecar 注入 NGINX Ingress Controller 部署中
  • 仅将一个 HTTP Host 标头发送到后端

要满足第一个要求,请将下列项目添加至 NGINX Ingress 部署文件的 annotations 字段。

annotations:   traffic.sidecar.istio.io/includeInboundPorts: "" 
  traffic.sidecar.istio.io/excludeInboundPorts: "80,443"         
  traffic.sidecar.istio.io/excludeOutboundIPRanges: "10.90.0.0/16,10.45.0.0/16"     sidecar.istio.io/inject: 'true'

第二个要求可以通过更改 requestHeaders 字段的行为来实现。在之前的版本中,使用以下配置可以将两个 Host 标头发送至后端:$$host 和指定值 bar.example.com

apiVersion: k8s.nginx.org/v1kind: VirtualServer
metadata:
  name: foo 
spec:
  host: foo.example.com
  upstreams:
  - name: foo
    port: 8080
    service: backend-svc
    use-cluster-ip: true
  routes:
  - path: "/"
    action:
      proxy:
        upstream: foo
        requestHeaders:
          set:
          - name: Host
            value: bar.example.com

在 1.11.0 版及更高版本中,仅需发送指定值。若要发送 $host,请完全忽略 requestHeaders 字段。

Cluster IP 地址作为上游 Endpoints

NGINX Ingress Controller 配置中的上游 Endpoints 现在可以使用 Service/Cluster IP 地址进行配置,而非 每个 Pod Endpoints 的 IP 地址。若要启用 NGINX Ingress Controller 将流量路由至 Cluster IP 服务,请将 use-cluster-ip:: true 字段添加至 VS 或 VSR 配置的 upstreams 部分:

upstreams:  - name: tea
    service: tea-svc
    port: 80
    use-cluster-ip: true
  - name: coffee
    service: coffee-svc
    port: 80
    use-cluster-ip: true

资源

有关 1.11.0 版的完整变更日志发布,可参考版本说明了解详情。

如欲试用基于 NGINX 开源版的 NGINX Ingress Controller,您可以获取发布的源代码,或者从 DockerHub 下载预构建的容器。

如欲了解 Ingress Controller 之间的差异,请参阅我们的博文《Ingress Controller 选型指南,第四部分:NGINX Ingress Controller 选项》(NGINX Ingress Controller for Kubernetes 版本辨析)。


"This blog post may reference products that are no longer available and/or no longer supported. For the most current information about available F5 NGINX products and solutions, explore our NGINX product family. NGINX is now part of F5. All previous NGINX.com links will redirect to similar NGINX content on F5.com."