NGINX.COM
Web Server Load Balancing with NGINX Plus

许多第一次使用 Kubernetes 的企业,都是从 Kubernetes 社区所开发和维护的 NGINX Ingress Controller 上手的 (kubernetes/ingress-nginx)。然而,随着 Kubernetes 部署的成熟,一些企业发现他们需要在将 NGINX 作为数据平面的同时,添加一些高级功能或商业支持。

一种选择是迁移到由 F5 NGINX 开发和维护的 NGINX Ingress Controller (nginxinc/kubernetes-ingress),我们为此提供了完整的说明,可以帮助您避免因两个项目的差异而引起的一些复杂问题。

不确定这两个项目有何不同?那您不妨参考一下我们的博文:《Ingress Controller 选购指南,第四部分:NGINX Ingress Controller 选项》

为了便于在接下来的内容中区分这两个项目,我们将 Kubernetes 社区维护的 NGINX Ingress Controller (kubernetes/ingress-nginx) 称为“社区版 Ingress Controller”,将 F5 NGINX 维护的 Ingress controller (nginxinc/kubernetes-ingress) 称为 “NGINX Ingress Controller”。

从社区版 Ingress Controller 迁移到 NGINX Ingress Controller 有两种方法:

 

选项 1:使用 NGINX Ingress 资源进行迁移

在该迁移选项下,您可以使用标准 Kubernetes Ingress 资源设置根功能,并用 NGINX Ingress 资源借助更多的功能和出色的易用性来增强配置。

面向 NGINX Ingress 资源的自定义资源定义 (CRD)(VirtualServer、VirtualServerRouteTransportServerGlobalConfigurationPolicy)使您轻松将各个部分的配置控制权委派给不同的团队(比如 AppDev 和安全团队),同时实现更高的配置安全性和更出色的验证。

配置 SSL 终止和基于 HTTP 路径的路由

下表将标准 Kubernetes Ingress 资源的 spec 字段中的 SSL 卸载和基于七层路径的路由配置,与 NGINX VirtualServer 资源的 spec 字段进行了对照。两个资源的语法和缩进格式略有不同,但是都完成了相同的基本 Ingress 功能。

Kubernetes Ingress 资源 NGINX VirtualServer 资源
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-test
spec:
  tls:
    - hosts:
      - foo.bar.com
      secretName: tls-secret
  rules:
    - host: foo.bar.com
      http:
        paths:
        - path: /login
          backend: 
            serviceName: login-svc
            servicePort: 80
        - path: /billing
            serviceName: billing-svc
            servicePort: 80
apiVersion: networking.k8s.io/v1
kind: VirtualServer
metadata:
  name: nginx-test
spec:
  host: foo.bar.com 
  tls:
    secret: tls-secret
  upstreams:
    - name: login
      service: login-svc
      port: 80
    - name: billing 
      service: billing-svc
      port: 80
  routes: 
  - path: /login
    action:
      pass: login 
  - path: /billing 
    action: 
      pass: billing

配置 TCP/UDP 负载均衡和 TLS Passthrough

使用社区版 Ingress Controller 时,Kubernetes ConfigMap API 对象是暴露 TCP 和 UDP 服务的唯一途径

使用 NGINX Ingress Controller 时,TransportServer 资源为 TCP/UDP 和 TLS Passthrough 负载均衡定义了一系列广泛的选项。TransportServer 资源与 GlobalConfiguration 资源一起使用,以控制出入站连接。

有关更多信息,请参阅我们的博文:《使用 NGINX Ingress 资源支持 TCP、UDP 和 TLS Passthrough 服务》

将社区版 Ingress Controller 注解转换为 NGINX Ingress 资源

生产级 Kubernetes 部署通常需要扩展基础 Ingress 规则来实施高级用例,包括灰度部署、蓝绿部署、流量控制、出入向流量操作等。

社区版 Ingress Controller 使用 Kubernetes 注解(Annotation)实施这些用例。但是,其中许多注解是使用自定义 Lua 扩展构建的,这些扩展与非常特定的 NGINX Ingress 资源定义有关,因此不适合在受支持的稳定生产环境中实施高级功能。

