Configurazione del bilanciamento del carico HTTP(S) esterno per Anthos Service Mesh gestito

Panoramica

Cloud Load Balancing offre molte funzionalità perimetrali gestite dal cloud, tra cui il bilanciamento del carico anycast globale, i certificati gestiti da Google, la gestione di identità e accessi e firewall o IDS cloud. Anthos Service Mesh può integrare perfettamente queste funzionalità perimetrali nel seguente modello mesh in entrata. Il gateway cloud del mesh di servizi fornisce un modo unificato per configurare il gateway in entrata Anthos Service Mesh con Cloud Load Balancing contemporaneamente tramite l'API Kubernetes Gateway.

Diagramma che mostra il bilanciatore del carico Cloud con Anthos Service Mesh

Rispetto alla nostra precedente guida dell'utente, Da perimetro a mesh: esposizione delle applicazioni mesh di servizi tramite GKE Ingress, con il gateway cloud del mesh di servizi, ora il deployment di questo modello può essere eseguito tramite un'unica risorsa gateway Kubernetes che semplifica il processo di deployment congiunto del bilanciamento del carico nel cloud e in un cluster.

Limitazioni per l'anteprima

Per la versione di anteprima di questa funzionalità, si applicano le seguenti limitazioni:

  • I gateway multi-cluster non sono supportati.
  • I cluster Autopilot non sono supportati.
  • È supportato solo l'Application Load Balancer classico. Il bilanciatore del carico avanzato e il bilanciatore del carico HTTP(S) interno non sono supportati.
  • Il traffico tra il bilanciatore del carico HTTP(S) esterno e il gateway in entrata di Anthos Service Mesh è criptato tramite TLS. Tuttavia, il bilanciatore del carico HTTP(S) esterno non verificherà il certificato fornito dal gateway in entrata di Anthos Service Mesh. Questa limitazione si applica a tutti gli utenti del bilanciatore del carico HTTP(S) di Google Cloud.
  • Se Anthos Service Mesh GatewayClasses viene eliminato da un cluster, non verrà reinstallato automaticamente. Tuttavia, questo non influirà sull'usabilità della funzionalità.
  • La logica di corrispondenza delle route non segue le specifiche dell'API Gateway e corrisponde nell'ordine di HTTPRoute. Questo cambierà nelle versioni future per seguire le specifiche dell'API Gateway.

Requisiti

  • Anthos Service Mesh gestito installato su un cluster Google Kubernetes Engine (GKE) che esegue la versione 1.24 o successiva. Altri cluster GKE Enterprise non sono supportati.
  • Solo la versione v1beta1 dell'API Kubernetes Gateway.

Prerequisiti

  • Abilita le seguenti API nel tuo progetto:

    • compute.googleapis.com
    • container.googleapis.com
    • certificatemanager.googleapis.com
    • serviceusage.googleapis.com
    gcloud services enable \
       compute.googleapis.com \
       container.googleapis.com \
       certificatemanager.googleapis.com \
       serviceusage.googleapis.com
    

Esegui il deployment del gateway cloud del mesh di servizi per un mesh a cluster singolo

Questa sezione mostra come eseguire il deployment di una risorsa gateway Kubernetes che esegue il deployment di un bilanciatore del carico HTTP(S) esterno globale (classico) e di un gateway in entrata Anthos Service Mesh.

Abilita API Gateway con Anthos Service Mesh gestito

  1. Abilita l'API Gateway nel cluster. La versione del cluster GKE deve essere 1.24 o successiva.

  2. Installa Anthos Service Mesh gestito con rapid o regular come canale di rilascio.

esegui il deployment della risorsa gateway

Durante il deployment di un gateway cloud mesh di servizi, le risorse del gateway Kubernetes vengono utilizzate per eseguire il deployment sia di Cloud Load Balancing sia del gateway in entrata di Anthos Service Mesh come singolo passaggio. Tieni presente che le risorse Gateway Kubernetes sono diverse dalle risorse Gateway Istio.

