Configura Google Kubernetes Engine e i servizi gRPC senza proxy

Questa guida descrive come configurare Google Kubernetes Engine, le applicazioni gRPC e i componenti di bilanciamento del carico richiesti da Cloud Service Mesh.

Prima di seguire le istruzioni di questa guida, consulta Preparazione della configurazione di Cloud Service Mesh con servizi gRPC senza proxy.

Panoramica

La configurazione di Cloud Service Mesh con GKE e i servizi gRPC senza proxy prevede quanto segue:

  1. Preparazione del cluster GKE.
  2. Deployment di un'applicazione server gRPC come servizio Kubernetes. Annota le specifiche di deployment di GKE per creare automaticamente un gruppo di endpoint di rete (NEG) per il servizio.
  3. Configurazione di Cloud Service Mesh utilizzando il NEG e altri componenti di bilanciamento del carico di Google Cloud.
  4. Per verificare che il deployment funzioni correttamente, utilizza un'applicazione client gRPC senza proxy per inviare il traffico all'applicazione server gRPC.

Configurazione di cluster GKE per Cloud Service Mesh

Questa sezione fornisce le istruzioni per abilitare i cluster GKE al funzionamento con Cloud Service Mesh.

Requisiti dei cluster GKE

I cluster GKE devono soddisfare i seguenti requisiti:

  • Devi abilitare il supporto per i gruppi di endpoint di rete. Per ulteriori informazioni ed esempi, vedi Gruppi di endpoint di rete autonomi. La funzionalità NEG standalone è disponibile in disponibilità generale per Cloud Service Mesh.
  • L'account di servizio delle istanze dei nodi del cluster deve disporre dell'autorizzazione per accedere all'API Cloud Service Mesh. Per ulteriori informazioni sulle autorizzazioni richieste, consulta Abilitazione dell'account di servizio per l'accesso all'API Cloud Service Mesh.
  • I container devono avere accesso all'API Cloud Service Mesh, che è protetta dall'autenticazione OAuth. Per maggiori informazioni, consulta la sezione sulla configurazione dell'host.

Creazione del cluster GKE

L'esempio seguente mostra come creare un cluster GKE denominato grpc-td-cluster in us-central1-a zone.

Console

Per creare un cluster utilizzando la console Google Cloud, esegui questi passaggi:

  1. Vai al menu Kubernetes Engine nella console Google Cloud.

    Vai al menu Google Kubernetes Engine

  2. Fai clic su Crea cluster.

  3. Scegli il modello di cluster Standard o scegli un modello appropriato per il tuo carico di lavoro.

  4. Personalizza il modello, se necessario. I seguenti campi sono obbligatori:

    • Nome: inserisci grpc-td-cluster.
    • Tipo di posizione: Zonal.
    • Zona: us-central1-a.
    • Pool di nodi:
  5. Nel menu a sinistra, fai clic su default-pool.

  6. Cambia il Nome in grpc-td-cluster.

  7. In Dimensioni, inserisci il numero di nodi da creare. Devi disporre di una quota di risorse disponibile per i nodi e le relative risorse (come le route firewall).

  8. Nel menu a sinistra, fai clic su Nodi.

  9. In Configurazione macchina, in Famiglia di macchine, fai clic su Ottimizzato per il calcolo.

  10. Seleziona un Tipo di macchina. Per informazioni sui prezzi dei tipo di macchina, consulta la pagina dei prezzi di Compute Engine.

  11. In Networking, aggiungi il tag di rete allow-health-checks.

  12. Nel menu a sinistra, fai clic su Sicurezza nodo.

  13. In Ambiti di accesso, seleziona Consenti l'accesso completo a tutte le API Cloud.

  14. Fai clic su Crea.

Dopo aver creato un cluster nella console Google Cloud, devi configurare kubectl per interagire con il cluster. Per ulteriori informazioni, consulta Generazione di una voce kubeconfig.