在接下来的几节中,我们将展示如何将社区版 Ingress Controller 注解转换为 NGINX Ingress Controller 资源。

灰度部署

当您需要对生产环境下的容器负载进行频繁的代码改动时(换句话说,发布 App 版本更新时),也必须继续为现有用户服务。灰度部署和蓝绿部署可以帮助您做到这一点,您可以在 NGINX Ingress Controller 数据平面上实施这些部署方法,以便在生产级 Kubernetes 环境中实现稳定且可预测的更新。

下表显示了在灰度部署中,NGINX VirtualServer 和 VirtualServerRoute 资源中的字段与社区版 Ingress Controller 注解的对应关系。

社区版 Ingress Controller 按照以下优先顺序评估灰度部署的注解:

  1. nginx.ingress.kubernetes.io/canary-by-header
  2. nginx.ingress.kubernetes.io/canary-by-cookie
  3. nginx.ingress.kubernetes.io/canary-by-weight

为了使 NGINX Ingress Controller 以同样的方式评估它们,它们必须按照在 NGINX VirtualServer 或 VirtualServerRoute manifest 中的顺序排列。

社区版 Ingress Controller NGINX Ingress Controller
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "httpHeader"
matches:
- conditions:
  - header: httpHeader
      value: never
  action:
    pass: echo 
  - header: httpHeader
      value: always
  action:
    pass: echo-canary
action:
  pass: echo
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "httpHeader"
nginx.ingress.kubernetes.io/canary-by-header-value: "my-value"
matches:
- conditions:
  - header: httpHeader
      value: my-value
  action:
    pass: echo-canary 
action:
  pass: echo
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-cookie: "cookieName"
matches:
- conditions:
  - cookie: cookieName
      value: never
  action:
    pass: echo 
  - cookie: cookieName
      value: always
  action:
    pass: echo-canary
action:
  pass: echo
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"
splits:
- weight: 90 
  action:
    pass: echo
- weight: 10 
   action:
     pass: echo-canary

流量控制

在微服务环境中,应用本质上是短暂的,因此更有可能返回错误响应。DevOps 团队广泛使用流量控制策略(比如断路、速率和连接限制)来防止应用出现不健康或运行不正常的错误情况。

下表显示了在速率限制自定义 HTTP 错误自定义默认后端URI 重写用例中,NGINX VirtualServer 和 VirtualServerRoute 资源中的字段与社区版 Ingress Controller 注解的对应关系。

社区版 Ingress Controller NGINX Ingress Controller

nginx.ingress.kubernetes.io/custom-http-errors: "code"

nginx.ingress.kubernetes.io/default-backend: "default-svc"
errorPages:
- codes: [code]
    redirect:
      code: 301
      url: default-svc

nginx.ingress.kubernetes.io/limit-connections: "number"
http-snippets: |
    limit_conn_zone $binary_remote_addr zone=zone_name:size;
routes:
- path: /path
    location-snippets: |
      limit_conn zone_name number;

nginx.ingress.kubernetes.io/limit-rate: "number"
nginx.ingress.kubernetes.io/limit-rate-after: "number"
location-snippets: |
    limit_rate number;

    limit_rate_after number;

nginx.ingress.kubernetes.io/limit-rpm: "number"
nginx.ingress.kubernetes.io/limit-burst-multiplier: "multiplier"
rateLimit:
    rate: numberr/m

    burst: number * multiplier
    key: ${binary_remote_addr}
    zoneSize: size

nginx.ingress.kubernetes.io/limit-rps: "number"
nginx.ingress.kubernetes.io/limit-burst-multiplier: "multiplier"
rateLimit:
    rate: numberr/s

    burst: number * multiplier
    key: ${binary_remote_addr}
    zoneSize: size
nginx.ingress.kubernetes.io/limit-whitelist: "CIDR"
http-snippets: |
server-snippets: |
nginx.ingress.kubernetes.io/rewrite-target: "URI"
rewritePath: "URI"