Per ulteriori informazioni sulle differenze, consulta Gateway Kubernetes e gateway Istio. Ogni gateway Kubernetes ha un oggetto GatewayClass che indica il tipo e le funzionalità intrinseche. Il gateway cloud della mesh di servizi dispone di un GatewayClass che consente di eseguire il deployment sia del gateway in entrata di Cloud Load Balancing che di Anthos Service Mesh.

  1. Salva il seguente manifest di GatewayClass in un file denominato l7-gateway-class.yaml:

    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: GatewayClass
    metadata:
      name: asm-l7-gxlb
    spec:
      controllerName: mesh.cloud.google.com/gateway
    
  2. Esegui il deployment di GatewayClass nel tuo cluster:

    kubectl apply -f l7-gateway-class.yaml
    
  3. Verifica che GatewayClass sia presente dopo l'installazione:

    kubectl get gatewayclasses.gateway.networking.k8s.io
    

    L'output è simile a questo:

    NAME          CONTROLLER
    asm-l7-gxlb   mesh.cloud.google.com/gateway
    gke-l7-rilb   networking.gke.io/gateway
    gke-l7-gxlb   networking.gke.io/gateway
    

    Il deployment di tutte le risorse potrebbe richiedere alcuni minuti. Se non vedi l'output previsto, verifica di aver soddisfatto correttamente i prerequisiti.

    Vedrai anche il seguente GatewayClass:

    gke-l7-gxlb   networking.gke.io/gateway
    

    Viene utilizzato per eseguire il deployment del bilanciatore del carico HTTP(S) esterno globale di Google Cloud sottostante.

  4. Crea uno spazio dei nomi dedicato per il gateway cloud del mesh di servizi:

    kubectl create namespace istio-ingress
    
  5. Salva il seguente manifest del gateway in un file denominato gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: servicemesh-cloud-gw
      namespace: istio-ingress
    spec:
      gatewayClassName: asm-l7-gxlb
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          namespaces:
            from: All
    
  6. Esegui il deployment del gateway nel tuo cluster nello spazio dei nomi istio-ingress:

    kubectl apply -f gateway.yaml
    
  7. Verifica che gli oggetti dell'API Kubernetes Gateway siano creati:

    kubectl get gateways.gateway.networking.k8s.io -n istio-ingress
    

    L'output è simile a questo:

    NAME                                CLASS         ADDRESS         READY   AGE
    asm-gw-gke-servicemesh-cloud-gw     gke-l7-gxlb   34.111.114.64   True    9m40s
    asm-gw-istio-servicemesh-cloud-gw   istio                                 9m44s
    servicemesh-cloud-gw                asm-l7-gxlb                           9m44s
    

Quando viene eseguito il deployment di questo oggetto API Gateway Kubernetes, si verifica quanto segue:

  • Viene eseguito il deployment e la configurazione di un bilanciatore del carico HTTP(S) esterno. Potrebbero essere necessari alcuni minuti prima che venga visualizzato, ma quando succede, il gateway indicherà l'indirizzo IP e verrà annotato con i nomi delle risorse del bilanciatore del carico di Compute Engine che sono state create.
  • Nello spazio dei nomi istio-ingress viene creato un deployment del gateway in entrata di Anthos Service Mesh. In questo modo vengono create le istanze proxy Envoy che riceveranno il traffico dal bilanciatore del carico Cloud.
  • Il bilanciatore del carico Cloud cripterà e instrada tutto il traffico al gateway in entrata di Anthos Service Mesh.

Ora hai l'infrastruttura completa necessaria per accettare il traffico internet nella tua rete mesh. Tieni presente che questo è il deployment Gateway più semplice possibile. Nelle sezioni seguenti aggiungerai ulteriori criteri e funzionalità che la renderanno pronta per la produzione.

Deployment di app e routing