gcloud

Crea il cluster.

gcloud container clusters create grpc-td-cluster \
   --zone us-central1-a \
   --scopes=https://www.googleapis.com/auth/cloud-platform \
   --tags=allow-health-checks \
   --enable-ip-alias

Ottenere i privilegi necessari per il cluster GKE

Passa al cluster che hai appena creato eseguendo il comando seguente. Questo indirizza kubectl al cluster corretto.

gcloud

gcloud container clusters get-credentials grpc-td-cluster \
    --zone us-central1-a

Configurazione dei servizi GKE

Questa sezione descrive come preparare le specifiche del deployment GKE per utilizzare Cloud Service Mesh. Questa operazione prevede la configurazione di un servizio di esempio GKE helloworld con annotazioni NEG.

Il servizio di esempio helloworld è un'applicazione server gRPC che restituisce un messaggio in risposta alla richiesta di un client gRPC. Tieni presente che non c'è niente di speciale nel servizio helloworld. Non è un servizio gRPC senza proxy e può rispondere alle richieste di qualsiasi client gRPC.

La parte "senza proxy" entra in gioco solo quando un'applicazione client gRPC si connette a Cloud Service Mesh, apprende il servizio helloworld e può quindi inviare traffico ai pod associati a helloworld, senza dover fare affidamento su indirizzi IP o risoluzione dei nomi basata su DNS.

Configurazione di servizi GKE con NEG

Il primo passaggio per la configurazione dei servizi GKE da utilizzare con Cloud Service Mesh è esporre il servizio tramite un NEG. Per essere esposta tramite i NEG, ogni specifica deve avere la seguente annotazione, corrispondente alla porta da esporre.

...
metadata:
  annotations:
    cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}'

Questa annotazione crea un NEG autonomo quando esegui il primo deployment del servizio. Questo NEG contiene endpoint che corrispondono agli indirizzi IP e alle porte del pod. Per ulteriori informazioni ed esempi, consulta Gruppi di endpoint di rete autonomi.

Nell'esempio seguente, esegui il deployment di un servizio Kubernetes helloworld esposto sulla porta 8080. Questa è la porta su cui il servizio è visibile nel cluster. Il servizio gRPC nel pod è in ascolto su targetPort 50051. Questa è la porta sul pod a cui viene inviata la richiesta. In genere, port e targetPort sono impostati sullo stesso valore per comodità, ma in questo esempio vengono utilizzati valori diversi per indicare il valore corretto da utilizzare nell'annotazione NEG.

cat << EOF > grpc-td-helloworld.yaml
apiVersion: v1
kind: Service
metadata:
  name: helloworld
  annotations:
    cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}'
spec:
  ports:
  - port: 8080
    name: helloworld
    protocol: TCP
    targetPort: 50051
  selector:
    run: app1
  type: ClusterIP

---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: app1
  name: app1
spec:
  selector:
    matchLabels:
      run: app1
  replicas: 2
  template:
    metadata:
      labels:
        run: app1
    spec:
      containers:
      - image: grpc/java-example-hostname:1.50.2
        name: app1
        ports:
        - protocol: TCP
          containerPort: 50051
EOF
kubectl apply -f grpc-td-helloworld.yaml

Verifica che sia stato creato il nuovo servizio helloworld:

kubectl get svc

L'output di kubectl get svc dovrebbe essere simile al seguente:

NAME           TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
helloworld     ClusterIP   10.71.9.71   <none>        8080/TCP  41m
[..skip..]

Verifica che il pod dell'applicazione sia in esecuzione:

kubectl get pods

L'output di kubectl get pods dovrebbe essere simile al seguente:

NAME                        READY     STATUS    RESTARTS   AGE
app1-6db459dcb9-zvfg2   1/1       Running   0          6m
app1-6db459dcb9-hlvhj   1/1       Running   0          6m
[..skip..]

