Il bilanciamento del carico di NSX è integrato con OpenShift e agisce come router di OpenShift.

NCP controlla gli eventi di routing ed endpoint di OpenShift e configura regole di bilanciamento del carico nel bilanciamento del carico in base alla specifica della route. Di conseguenza, il bilanciamento del carico di NSX inoltrerà il traffico di livello 7 in entrata ai pod back-end appropriati in base alle regole.

La configurazione del bilanciamento del carico implica la configurazione di un servizio LoadBalancer Kubernetes o di una route OpenShift. È inoltre necessario configurare il controller di replica di NCP. Il servizio LoadBalancer è per il traffico di livello 4 e la route OpenShift è per il traffico di livello 7.

Quando si configura un servizio LoadBalancer Kubernetes, a tale servizio viene allocato un indirizzo IP dal blocco di IP esterno configurato. Il bilanciamento del carico è esposto su questo indirizzo IP e sulla porta del servizio. È possibile specificare il nome o l'ID di un pool di IP utilizzando la specifica loadBalancerIP nella definizione di LoadBalancer. L'IP del servizio LoadBalancer verrà allocato da questo pool di IP. Se la specifica loadBalancerIP è vuota, l'IP verrà allocato dal blocco di IP esterno configurato.

Il pool di IP specificato da loadBalancerIP deve avere il tag scope: ncp/owner, tag: cluster:<cluster_name>.

Per utilizzare il bilanciamento del carico di NSX, è necessario configurare il bilanciamento del carico in NCP. Nel file ncp_rc.yml, eseguire le operazioni seguenti:

  1. Impostare use_native_loadbalancer = True.
  2. Impostare pool_algorithm su WEIGHTED_ROUND_ROBIN.
  3. Impostare lb_default_cert_path e lb_priv_key_path come nomi dei percorsi completi del file del certificato firmato dall'autorità di certificazione e del file della chiave privata, rispettivamente. Per uno script di esempio per generare un certificato firmato dall'autorità di certificazione, vedere di seguito. Montare inoltre il certificato e la chiave predefiniti nel pod NCP. Per istruzioni, vedere di seguito.
  4. (Facoltativo) Specificare un'impostazione di persistenza con i parametri l4_persistence e l7_persistence. L'opzione disponibile per la persistenza di livello 4 è l'IP di origine. Le opzioni disponibili per la persistenza di livello 7 sono cookie e IP di origine. Il valore predefinito è <None>. Ad esempio,
       # 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. (Facoltativo) Impostare service_size = SMALL, MEDIUM o LARGE. Il valore predefinito è SMALL.
  6. Se si esegue OpenShift 3.11, è necessario eseguire la configurazione seguente in modo che OpenShift non assegni un IP al servizio LoadBalancer.
    • Impostare ingressIPNetworkCIDR su 0.0.0.0/32 in networkConfig nel file /etc/origin/master/master-config.yaml.
    • Riavviare il server e i controller dell'API con i comandi seguenti:
         master-restart api
         master-restart controllers

