尽管标准的 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 中,我们支持为VirtualServer 和 VirtualServerRoute(VS 和 VSR)资源的配置代码片段,支持您为基于 HTTP 的客户端原生扩展 NGINX Ingress 配置。1.11.0 版引入了 TS 资源的代码片段,因此您可以轻松利用 NGINX 和 NGINX Plus 的全部功能来提供基于 TCP/UDP 的服务。例如,您可使用代码段添加 deny
和 allow
指令,以使用 IP 地址和范围定义可以访问服务的客户端。
apiVersion: k8s.nginx.org/v1alpha1
kind: 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
命令;输出结果包括状态(Valid
或 Invalid
)、最近的更新原因及(对于单个 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 版中引入 的 APLogConf 和 APPolicy 对象,并可连接到 VirtualServer (VS) 和 VSR 资源。这意味着安全管理员可以利用 VS 资源管理整个 Ingress 配置,同时通过引用 VSR 资源将安全职责委派给其他团队。
在下例中,waf-prod
策略应用于被路由到 webapp-prod
上游的用户。为了横跨不同团队拥有的命名空间委派 /v2
路由的安全职责,突出显示的 route
指令引用了 VSR 资源。
apiVersion: k8s.nginx.org/v1
kind: 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/v1
kind: 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 校验 – 避免更多配置错误
- Policy 状态信息 – 在将 Policy 对象应用于 Ingress 配置前显示其状态
- Istio 兼容 – 在 Istio 环境中利用 NGINX Ingress Controller 的高级功能
- Cluster IP 地址作为上游 endpoints – 使用 Service/Cluster IP 地址作为 NGINX Ingress Controller 配置中的上游 endpoints。
更多 Annotation 校验
在 1.10.0 版中引入的 Annotation 校验改进的基础之上,我们将新增以下 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
命令现在可以报告策略的状态(Valid
或 Invalid
)、(对于单个 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/v1
kind: 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 版本辨析)。