Verifica che il nome del NEG sia corretto.

Console

Per visualizzare un elenco di gruppi di endpoint di rete, vai alla pagina Gruppi di endpoint di rete nella console Google Cloud. Vedi un NEG denominato example-grpc-server.
Vai alla pagina Gruppi di endpoint di rete

gcloud

# List the NEGs
gcloud compute network-endpoint-groups list \
    --filter "name=example-grpc-server" --format "value(name)"

# Optionally examine the NEG
gcloud compute network-endpoint-groups describe example-grpc-server \
    --zone us-central1-a

# Optionally examine the endpoint(s) contained
gcloud compute network-endpoint-groups list-network-endpoints example-grpc-server \
    --zone us-central1-a

Configurazione di Cloud Service Mesh con componenti di bilanciamento del carico

Questa sezione descrive come configurare i componenti di bilanciamento del carico di Google Cloud per i tuoi servizi. Questi componenti contengono informazioni di configurazione che consentono ai client gRPC senza proxy di comunicare con i tuoi servizi GKE.

L'esempio di configurazione di Cloud Service Mesh che segue fa queste ipotesi:

  • I NEG e tutte le altre risorse vengono creati nella rete predefinita in modalità automatica, nella zona us-central1-a.
  • Quando utilizzi Google Cloud CLI, il nome del NEG per il cluster è example-grpc-server.

Creazione del controllo di integrità, della regola firewall e del servizio di backend in corso...

In questa sezione creerai un controllo di integrità e la regola firewall per il controllo di integrità. Il controllo di integrità deve utilizzare il protocollo di controllo di integrità gRPC. La regola firewall consente ai probe del controllo di integrità di connettersi alle VM nel deployment. L'istruzione --use-serving-port viene utilizzata dai controlli di integrità per ottenere la porta di ascolto configurata per ciascun endpoint.

La regola firewall consente le connessioni in entrata per il controllo di integrità alle istanze nella tua rete.

In questa sezione creerai un servizio di backend globale con uno schema di bilanciamento del carico di INTERNAL_SELF_MANAGED e protocollo GRPC, quindi assocerai il controllo di integrità al servizio di backend.

Per saperne di più, consulta Creazione di controlli di integrità.

gcloud

  1. Crea il controllo di integrità.

    gcloud compute health-checks create grpc grpc-gke-helloworld-hc \
     --use-serving-port
    
  2. Crea la regola firewall.

    gcloud compute firewall-rules create grpc-gke-allow-health-checks \
      --network default --action allow --direction INGRESS \
      --source-ranges 35.191.0.0/16,130.211.0.0/22 \
      --target-tags allow-health-checks \
      --rules tcp:50051
    
  3. Creare il servizio di backend.

    gcloud compute backend-services create grpc-gke-helloworld-service \
       --global \
       --load-balancing-scheme=INTERNAL_SELF_MANAGED \
       --protocol=GRPC \
       --health-checks grpc-gke-helloworld-hc
    
  4. Aggiungi i NEG di backend al servizio di backend.

    gcloud compute backend-services add-backend grpc-gke-helloworld-service \
       --global \
       --network-endpoint-group example-grpc-server \
       --network-endpoint-group-zone us-central1-a \
       --balancing-mode RATE \
       --max-rate-per-endpoint 5
    

Creazione della mappa di regole di routing

In questa sezione, creerai una mappa URL, un matcher di percorso e una regola host per instradare il traffico verso il tuo servizio in base al nome host e a un percorso. L'esempio seguente utilizza helloworld-gke come nome del servizio. Il client gRPC utilizza questo nome del servizio nell'URI di destinazione quando si connette al servizio helloworld. Creerai anche il proxy gRPC di destinazione e la regola di forwarding.

Per ulteriori informazioni, consulta Mappe di regole di routing.