如该表所示,截至撰写本文之时,NGINX Ingress 资源不包括能够直接转换以下四个社区版 Ingress Controller 注解的字段,并且您必须使用代码段。未来版本的 NGINX Ingress Controller 计划使用 Policy 资源提供对这四个注解的直接支持。

  • nginx.ingress.kubernetes.io/limit-connections
  • nginx.ingress.kubernetes.io/limit-rate
  • nginx.ingress.kubernetes.io/limit-rate-after
  • nginx.ingress.kubernetes.io/limit-whitelist

请求头修改

HTTP 请求头修改在许多用例中都很有用,因为它们包含一些对 HTTP 事务相关系统来说十分重要且息息相关的附加信息。例如,社区版 Ingress Controller 支持启用和设置 AJAX 应用常用的跨域资源共享 (CORS) 请求头,它可以将来自浏览器的前端 JavaScript 代码连接到后端应用或 Web 服务器。

下表显示了在请求头修改用例中,NGINX VirtualServer 和 VirtualServerRoute 资源中的字段与社区版 Ingress Controller 注解的对应关系。

社区版 Ingress Controller NGINX Ingress Controller
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"

nginx.ingress.kubernetes.io/cors-allow-headers: "X-Forwarded-For" 

nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"

nginx.ingress.kubernetes.io/cors-allow-origin: "*"

nginx.ingress.kubernetes.io/cors-max-age: "seconds"
responseHeaders:
  add: 
    - name: Access-Control-Allow-Credentials
      value: "true" 
    - name: Access-Control-Allow-Headers
      value: "X-Forwarded-For"
    - name: Access-Control-Allow-Methods
      value: "PUT, GET, POST, OPTIONS"
    - name: Access-Control-Allow-Origin
      value: "*"
    - name: Access-Control-Max-Age
      value: "seconds"

代理和负载均衡

在特定的用例中,您可能还想在 NGINX Ingress Controller 中配置其他代理和负载均衡功能,包括设置负载均衡算法以及代理连接的超时和缓冲等。

下表显示了在自定义 NGINX 负载均衡代理超时代理缓冲以及将连接路由到 service 集群的 IP 地址和端口用例中,NGINX VirtualServer 和 VirtualServerRoute 资源中的 upstream 字段的语句与社区版 Ingress Controller 注解的对应关系。

社区版 Ingress Controller NGINX Ingress Controller
nginx.ingress.kubernetes.io/load-balance
lb-method
nginx.ingress.kubernetes.io/proxy-buffering
buffering
nginx.ingress.kubernetes.io/proxy-buffers-number
nginx.ingress.kubernetes.io/proxy-buffer-size
buffers
nginx.ingress.kubernetes.io/proxy-connect-timeout
connect-timeout
nginx.ingress.kubernetes.io/proxy-next-upstream
next-upstream
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout
next-upstream-timeout
nginx.ingress.kubernetes.io/proxy-read-timeout
read-timeout
nginx.ingress.kubernetes.io/proxy-send-timeout
send-timeout
nginx.ingress.kubernetes.io/service-upstream
use-cluster-ip

mTLS 身份验证

Service mesh(服务网格)在严格的零信任环境中尤为有用,在这种环境中,集群内的分布式应用通过双向身份验证进行安全通信。如果我们需要在进出集群的流量(南北向流量)上施加同样级别的安全性,该怎么办?

我们可以在 Ingress controller 层上配置 mTLS 身份验证,这样外部连接的终端系统就可以通过呈现有效的证书来相互验证了。

下表显示了在客户端证书身份验证后端证书身份验证中,NGINX Policy 资源中的字段与社区版 Ingress Controller 注解的对应关系。

社区版 Ingress Controller NGINX Ingress Controller

nginx.ingress.kubernetes.io/auth-tls-secret: secretName
nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
ingressMTLS:
   clientCertSecret: secretName
   verifyClient: "on"

   verifyDepth: 1

