NSX负载均衡器与 OpenShift 集成,并充当 OpenShift 路由器。

NCP 监视 OpenShift 路由和端点事件,并根据路由规范在负载均衡器上配置负载均衡规则。因此,NSX负载均衡器会根据规则将入站第 7 层流量转发到适当的后端容器。

配置负载均衡需要配置 Kubernetes LoadBalancer 服务或 OpenShift 路由。此外,还需要配置 NCP 复制控制器。LoadBalancer 服务用于第 4 层流量,而 OpenShift 路由用于第 7 层流量。

配置 Kubernetes LoadBalancer 服务时,会从您配置的外部 IP 块为该服务分配一个 IP 地址。会在此 IP 地址和服务端口上公开负载均衡器。可以使用 loadBalancerIP 规范在 LoadBalancer 定义中指定 IP 池的名称或 ID。将从该 IP 池分配 Loadbalancer 服务的 IP。如果 loadBalancerIP 规范为空,将从您配置的外部 IP 块分配 IP。

loadBalancerIP 指定的 IP 池必须具有标记 scope: ncp/owner, tag: cluster:<cluster_name>

要使用 NSX 负载均衡器,必须在 NCP 中配置负载均衡。在 ncp_rc.yml 文件中,执行以下操作:

  1. use_native_loadbalancer 设置为 True
  2. pool_algorithm 设置为 WEIGHTED_ROUND_ROBIN
  3. lb_default_cert_pathlb_priv_key_path 分别设置为 CA 签名证书文件和私钥文件的完整路径名称。有关用于生成 CA 签名证书的示例脚本,请参见下文。此外,将默认证书和密钥挂载到 NCP pod 中。有关说明,请参见下文。
  4. (可选)使用参数 l4_persistencel7_persistence 指定持久性设置。可用于设置第 4 层持久性的选项为源 IP。可用于设置第 7 层持久性的选项为 cookie 和源 IP。默认值为 <None>。例如,
       # Choice of persistence type for ingress traffic through L7 Loadbalancer.
       # Accepted values:
       # 'cookie'
       # 'source_ip'
       l7_persistence = cookie
    
       # Choice of persistence type for ingress traffic through L4 Loadbalancer.
       # Accepted values:
       # 'source_ip'
       l4_persistence = source_ip
  5. (可选)将 service_size 设置为 SMALLMEDIUMLARGE。默认值为 SMALL
  6. 如果运行的是 OpenShift 3.11,则必须执行以下配置,OpenShift 才不会向 LoadBalancer 服务分配 IP。
    • /etc/origin/master/master-config.yaml 文件中的 networkConfig 下,将 ingressIPNetworkCIDR 设置为 0.0.0.0/32。
    • 使用以下命令重新启动 API 服务器和控制器:
         master-restart api
         master-restart controllers