L'esempio seguente utilizza il nome del servizio helloworld-gke e la porta 8000. Ciò significa che il client gRPC deve utilizzare xds:///helloworld-gke:8000 per connettersi a questo servizio e deve essere configurata una regola host helloworld-gke:8000 nella mappa URL. Tieni presente che la porta di servizio 8080 mostrata nella specifica del servizio Kubernetes in una sezione precedente non viene utilizzata da Cloud Service Mesh, perché helloworld-gke:8000 viene risolta direttamente per gli endpoint NEG che sono in ascolto su targetPort 50051. In genere, la porta nella regola host della mappa URL e le specifiche del servizio Kubernetes port e targetPort sono tutte impostate sullo stesso valore per comodità, ma questo esempio utilizza valori diversi per mostrare che port nella specifica del servizio non è utilizzato da Cloud Service Mesh.

gcloud

  1. Crea la mappa URL.

    gcloud compute url-maps create grpc-gke-url-map \
    --default-service grpc-gke-helloworld-service
    
  2. Crea il matcher del percorso.

    gcloud compute url-maps add-path-matcher grpc-gke-url-map \
    --default-service grpc-gke-helloworld-service \
    --path-matcher-name grpc-gke-path-matcher \
    --new-hosts helloworld-gke:8000
    
  3. Crea il proxy gRPC di destinazione.

    gcloud compute target-grpc-proxies create grpc-gke-proxy \
    --url-map grpc-gke-url-map \
    --validate-for-proxyless
    
  4. Crea la regola di forwarding.

    gcloud compute forwarding-rules create grpc-gke-forwarding-rule \
    --global \
    --load-balancing-scheme=INTERNAL_SELF_MANAGED \
    --address=0.0.0.0 \
    --target-grpc-proxy=grpc-gke-proxy \
    --ports 8000 \
    --network default
    

Cloud Service Mesh è ora configurato per bilanciare il carico del traffico tra gli endpoint nel NEG per i servizi specificati nella mappa URL.

Verifica della configurazione in corso...

Al termine del processo di configurazione, verifica di poter raggiungere il server gRPC helloworld utilizzando un client gRPC senza proxy. Questo client si connette a Cloud Service Mesh, ottiene informazioni sul servizio helloworld (configurato con Cloud Service Mesh utilizzando il servizio di backend grpc-gke-helloworld-service) e utilizza queste informazioni per inviare il traffico ai backend del servizio.

Puoi anche consultare la sezione Cloud Service Mesh nella console Google Cloud per informazioni sul servizio configurato helloworld-gke e controllare se i backend sono segnalati come integri.

Verifica con un client gRPC senza proxy

Negli esempi seguenti, utilizzi i client gRPC in linguaggi diversi o lo strumento grpcurl per verificare che Cloud Service Mesh stia eseguendo correttamente il routing del traffico nel mesh. Creerai un pod client, quindi apri una shell ed esegui i comandi di verifica dalla shell.

Configurazione della variabile di ambiente e del file di bootstrap

L'applicazione client richiede un file di configurazione di bootstrap. Modifica la specifica del deployment delle applicazioni Kubernetes aggiungendo un initContainer che genera il file di bootstrap e un volume per trasferire il file. Aggiorna il container esistente per trovare il file.

Aggiungi il seguente initContainer alla specifica di deployment dell'applicazione:

      initContainers:
      - args:
        - --output
        - "/tmp/bootstrap/td-grpc-bootstrap.json"
        image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.11.0

        imagePullPolicy: IfNotPresent
        name: grpc-td-init
        resources:
          limits:
            cpu: 100m
            memory: 100Mi
          requests:
            cpu: 10m
            memory: 100Mi
        volumeMounts:
        - name: grpc-td-conf
          mountPath: /tmp/bootstrap/
      volumes:
      - name: grpc-td-conf
        emptyDir:
          medium: Memory