nginx.ingress.kubernetes.io/proxy-ssl-secret: "secretName"
nginx.ingress.kubernetes.io/proxy-ssl-verify: "on|off"
nginx.ingress.kubernetes.io/proxy-ssl-verify-depth: "1"
nginx.ingress.kubernetes.io/proxy-ssl-protocols: "TLSv1.2"
nginx.ingress.kubernetes.io/proxy-ssl-ciphers: "DEFAULT"
nginx.ingress.kubernetes.io/proxy-ssl-name: "server-name"
nginx.ingress.kubernetes.io/proxy-ssl-server-name: "on|off"
egressMTLS:
   tlsSecret: secretName

   verifyServer: true|false

   verifyDepth: 1

   protocols: TLSv1.2

   ciphers: DEFAULT

   sslName: server-name

   serverName: true|false

会话保持(NGINX Plus 独有)

下表显示了在会话保持 (affinity) 中,基于 NGINX Plus 的 NGINX Ingress Controller 独有的 NGINX Policy 资源中的字段及其与社区版 Ingress Controller 注解的对应关系。

社区版 Ingress Controller NGINX Ingress Controller

nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "cookieName"
nginx.ingress.kubernetes.io/session-cookie-expires: "x"
nginx.ingress.kubernetes.io/session-cookie-path: "/route"
nginx.ingress.kubernetes.io/session-cookie-secure: "true"
sessionCookie:
  enable: true

  name: cookieName

  expires: xh

  path: /route

  secure: true

 

选项 2:使用 Kubernetes Ingress 资源进行迁移

从社区版 Ingress Controller 迁移到 NGINX Ingress Controller 的第二种方法是,在标准 Kubernetes Ingress 资源中仅使用注解ConfigMaps ,并且可能还会依赖于 master/minion 式的处理。这将所有配置都保留在了 Ingress 对象中。

注:在使用这种方法时,不要更改 Ingress 资源的 spec 字段。

使用注解进行高级配置

下表列出了与 NGINX Ingress Controller 支持的注解直接对应的社区版 Ingress Controller。

社区版 Ingress Controller NGINX Ingress Controller NGINX 指令
nginx.ingress.kubernetes.io/configuration-snippet: |
nginx.org/location-snippets: |
N/A
nginx.ingress.kubernetes.io/load-balance1
nginx.org/lb-method
Default:

random two least_conn
nginx.ingress.kubernetes.io/proxy-buffering: "on|off"
nginx.org/proxy-buffering: "True|False"
proxy_buffering
nginx.ingress.kubernetes.io/proxy-buffers-number: "number"
nginx.ingress.kubernetes.io/proxy-buffer-size: "xk"
nginx.org/proxy-buffers: "number 4k|8k"
nginx.org/proxy-buffer-size: "4k|8k"
proxy_buffers

proxy_buffer_size
nginx.ingress.kubernetes.io/proxy-connect-timeout: "seconds"
nginx.org/proxy-connect-timeout: : "secondss"
proxy_connect_timeout
nginx.ingress.kubernetes.io/proxy-read-timeout: "seconds"
nginx.org/proxy-read-timeout: "secondss"
proxy_read_timeout
nginx.ingress.kubernetes.io/proxy-send-timeout: "seconds"
nginx.org/proxy-send-timeout: "secondss"
proxy_send_timeout
nginx.ingress.kubernetes.io/rewrite-target: "URI"
nginx.org/rewrites: "serviceName=svc rewrite=URI"
rewrite
nginx.ingress.kubernetes.io/server-snippet: |
nginx.org/server-snippets: |
N/A
nginx.ingress.kubernetes.io/ssl-redirect: "true|false"
ingress.kubernetes.io/ssl-redirect: "True|False"
N/A2

1 社区版 Ingress Controller 使用 Lua 实施一些负载均衡算法。NGINX Ingress Controller 对此没有对等的机制。

2 将 HTTP 流量重定向到 HTTPS。对此,社区版 Ingress Controller 使用的是 Lua 代码,而 NGINX Ingress Controller 使用了原生的 NGINX if 条件语句。