Per dimostrare completamente le funzionalità eseguirai il deployment di un'applicazione su Anthos Service Mesh e riceverai traffico internet tramite il tuo gateway, ad esempio per scopi.

  1. Etichetta lo spazio dei nomi default per abilitare l'inserimento di file collaterali.

    kubectl label namespace default istio-injection=enabled istio.io/rev- --overwrite
    
  2. Salva il seguente manifest del gateway in un file denominato whereami.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whereami-v1
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: whereami-v1
      template:
        metadata:
          labels:
            app: whereami-v1
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20
            ports:
              - containerPort: 8080
            env:
            - name: METADATA
              value: "whereami-v1"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: whereami-v1
    spec:
      selector:
        app: whereami-v1
      ports:
      - port: 8080
        targetPort: 8080
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whereami-v2
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: whereami-v2
      template:
        metadata:
          labels:
            app: whereami-v2
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20
            ports:
              - containerPort: 8080
            env:
            - name: METADATA
              value: "whereami-v2"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: whereami-v2
    spec:
      selector:
        app: whereami-v2
      ports:
      - port: 8080
        targetPort: 8080
    

    Il file manifest crea Service/whereami-v1, Service/whereami-v2, Deployment/whereami-v1 e Deployment/whereami-v2 per whereami, un'applicazione semplice che genera JSON per indicarne l'identità e la posizione. Eseguirai il deployment di due versioni diverse.

  3. Crea i servizi e i deployment:

    kubectl apply -f whereami.yaml
    

    Una volta avviato, avrai quattro pod doveami in esecuzione nel tuo cluster.

  4. Verifica che tutti e quattro i pod siano in esecuzione:

    kubectl get pods
    

    L'output è simile a questo:

    whereami-v1-7c76d89d55-qg6vs       2/2     Running   0          28s
    whereami-v1-7c76d89d55-vx9nm       2/2     Running   0          28s
    whereami-v2-67f6b9c987-p9kqm       2/2     Running   0          27s
    whereami-v2-67f6b9c987-qhj76       2/2     Running   0          27s
    
  5. Salva il seguente manifest HTTPRoute in un file denominato http-route.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: where-route
    spec:
     parentRefs:
     - kind: Gateway
       name: servicemesh-cloud-gw
       namespace: istio-ingress
     hostnames:
     - "where.example.com"
     rules:
     - matches:
       - headers:
         - name: version
           value: v2
       backendRefs:
       - name: whereami-v2
         port: 8080
     - backendRefs:
       - name: whereami-v1
         port: 8080
    
  6. Esegui il deployment di http-route.yaml nel cluster:

    kubectl apply -f http-route.yaml
    

    Questa proprietà HTTPRoute fa riferimento a servicemesh-cloud-gw, il che significa che configurerà il gateway cloud del mesh di servizi in modo da configurare il gateway in entrata Anthos Service Mesh sottostante con queste regole di routing. HTTPRoute esegue la stessa funzione di Istio VirtualService, ma utilizza l'API Kubernetes Gateway. Poiché l'API Gateway è una specifica OSS con molte implementazioni sottostanti, è l'API più adatta per definire il routing su una combinazione di bilanciatori del carico diversi (come proxy Anthos Service Mesh e Cloud Load Balancer).

  7. Recupera l'indirizzo IP dal gateway in modo da poter inviare traffico alla tua applicazione:

    VIP=$(kubectl get gateways.gateway.networking.k8s.io asm-gw-gke-servicemesh-cloud-gw -o=jsonpath="{.status.addresses[0].value}" -n istio-ingress)
    

    L'output è un indirizzo IP.

    echo $VIP
    
    34.111.61.135
    
  8. Invia il traffico all'indirizzo IP del gateway per verificare che questa configurazione funzioni correttamente. Invia una richiesta con l'intestazione version: v2 e una senza per determinare che il routing viene eseguito correttamente tra le due versioni dell'applicazione.

    curl ${VIP} -H "host: where.example.com"
    
    {
      "cluster_name": "gke1",
      "host_header": "where.example.com",
      "metadata": "whereami-v1",
      "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal",
      "pod_name": "whereami-v1-67d9c5d48b-zhr4l",
      "pod_name_emoji": "⚒",
      "project_id": "church-243723",
      "timestamp": "2021-02-08T18:55:01",
      "zone": "us-central1-a"
    }
    
    curl ${VIP} -H "host: where.example.com" -H "version: v2"
    
    {
      "cluster_name": "gke1",
      "host_header": "where.example.com",
      "metadata": "whereami-v2",
      "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal",
      "pod_name": "whereami-v2-67d9c5d48b-zhr4l",
      "pod_name_emoji": "⚒",
      "project_id": "church-243723",
      "timestamp": "2021-02-08T18:55:01",
      "zone": "us-central1-a"
    }
    

Deployment del gateway di produzione

La sezione precedente mostra un esempio molto semplice di gateway cloud del mesh di servizi. I passaggi seguenti si basano sul semplice esempio per mostrare una configurazione pronta per la produzione che dimostra i vantaggi della delega di alcune delle funzionalità di routing in entrata al bilanciatore del carico cloud.