Aggiorna la sezione env del container di applicazioni per includere quanto segue:

        env:
        - name: GRPC_XDS_BOOTSTRAP
          value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
        volumeMounts:
        - name: grpc-td-conf
          mountPath: /tmp/grpc-xds/

Questo è un esempio completo di una specifica Kubernetes del client:

cat << EOF  | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: client
  name: sleeper
spec:
  selector:
    matchLabels:
      run: client
  template:
    metadata:
      labels:
        run: client
    spec:
      containers:
      - image: openjdk:8-jdk
        imagePullPolicy: IfNotPresent
        name: sleeper
        command:
        - sleep
        - 365d
        env:
        - name: GRPC_XDS_BOOTSTRAP
          value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
        resources:
          limits:
            cpu: "2"
            memory: 2000Mi
          requests:
            cpu: 300m
            memory: 1500Mi
        volumeMounts:
        - name: grpc-td-conf
          mountPath: /tmp/grpc-xds/
      initContainers:
      - args:
        - --output
        - "/tmp/bootstrap/td-grpc-bootstrap.json"
        image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.11.0
        imagePullPolicy: IfNotPresent
        name: grpc-td-init
        resources:
          limits:
            cpu: 100m
            memory: 100Mi
          requests:
            cpu: 10m
            memory: 100Mi
        volumeMounts:
        - name: grpc-td-conf
          mountPath: /tmp/bootstrap/
      volumes:
      - name: grpc-td-conf
        emptyDir:
          medium: Memory
EOF

Quando il deployment è pronto, apri una shell sul pod del client.

kubectl exec -it $(kubectl get pods -o custom-columns=:.metadata.name \
    --selector=run=client) -- /bin/bash

Per verificare la configurazione, esegui gli esempi appropriati nella shell del pod.

Java

Per verificare il servizio con un client Java gRPC:

  1. Scarica la versione più recente di gRPC Java, con la patch più recente e crea l'applicazione client xds-hello-world.

     curl -L https://github.com/grpc/grpc-java/archive/v1.37.0.tar.gz | tar -xz
     cd grpc-java-1.37.0/examples/example-xds
     ../gradlew --no-daemon installDist
     

  2. Esegui il client con "world" come nome e "xds:///helloworld-gke:8000" come URI e porta del servizio.

    ./build/install/example-xds/bin/xds-hello-world-client "world" \
    xds:///helloworld-gke:8000
    

Go

Per verificare il servizio con un client gRPC Go:

  1. Scarica la versione più recente di gRPC Go con la patch più recente e crea l'applicazione client xds-hello-world.

    apt-get update -y
    apt-get install -y golang git
    curl -L https://github.com/grpc/grpc-go/archive/v1.37.0.tar.gz | tar -xz
    cd grpc-go-1.37.0/examples/features/xds/client
    go get google.golang.org/grpc@v1.37.0
    go build .
    
  2. Esegui il client con "world" come nome e "xds:///helloworld-gke:8000" come URI e porta del servizio.

    ./client "world" xds:///helloworld-gke:8000
    

C++

Per verificare il servizio con un client gRPC C++:

  1. Scarica l'ultima versione di gRPC C++,con la patch più recente, e crea l'esempio di client helloworld.

    apt-get update -y
    apt-get install -y build-essential cmake git
    git clone --recurse-submodules -b v1.37.1 https://github.com/grpc/grpc
    cd grpc
    mkdir -p cmake/build
    pushd cmake/build
    cmake ../..
    make
    make install
    popd
    mkdir -p third_party/abseil-cpp/cmake/build
    pushd third_party/abseil-cpp/cmake/build
    cmake ../..
    make
    make install
    popd
    cd examples/cpp/helloworld
    mkdir -p cmake/build
    cd cmake/build/
    cmake ../..
    make
    
  2. Esegui il client con "xds:///helloworld-gke:8000" come URI e porta del servizio.

    ./greeter_client --target=xds:///helloworld-gke:8000
    

Gripcurl