下表列出了与基于 NGINX Plus 的 NGINX Ingress Controller 支持的注解直接对应的社区版 Ingress Controller 注解。

社区版 Ingress Controller 基于 NGINX Plus 的 NGINX Ingress Controller
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "cookie_name"
nginx.ingress.kubernetes.io/session-cookie-expires: "seconds"
nginx.ingress.kubernetes.io/session-cookie-path: "/route"
nginx.com/sticky-cookie-services: "serviceName=example-svc cookie_name expires=time path=/route"

注:基于 NGINX Plus 的 NGINX Ingress Controller 还有其他注解,能够实现社区版 Ingress Controller 根本不支持的一些功能,包括主动健康检查以及使用 JSON Web Token (JWT) 进行身份验证。

使用 ConfigMaps 进行全局配置

下表对照了社区版 Ingress Controller 的 ConfigMap 键以及与其直接对应的 NGINX Ingress Controller ConfigMap 键。请注意,有少数 ConfigMap 键名是相同的。另外,社区版 Ingress Controller 和 NGINX Ingress Controller 都具有对方所没有的 ConfigMap 键(表中未显示)。

社区版 Ingress Controller NGINX Ingress Controller
disable-access-log
access-log-off
error-log-level
error-log-level
hsts
hsts
hsts-include-subdomains
hsts-include-subdomains
hsts-max-age
hsts-max-age
http-snippet
http-snippets
keep-alive
keepalive-timeout
keep-alive-requests
keepalive-requests
load-balance
lb-method
location-snippet
location-snippets
log-format-escape-json: "true"
log-format-escaping: "json"
log-format-stream
stream-log-format
log-format-upstream
log-format
main-snippet
main-snippets
max-worker-connections 
worker-connections
max-worker-open-files
worker-rlimit-nofile
proxy-body-size
client-max-body-size
proxy-buffering
proxy-buffering
proxy-buffers-number: "number"
proxy-buffer-size: "size"
proxy-buffers: number size
proxy-connect-timeout
proxy-connect-timeout
proxy-read-timeout
proxy-read-timeout
proxy-send-timeout
proxy-send-timeout
server-name-hash-bucket-size
server-names-hash-bucket-size
server-name-hash-max-size
server-names-hash-max-size
server-snippet
server-snippets
server-tokens
server-tokens
ssl-ciphers
ssl-ciphers
ssl-dh-param
ssl-dhparam-file
ssl-protocols
ssl-protocols
ssl-redirect
ssl-redirect
upstream-keepalive-connections
keepalive
use-http2
http2
use-proxy-protocol
proxy-protocol
variables-hash-bucket-size
variables-hash-bucket-size
worker-cpu-affinity
worker-cpu-affinity
worker-processes
worker-processes
worker-shutdown-timeout
worker-shutdown-timeout

 

结语

您可以使用自定义 NGINX Ingress 资源或带注解和 ConfigMap 的标准 Kubernetes Ingress 资源从社区版 Ingress Controller 迁移到 NGINX Ingress Controller。前者支持更广泛的网络功能,因此更适合生产级 Kubernetes 环境。

立即体验基于 NGINX Plus 的 NGINX Ingress Controller 的 30 天免费试用版,或者联系我们讨论您的用例

Hero image
Kubernetes:
从测试到生产

通过多种流量管理工具提升弹性、可视性和安全性

关于作者

Amir Rawdat

解决方案工程师

Amir Rawdat 是 NGINX 的技术营销工程师,专门负责各种技术内容的撰写。他在计算机网络、计算机编程、故障排除和内容撰写方面拥有深厚的背景。此前,Amir 是诺基亚(Nokia)的客户应用工程师。

关于 F5 NGINX

F5, Inc. 是备受欢迎的开源软件 NGINX 背后的商业公司。我们为现代应用的开发和交付提供一整套技术。我们的联合解决方案弥合了 NetOps 和 DevOps 之间的横沟,提供从代码到用户的多云应用服务。访问 nginx-cn.net 了解更多相关信息。