Nell'esempio seguente, prenderai il servicemesh-cloud-gw dalla sezione precedente e aggiungerai le seguenti funzionalità per creare un gateway più sicuro e gestibile:

  • Esegui il deployment del gateway con un indirizzo IP statico che verrà conservato anche in caso di modifica dell'infrastruttura sottostante.
  • Converti il gateway in modo che riceva il traffico HTTPS con un certificato autofirmato.
  1. Crea un indirizzo IP esterno statico. Un IP statico è utile perché l'infrastruttura sottostante può cambiare in futuro, ma l'indirizzo IP può essere conservato.

    gcloud compute addresses create whereami-ip \
        --global \
        --project PROJECT_ID
    
  2. Crea un certificato autofirmato per il dominio where-example-com:

    openssl genrsa -out key.pem 2048
    cat <<EOF >ca.conf
    [req]
    default_bits              = 2048
    req_extensions            = extension_requirements
    distinguished_name        = dn_requirements
    prompt                    = no
    [extension_requirements]
    basicConstraints          = CA:FALSE
    keyUsage                  = nonRepudiation, digitalSignature, keyEncipherment
    subjectAltName            = @sans_list
    [dn_requirements]
    0.organizationName        = example
    commonName                = where.example.com
    [sans_list]
    DNS.1                     = where.example.com
    EOF
    
    openssl req -new -key key.pem \
        -out csr.pem \
        -config ca.conf
    
    openssl x509 -req \
        -signkey key.pem \
        -in csr.pem \
        -out cert.pem \
        -extfile ca.conf \
        -extensions extension_requirements \
        -days 365
    
    gcloud compute ssl-certificates create where-example-com \
        --certificate=cert.pem \
        --private-key=key.pem \
        --global \
        --project PROJECT_ID
    

    Esistono molti modi per generare certificati TLS. Possono essere generate manualmente sulla riga di comando, utilizzando certificati gestiti da Google oppure internamente dal sistema di infrastruttura a chiave pubblica (PKI) della tua azienda. In questo esempio, generi manualmente un certificato autofirmato. Sebbene i certificati autofirmati non siano in genere utilizzati per i servizi pubblici, consente di dimostrare questi concetti più facilmente.

    Per saperne di più sulla creazione di un certificato autofirmato tramite il secret di Kubernetes, consulta Proteggere un gateway.

  3. Aggiorna gateway.yaml con il seguente manifest:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: servicemesh-cloud-gw
      namespace: istio-ingress
    spec:
      gatewayClassName: asm-l7-gxlb
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          namespaces:
            from: All
      - name: https
        protocol: HTTPS
        port: 443
        allowedRoutes:
          namespaces:
            from: All
        tls:
          mode: Terminate
          options:
            networking.gke.io/pre-shared-certs: where-example-com
      addresses:
      - type: NamedAddress
        value: whereami-ip
    
  4. Esegui di nuovo il deployment del gateway nel cluster:

    kubectl apply -f gateway.yaml
    
  5. Recupera l'indirizzo IP dell'IP statico:

    VIP=$(gcloud compute addresses describe whereami-ip --global --format="value(address)")
    
  6. Utilizza curl per accedere al dominio del gateway. Poiché il DNS non è configurato per questo dominio, utilizza l'opzione --resolve per indicare a curl di risolvere il nome di dominio nell'indirizzo IP del gateway:

    curl https://where.example.com --resolve where.example.com:443:${VIP} --cacert cert.pem -v
    

    Una volta completato, l'output sarà simile al seguente:

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=where.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: where.example.com (matched)
    *  issuer: O=example; CN=where.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gke1",
      "host_header": "where.example.com",
      "metadata": "where-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "where-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08",
      "zone": "us-west1-a"
    }
    

L'output dettagliato include un handshake TLS riuscito, seguito da una risposta dell'applicazione come nell'output seguente. Questo dimostra che TLS viene terminato correttamente sul gateway e che l'applicazione risponde al client in modo sicuro.

Hai eseguito correttamente il deployment della seguente architettura:

Architettura di ASM

L'servicemesh-cloud-gw e il suo asm-l7-gxlb GatewayClass hanno astrato alcuni componenti infrastrutturali interni per semplificare l'esperienza utente. Cloud Load Balancing sta terminando il traffico TLS utilizzando un certificato interno e esegue anche il controllo di integrità del livello proxy del gateway in entrata di Anthos Service Mesh. Il whereami-routedi cui è stato eseguito il deployment nel deployment di app e routing configura i proxy del gateway in entrata di Anthos Service Mesh per instradare il traffico al servizio ospitato sulla rete mesh corretto.

Passaggi successivi