对于 Kubernetes LoadBalancer 服务,如果禁用了全局第 4 层持久性(即 l4_persistence 设置为 <None>),您还可以在服务规范上指定 sessionAffinity 以配置服务持久性行为。如果 l4_persistence 设置为 source_ip,则可以使用服务规范上的 sessionAffinity 自定义服务持久性超时。默认第 4 层持久性超时为 10800 秒,与 Kubernetes 文档 (https://kubernetes.io/docs/concepts/services-networking/service) 中指定的服务超时相同。具有默认持久性超时的所有服务将使用相同的 NSX 负载均衡器持久性配置文件。将为每个具有非默认持久性超时的服务创建专用的配置文件。

注: 如果 Ingress 的后端服务的服务类型为 LoadBalancer,则该服务的第 4 层虚拟服务器和 Ingress 的第 7 层虚拟服务器不能具有不同的持久性设置,例如,对于第 4 层,采用 source_ip,而对于第 7 层,采用 cookie。在这种场景下,这两个虚拟服务器的持久性设置必须相同( source_ipcookieNone),或者其中一个为 None(另一个的设置可以为 source_ipcookie)。下面列出了这种场景的一个示例:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: cafe-ingress
spec:
  rules:
  - host: cafe.example.com
    http:
      paths:
      - path: /tea
        backend:
          serviceName: tea-svc
          servicePort: 80
-----
apiVersion: v1
kind: Service
metadata:
  name: tea-svc <==== same as the Ingress backend above
  labels:
    app: tea
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: tcp
  selector:
    app: tea
  type: LoadBalancer

路由器分片

在 OpenShift 4 中,每个路由可以在其元数据字段中具有任意数量的标签。路由器使用选择器从整个路由池中选择一部分路由。选择的路由可能还涉及路由的命名空间上的标签。选定的路由组成一个路由分片。

您可能出于如下目的创建路由分片:
  • 根据路由标签或命名空间配置 Ingress。
  • 为应用程序配置不同的路由。
  • 在多个负载均衡器服务之间分配工作负载以提高性能。

该功能仅支持对第 7 层负载均衡器服务进行分片。

配置路由器分片的步骤如下所示:
  1. configmap.yaml[k8s] 部分中将 enable_lb_crd 选项设置为 True,并应用该 YAML 文件。创建并应用一个定义 LoadBalancer CRD (CustomResourceDefinition) 的 YAML 文件。例如,
    apiVersion: vmware.com/v1alpha1
    kind: LoadBalancer
    metadata:
        name: lbs-crd-1
    spec:
        httpConfig:
            virtualIP: 192.168.4.4          # VIP for HTTP/HTTPS server. Default to auto_allocate
            port: 81                        # HTTP port number. Default to 80
            tls:
                port: 9998                  # HTTPS port number. default to 443
                secretName: default_secret  # Default certificate for HTTPS server. Default to nil
                secretNamespace: default    # Need to be set with secretName
            xForwardedFor: INSERT           # Available values are INSERT, REPLACE. Default to nil
            affinity:
                type: source_ip             # Available values are sourceIP, cookie
                timeout: 100                # Default to 10800
        size: MEDIUM                        # Default to SMALL
  2. 运行以下命令,以配置一个具有命名空间标签选择器的路由器(假设路由器的 dc/svc 是 router):
    oc set env dc/router NAMESPACE_LABELS="router=r1"
  3. 上一步中配置的路由器将处理选定命名空间中的路由。要使该选择器与一个命名空间匹配,请相应地标记该命名空间。例如,
    apiVersion: v1
    kind: Route
    metadata:
      name: cafe-route
      annotations:
        nsx/loadbalancer: lbs-crd-1
    spec:
      host: cafe.example.com
      to:
        kind: Service
        name: tea-svc
        weight: 1
    运行以下命令:
    oc label namespace targetns "router=r1"
    将 targetns 替换为目标路由所在的确切命名空间。例如,
    apiVersion: v1
    kind: Namespace
    metadata:
        name: qe
        annotations:
            nsx/loadbalancer: lbs-crd-1

    注意:如果命名空间中的路由具有另一个注释,则路由注释优先。

第 7 层负载均衡器示例

以下 YAML 文件会配置两个复制控制器(tea-rc 和 coffee-rc)、两个服务(tea-svc 和 coffee-svc)以及两个路由(cafe-route-multi 和 cafe-route),以提供第 7 层负载均衡。
# RC
apiVersion: v1
kind: ReplicationController
metadata:
  name: tea-rc
spec:
  replicas: 2
  template:
    metadata:
       labels:
         app: tea
    spec:
      containers:
      - name: tea
        image: nginxdemos/hello
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: ReplicationController
metadata:
  name: coffee-rc
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: coffee
    spec:
      containers:
      - name: coffee
        image: nginxdemos/hello
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
---
# Services
apiVersion: v1
kind: Service
metadata:
  name: tea-svc
  labels:
    app: tea
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  selector:
    app: tea
---
apiVersion: v1
kind: Service
metadata:
  name: coffee-svc
  labels:
    app: coffee
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  selector:
    app: coffee
---
# Routes
apiVersion: v1
kind: Route
metadata:
  name: cafe-route-multi
spec:
  host: www.cafe.com
  path: /drinks
  to:
    kind: Service
    name: tea-svc
    weight: 1
  alternateBackends:
  - kind: Service
    name: coffee-svc
    weight: 2
---
apiVersion: v1
kind: Route
metadata:
  name: cafe-route
spec:
  host: www.cafe.com
  path: /tea-svc
  to:
    kind: Service
    name: tea-svc
    weight: 1

其他说明

  • 支持所有终止模式:edgepassthroughreencrypt
  • 支持通配符子域。例如,如果 wildcardPolicy 设置为 Subdomain,且主机名设置为 wildcard.example.com,则会处理针对 *.example.com 的任何请求。
  • 如果 NCP 在处理路由事件期间由于配置错误而引发错误,则需要更正路由 YAML 文件,删除并重新创建 Route 资源。
  • NCP 不按命名空间实施主机名所有权。
  • 每个 Kubernetes 集群支持一个 Loadbalancer 服务。
  • NSX 将为每个 LoadBalancer 服务端口创建一个第 4 层负载均衡器虚拟服务器和池。TCP 和 UDP 均受支持。
  • NSX 负载均衡器有多种不同大小。有关配置 NSX 负载均衡器的信息,请参见NSX 管理指南

    创建负载均衡器后,无法通过更新配置文件来更改负载均衡器大小,但是可以通过 UI 或 API 进行更改。

  • 支持自动缩放第 4 层负载均衡器。如果创建或修改 Kubernetes LoadBalancer 服务以便需要更多的虚拟服务器,而现有的第 4 层负载均衡器没有足够的容量,将创建新的第 4 层负载均衡器。NCP 也将删除不再连接虚拟服务器的第 4 层负载均衡器。默认情况下,将启用该功能。可以通过在 NCP ConfigMap 中将 l4_lb_auto_scaling 设置为 false 禁用此功能。
  • 在路由规范中,参数 destinationCACertificate 不受支持,且将被 NCP 忽略。
  • 每个 TLS 路由必须具有不同的 CA 签名证书。
  • 如果不希望 NSX 负载均衡器管理路由,请将注释 use_nsx_controller:False 添加到路由规范中。

用于生成 CA 签名证书的示例脚本

以下脚本可分别生成存储在文件 <filename>.crt 和 <finename>.key 中的 CA 签名证书和私钥。 genrsa 命令可生成 CA 密钥。应对 CA 密钥进行加密。您可以使用 aes256 等命令指定加密方法。
#!/bin/bash
host="www.example.com"
filename=server

openssl genrsa -out ca.key 4096
openssl req -key ca.key -new -x509 -days 365 -sha256 -extensions v3_ca -out ca.crt -subj "/C=US/ST=CA/L=Palo Alto/O=OS3/OU=Eng/CN=${host}"
openssl req -out ${filename}.csr -new -newkey rsa:2048 -nodes -keyout ${filename}.key -subj "/C=US/ST=CA/L=Palo Alto/O=OS3/OU=Eng/CN=${host}"
openssl x509 -req -days 360 -in ${filename}.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out ${filename}.crt -sha256