Per un servizio LoadBalancer Kubernetes, è inoltre possibile specificare sessionAffinity nella specifica del servizio per configurare il comportamento della persistenza per il servizio se la persistenza di livello 4 globale è disattivata, ovvero se l'opzione l4_persistence è impostata su <None>. Se l'opzione l4_persistence è impostata su source_ip, è possibile utilizzare sessionAffinity nella specifica del servizio per personalizzare il timeout della persistenza per il servizio. Il timeout della persistenza del livello 4 predefinito è 10800 secondi (uguale a quello specificato nella documentazione di Kubernetes per i servizi (https://kubernetes.io/docs/concepts/services-networking/service). Tutti i servizi con timeout della persistenza predefinito condivideranno lo stesso profilo di persistenza del bilanciamento del carico di NSX. Verrà creato un profilo dedicato per ogni servizio con timeout della persistenza non predefinito.

Nota: Se il servizio back-end di un ingresso è un servizio di tipo LoadBalancer, il server virtuale di livello 4 per il servizio e il server virtuale di livello 7 per l'ingresso non possono avere impostazioni di persistenza diverse, ad esempio source_ip per il livello 4 e cookie per il livello 7. In questo scenario le impostazioni della persistenza per entrambi i server virtuali devono essere uguali ( source_ip, cookie o None) oppure una delle impostazioni è None (quindi l'altra impostazione può essere source_ip o cookie). Un esempio di questo scenario:
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

Partizionamento del router

In OpenShift 4 ogni route può avere un numero qualsiasi di etichette nel campo dei metadati. Un router utilizza i selettori per selezionare un sottoinsieme di route dall'intero pool di route. Una selezione può anche coinvolgere etichette negli spazi dei nomi della route. Le route selezionate costituiscono una partizione di route.

È possibile creare partizioni di route per scopi come i seguenti:
  • Configurare l'ingresso in base alle etichette o agli spazi dei nomi delle route.
  • Configurare route diverse per le applicazioni.
  • Distribuire il carico di lavoro in più servizi di bilanciamento del carico per migliorare le prestazioni.

Questa funzionalità supporta solo il partizionamento dei servizi di bilanciamento del carico di livello 7.

Passaggi per configurare il partizionamento del router:
  1. Impostare l'opzione enable_lb_crd su True nella sezione [k8s] di configmap.yaml e applicare il file YAML. Creare e applicare un file YAML che definisca un CRD (CustomResourceDefinition) di LoadBalancer. Ad esempio,
    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. Configurare un router con un selettore di etichetta dello spazio dei nomi eseguendo il comando seguente (supponendo che dc/svc del router sia router):
    oc set env dc/router NAMESPACE_LABELS="router=r1"
  3. Il router configurato nel passaggio precedente gestirà le route dagli spazi dei nomi selezionati. Per fare in modo che il selettore corrisponda a uno spazio dei nomi, etichettare lo spazio dei nomi di conseguenza. Ad esempio,
    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
    Eseguire il comando seguente:
    oc label namespace targetns "router=r1"
    Sostituire la destinazione con lo spazio dei nomi esatto in cui si trovano le route di destinazione. Ad esempio,
    apiVersion: v1
    kind: Namespace
    metadata:
        name: qe
        annotations:
            nsx/loadbalancer: lbs-crd-1

    Nota: se una route in uno spazio dei nomi include un'altra annotazione, l'annotazione della route ha la precedenza.

Esempio di bilanciamento del carico di livello 7

Il seguente file YAML configura due controller di replica (tea-rc e coffee-rc), due servizi (tea-svc e coffee-svc) e due route (cafe-route-multi e cafe-route) per fornire un bilanciamento del carico di livello 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

Note aggiuntive

  • Sono supportate tutte le modalità di terminazione: edge, passthrough e reencrypt.
  • Sottodominio con caratteri jolly supportato. Ad esempio, se wildcardPolicy è impostato su Subdomain e il nome host è impostato su wildcard.example.com, qualsiasi richiesta di *.example.com verrà elaborata.
  • Se NCP genera un errore durante l'elaborazione di un evento Route a causa di una configurazione errata, è necessario correggere il file YAML della route, eliminare e ricreare la risorsa Route.
  • NCP non applica la proprietà del nome host in base agli spazi dei nomi.
  • Per ogni cluster Kubernetes, è supportato un servizio LoadBalancer.
  • NSX creerà un server virtuale e un pool di bilanciamento del carico di livello 4 per ogni porta del servizio LoadBalancer. TCP e UDP sono entrambi supportati.
  • Il bilanciamento del carico di NSX è disponibile in dimensioni diverse. Per informazioni sulla configurazione di un bilanciamento del carico di NSX, vedere la Guida all'amministrazione di NSX.

    Dopo aver creato il bilanciamento del carico, le dimensioni del bilanciamento del carico non possono essere modificate aggiornando il file di configurazione. Possono essere modificate tramite l'interfaccia utente o l'API.

  • È supportata la scalabilità automatica del bilanciamento del carico di livello 4. Se un servizio LoadBalancer Kubernetes viene creato o modificato in modo da richiedere server virtuali aggiuntivi e il bilanciamento del carico di livello 4 esistente non ha la capacità adeguata, verrà creato un nuovo bilanciamento del carico di livello 4. NCP eliminerà anche un bilanciamento del carico di livello 4 che non ha più server virtuali collegati. Questa funzionalità è abilitata per impostazione predefinita. È possibile disabilitarla impostando l4_lb_auto_scaling su false nella ConfigMap di NCP.
  • Nella specifica di una route il parametro destinationCACertificate non è supportato e verrà ignorato da NCP.
  • Ogni route TLS deve avere un certificato firmato dall'autorità di certificazione diverso.
  • Se non si desidera che il bilanciamento del carico di NSX gestisca le route, aggiungere l'annotazione use_nsx_controller:False alla specifica della route.

Script di esempio per la generazione di un certificato firmato dall'autorità di certificazione

Lo script seguente genera un certificato firmato dall'autorità di certificazione e una chiave privata archiviata nei file <nomefile>.crt e <nomefile>.key, rispettivamente. Il comando genrsa genera una chiave CA. La chiave CA deve essere crittografata. È possibile specificare un metodo di crittografia con un comando come 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