Lo strumento grpcurl può anche fungere da client gRPC senza proxy. In questo caso, grpcurl utilizza le informazioni sulla variabile di ambiente e sul bootstrap per connettersi a Cloud Service Mesh. Apprende quindi il servizio helloworld, che è stato configurato con Cloud Service Mesh tramite il servizio di backend grpc-gke-helloworld-service.

Per verificare la configurazione utilizzando lo strumento grpcurl:

  1. Scarica e installa lo strumento grpcurl.

    curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.8.1/grpcurl_1.8.1_linux_x86_64.tar.gz | tar -xz
    
  2. Esegui lo strumento grpcurl con "xds:///helloworld-gke:8000" come URI del servizio e helloworld.Greeter/SayHello come nome del servizio e metodo da richiamare. I parametri al metodo SayHello vengono passati utilizzando l'opzione -d.

    ./grpcurl --plaintext \
      -d '{"name": "world"}' \
      xds:///helloworld-gke:8000 helloworld.Greeter/SayHello
    

Python

Per verificare il servizio con un client Python gRPC, esegui quanto segue. Usa la versione più recente di gRPC con la patch più recente.

apt-get update -y
apt-get install python3-pip -y
pip3 install virtualenv
curl -L https://github.com/grpc/grpc/archive/v1.37.1.tar.gz | tar -xz
cd grpc-1.37.1/examples/python/xds
virtualenv venv -p python3
source venv/bin/activate
pip install -r requirements.txt
python client.py  xds:///helloworld-gke:8000

Ruby

Per verificare il servizio con un client Ruby gRPC, esegui quanto segue. Usa la versione più recente di gRPC con la patch più recente.

apt-get update -y
apt-get install -y ruby-full
gem install grpc
curl -L https://github.com/grpc/grpc/archive/v1.37.1.tar.gz | tar -xz
cd grpc-1.37.1/examples/ruby
ruby greeter_client.rb john xds:///helloworld-gke:8000

PHP

Per verificare il servizio con un client PHP gRPC, esegui il comando riportato di seguito. Usa la versione più recente di gRPC con la patch più recente.

apt-get update -y
apt-get install -y php7.3 php7.3-dev php-pear phpunit python-all zlib1g-dev git
pecl install grpc
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
curl -L https://github.com/grpc/grpc/archive/v1.37.1.tar.gz | tar -xz
cd grpc-1.37.1
export CC=/usr/bin/gcc
./tools/bazel build @com_google_protobuf//:protoc
./tools/bazel build src/compiler:grpc_php_plugin
cd examples/php
composer install
../../bazel-bin/external/com_google_protobuf/protoc --proto_path=../protos \
--php_out=. --grpc_out=. \
--plugin=protoc-gen-grpc=../../bazel-bin/src/compiler/grpc_php_plugin \
../protos/helloworld.proto
php -d extension=grpc.so greeter_client.php john xds:///helloworld-gke:8000

Node.js

Per verificare il servizio con un client Node.js gRPC, esegui quanto segue. Usa la versione più recente di gRPC con la patch più recente.

apt-get update -y
apt-get install -y nodejs npm
curl -L https://github.com/grpc/grpc/archive/v1.34.0.tar.gz | tar -xz
cd grpc-1.34.0/examples/node/xds
npm install
node ./greeter_client.js --target=xds:///helloworld-gke:8000

Dovresti vedere un output simile a questo, dove INSTANCE_HOST_NAME è il nome host dell'istanza VM:

Greetings: Hello world, from INSTANCE_HOST_NAME

Ciò consente di verificare che il client gRPC senza proxy si sia connesso correttamente a Cloud Service Mesh e di conoscere i backend per il servizio helloworld-gke utilizzando il resolver xds name. Il client ha inviato una richiesta a uno dei backend del servizio senza dover conoscere l'indirizzo IP o eseguire una risoluzione DNS.

Passaggi successivi