Configura un mesh di servizi gRPC senza proxy su GKE

Questa pagina descrive come eseguire il deployment di un client e di un server gRPC senza proxy di esempio in un mesh di servizi Cloud Service Mesh.

Prerequisiti

Come punto di partenza, questa guida presuppone che tu abbia già:

Requisiti

Questa sezione elenca i requisiti per i servizi supportati:

  • gRPC C++ - versione 1.68.1 o successive
  • gRPC Java - versione 1.68.2 o successive
  • gRPC Go - versione 1.68.0 o successive
  • gRPC Python - versione 1.68.1 o successive

Configura il servizio gRPC senza proxy

Questa guida illustra due metodi per configurare un servizio gRPC senza proxy all'interno del mesh di servizi:

Metodo 1: configurazione manuale

Questo metodo richiede di configurare manualmente i componenti necessari per il servizio gRPC senza proxy.

  • InitContainer: utilizza un initContainer all'interno della specifica del pod per eseguire il generatore di bootstrap gRPC di Traffic Director. Questo generatore produce la configurazione richiesta per il servizio.
  • Montaggio del volume: monta un volume che contiene la configurazione generata da initContainer. In questo modo, l'applicazione può accedere alle impostazioni necessarie.
  • Variabili di ambiente: includi le variabili di ambiente appropriate per abilitare l'emissione delle metriche di Cloud Service Mesh Observability dall'applicazione. Queste metriche forniscono informazioni preziose sulle prestazioni del servizio.

Metodo 2: automatico utilizzando l'iniettore di bootstrap senza proxy

Anziché configurare manualmente il servizio gRPC senza proxy, puoi optare per un approccio semplificato utilizzando l'iniettore di bootstrap senza proxy.

Questa funzionalità automatizza la procedura di configurazione, semplificando il deployment del servizio. Per abilitarla, aggiungi l'etichetta mesh.cloud.google.com/csm-injection=proxyless allo spazio dei nomi.

Aggiungendo questa etichetta allo spazio dei nomi, l'iniettore si occupa di tutte le configurazioni necessarie, risparmiando tempo e fatica.

Se hai bisogno di un controllo più granulare, puoi applicare questa etichetta direttamente ai singoli pod. In questo modo, puoi sostituire l'impostazione a livello di spazio dei nomi e personalizzare il comportamento di inserimento per ogni pod.

Seguendo uno di questi metodi, puoi stabilire correttamente un servizio gRPC senza proxy all'interno del mesh di servizi.

Manuale

  1. Applica lo spazio dei nomi

    kubectl apply -f - <<EOF
    ---
    kind: Namespace
    apiVersion: v1
    metadata:
     name: proxyless-example
    EOF
    
  2. Esegui il deployment di un servizio gRPC:

C++

kubectl apply -f - <<EOF
---
apiVersion: v1
kind: Service
metadata:
  name: helloworld
  namespace: proxyless-example
spec:
  selector:
    app: psm-grpc-server
  ports:
  - port: 50051
    targetPort: 50051
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-server
  namespace: proxyless-example
  labels:
    app: psm-grpc-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: psm-grpc-server
  template:
    metadata:
      labels:
        app: psm-grpc-server
        service.istio.io/canonical-name: deployment-psm-grpc-server
    spec:
      containers:
      - name: psm-grpc-server
        image: grpc/csm-o11y-example-cpp-server:v1.68.1
        imagePullPolicy: Always
        args:
          - "--port=50051"
        ports:
          - containerPort: 50051
        env:
          - name: GRPC_XDS_BOOTSTRAP
            value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: CONTAINER_NAME
            value: psm-grpc-server
          - name: NAMESPACE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: CSM_WORKLOAD_NAME
            value: psm-grpc-server
          - name: CSM_CANONICAL_SERVICE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.labels['service.istio.io/canonical-name']
          - name: CSM_MESH_ID
            value: proj-PROJECT_NUMBER
          - name: OTEL_RESOURCE_ATTRIBUTES
            value: k8s.pod.name=\$(POD_NAME),k8s.namespace.name=\$(NAMESPACE_NAME),k8s.container.name=\$(CONTAINER_NAME)
        volumeMounts:
          - mountPath: /tmp/grpc-xds/
            name: grpc-td-conf
            readOnly: true
      initContainers:
        - name: grpc-td-init
          image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.19.0
          imagePullPolicy: Always
          args:
            - "--output=/tmp/bootstrap/td-grpc-bootstrap.json"
            - "--vpc-network-name=default"
            - "--xds-server-uri=trafficdirector.googleapis.com:443"
            - "--generate-mesh-id"
          volumeMounts:
            - mountPath: /tmp/bootstrap/
              name: grpc-td-conf
      volumes:
        - name: grpc-td-conf
          emptyDir:
            medium: Memory
EOF

Java

kubectl apply -f - <<EOF
---
apiVersion: v1
kind: Service
metadata:
  name: helloworld
  namespace: proxyless-example
spec:
  selector:
    app: psm-grpc-server
  ports:
  - port: 50051
    targetPort: 50051
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-server
  namespace: proxyless-example
  labels:
    app: psm-grpc-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: psm-grpc-server
  template:
    metadata:
      labels:
        app: psm-grpc-server
        service.istio.io/canonical-name: deployment-psm-grpc-server
    spec:
      containers:
      - name: psm-grpc-server
        image: grpc/csm-o11y-example-java-server:v1.68.2
        imagePullPolicy: Always
        args:
          - "50051"
          - "9464"
        ports:
          - containerPort: 50051
        env:
          - name: GRPC_XDS_BOOTSTRAP
            value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: CONTAINER_NAME
            value: psm-grpc-server
          - name: NAMESPACE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: CSM_WORKLOAD_NAME
            value: psm-grpc-server
          - name: CSM_CANONICAL_SERVICE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.labels['service.istio.io/canonical-name']
          - name: CSM_MESH_ID
            value: proj-PROJECT_NUMBER
          - name: OTEL_RESOURCE_ATTRIBUTES
            value: k8s.pod.name=\$(POD_NAME),k8s.namespace.name=\$(NAMESPACE_NAME),k8s.container.name=\$(CONTAINER_NAME)
        volumeMounts:
          - mountPath: /tmp/grpc-xds/
            name: grpc-td-conf
            readOnly: true
      initContainers:
        - name: grpc-td-init
          image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.19.0
          imagePullPolicy: Always
          args:
            - "--output=/tmp/bootstrap/td-grpc-bootstrap.json"
            - "--vpc-network-name=default"
            - "--xds-server-uri=trafficdirector.googleapis.com:443"
            - "--generate-mesh-id"
          volumeMounts:
            - mountPath: /tmp/bootstrap/
              name: grpc-td-conf
      volumes:
        - name: grpc-td-conf
          emptyDir:
            medium: Memory
EOF

Go

kubectl apply -f - <<EOF
---
apiVersion: v1
kind: Service
metadata:
  name: helloworld
  namespace: proxyless-example
spec:
  selector:
    app: psm-grpc-server
  ports:
  - port: 50051
    targetPort: 50051
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-server
  namespace: proxyless-example
  labels:
    app: psm-grpc-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: psm-grpc-server
  template:
    metadata:
      labels:
        app: psm-grpc-server
        service.istio.io/canonical-name: deployment-psm-grpc-server
    spec:
      containers:
      - name: psm-grpc-server
        image: grpc/csm-o11y-example-go-server:v1.69.4
        imagePullPolicy: Always
        args:
          - "--port=50051"
        ports:
          - containerPort: 50051
        env:
          - name: GRPC_XDS_BOOTSTRAP
            value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: CONTAINER_NAME
            value: psm-grpc-server
          - name: NAMESPACE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: CSM_WORKLOAD_NAME
            value: psm-grpc-server
          - name: CSM_CANONICAL_SERVICE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.labels['service.istio.io/canonical-name']
          - name: CSM_MESH_ID
            value: proj-PROJECT_NUMBER
          - name: OTEL_RESOURCE_ATTRIBUTES
            value: k8s.pod.name=\$(POD_NAME),k8s.namespace.name=\$(NAMESPACE_NAME),k8s.container.name=\$(CONTAINER_NAME)
        volumeMounts:
          - mountPath: /tmp/grpc-xds/
            name: grpc-td-conf
            readOnly: true
      initContainers:
        - name: grpc-td-init
          image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.19.0
          imagePullPolicy: Always
          args:
            - "--output=/tmp/bootstrap/td-grpc-bootstrap.json"
            - "--vpc-network-name=default"
            - "--xds-server-uri=trafficdirector.googleapis.com:443"
            - "--generate-mesh-id"
          volumeMounts:
            - mountPath: /tmp/bootstrap/
              name: grpc-td-conf
      volumes:
        - name: grpc-td-conf
          emptyDir:
            medium: Memory
EOF

Python

kubectl apply -f - <<EOF
---
apiVersion: v1
kind: Service
metadata:
  name: helloworld
  namespace: proxyless-example
spec:
  selector:
    app: psm-grpc-server
  ports:
  - port: 50051
    targetPort: 50051
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-server
  namespace: proxyless-example
  labels:
    app: psm-grpc-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: psm-grpc-server
  template:
    metadata:
      labels:
        app: psm-grpc-server
        service.istio.io/canonical-name: deployment-psm-grpc-server
    spec:
      containers:
      - name: psm-grpc-server
        image: grpc/csm-o11y-example-python-server:v1.68.1
        imagePullPolicy: Always
        args:
          - "--port=50051"
        ports:
          - containerPort: 50051
        env:
          - name: GRPC_XDS_BOOTSTRAP
            value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: CONTAINER_NAME
            value: psm-grpc-server
          - name: NAMESPACE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: CSM_WORKLOAD_NAME
            value: psm-grpc-server
          - name: CSM_CANONICAL_SERVICE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.labels['service.istio.io/canonical-name']
          - name: CSM_MESH_ID
            value: proj-PROJECT_NUMBER
          - name: OTEL_RESOURCE_ATTRIBUTES
            value: k8s.pod.name=\$(POD_NAME),k8s.namespace.name=\$(NAMESPACE_NAME),k8s.container.name=\$(CONTAINER_NAME)
        volumeMounts:
          - mountPath: /tmp/grpc-xds/
            name: grpc-td-conf
            readOnly: true
      initContainers:
        - name: grpc-td-init
          image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
          imagePullPolicy: Always
          args:
            - "--output=/tmp/bootstrap/td-grpc-bootstrap.json"
            - "--vpc-network-name=default"
            - "--xds-server-uri=trafficdirector.googleapis.com:443"
            - "--generate-mesh-id"
          volumeMounts:
            - mountPath: /tmp/bootstrap/
              name: grpc-td-conf
      volumes:
        - name: grpc-td-conf
          emptyDir:
            medium: Memory
EOF

L'output è simile a:

namespace/proxyless-example created
service/helloworld created
deployment.apps/psm-grpc-server created

Automatico

  1. Applica lo spazio dei nomi

    kubectl apply -f - <<EOF
    ---
    kind: Namespace
    apiVersion: v1
    metadata:
     name: proxyless-example
    EOF
    
  2. Esegui il comando seguente per abilitare l'iniettore di bootstrap senza proxy nello spazio dei nomi proxyless-example:

    kubectl label namespace proxyless-example mesh.cloud.google.com/csm-injection=proxyless
    
  3. Esegui il deployment di un servizio gRPC:

C++

kubectl apply -f - <<EOF
---
apiVersion: v1
kind: Service
metadata:
  name: helloworld
  namespace: proxyless-example
spec:
  selector:
    app: psm-grpc-server
  ports:
  - port: 50051
    targetPort: 50051
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-server
  namespace: proxyless-example
  labels:
    app: psm-grpc-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: psm-grpc-server
  template:
    metadata:
      labels:
        app: psm-grpc-server
    spec:
      containers:
      - name: psm-grpc-server
        image: grpc/csm-o11y-example-cpp-server:v1.68.1
        imagePullPolicy: Always
        args:
          - "--port=50051"
        ports:
          - containerPort: 50051
EOF

Java

kubectl apply -f - <<EOF
---
apiVersion: v1
kind: Service
metadata:
  name: helloworld
  namespace: proxyless-example
spec:
  selector:
    app: psm-grpc-server
  ports:
  - port: 50051
    targetPort: 50051
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-server
  namespace: proxyless-example
  labels:
    app: psm-grpc-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: psm-grpc-server
  template:
    metadata:
      labels:
        app: psm-grpc-server
    spec:
      containers:
      - name: psm-grpc-server
        image: grpc/csm-o11y-example-java-server:v1.68.2
        imagePullPolicy: Always
        args:
          - "50051"
          - "9464"
        ports:
          - containerPort: 50051
EOF

Go

kubectl apply -f - <<EOF
---
apiVersion: v1
kind: Service
metadata:
  name: helloworld
  namespace: proxyless-example
spec:
  selector:
    app: psm-grpc-server
  ports:
  - port: 50051
    targetPort: 50051
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-server
  namespace: proxyless-example
  labels:
    app: psm-grpc-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: psm-grpc-server
  template:
    metadata:
      labels:
        app: psm-grpc-server
    spec:
      containers:
      - name: psm-grpc-server
        image: grpc/csm-o11y-example-go-server:v1.69.4
        imagePullPolicy: Always
        args:
          - "--port=50051"
        ports:
          - containerPort: 50051
EOF

Python

kubectl apply -f - <<EOF
---
apiVersion: v1
kind: Service
metadata:
  name: helloworld
  namespace: proxyless-example
spec:
  selector:
    app: psm-grpc-server
  ports:
  - port: 50051
    targetPort: 50051
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-server
  namespace: proxyless-example
  labels:
    app: psm-grpc-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: psm-grpc-server
  template:
    metadata:
      labels:
        app: psm-grpc-server
    spec:
      containers:
      - name: psm-grpc-server
        image: grpc/csm-o11y-example-python-server:v1.68.1
        imagePullPolicy: Always
        args:
          - "--port=50051"
        ports:
          - containerPort: 50051
EOF

L'output è simile a:

namespace/proxyless-example created
service/helloworld created
deployment.apps/psm-grpc-server created
  1. Verifica che i pod siano stati creati:

    kubectl get pods -n proxyless-example
    

    L'output è simile a:

    NAME                               READY   STATUS    RESTARTS   AGE
    psm-grpc-server-65966bf76d-2wwxz   1/1     Running   0          13s
    psm-grpc-server-65966bf76d-nbxd2   1/1     Running   0          13s
    

    Prima di continuare, attendi che tutti i pod siano pronti e che lo Status sia In esecuzione prima di continuare.

  2. Esegui il deployment di un HTTPRoute:

    kubectl apply -f - <<EOF
    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: HTTPRoute
    metadata:
      name: app1
      namespace: proxyless-example
    spec:
      parentRefs:
      - name: helloworld
        namespace: proxyless-example
        kind: Service
        group: ""
      rules:
      - backendRefs:
        - name: helloworld
          port: 50051
    EOF
    

    Questo comando crea un HTTPRoute denominato app1 e invia tutti gli RPC al servizio helloworld.

    Tieni presente che il servizio parentRef è anche helloworld, il che significa che il nostro HTTPRoute è collegato a questo servizio ed elaborerà tutti gli RPC indirizzati a questo servizio. Nel caso di gRPC senza proxy, significa che qualsiasi client che invia RPC su un canale gRPC per il target xds:///helloworld.proxyless-example.svc.cluster.local:50051.

  3. Verifica che sia stato creato il nuovo HTTPRoute app1:

    kubectl get httproute -n proxyless-example
    

    L'output è simile a:

    NAME   HOSTNAMES   AGE
    app1               72s
    

Configura il client gRPC senza proxy

Questa sezione descrive come utilizzare un client gRPC per verificare che Cloud Service Mesh stia instradando correttamente il traffico nel mesh.

Come per la configurazione del servizio, hai due opzioni per configurare il client:

Metodo 1: configurazione manuale

Questo approccio prevede la configurazione manuale dei componenti necessari per il client, rispecchiando la configurazione manuale del servizio.

Metodo 2: automatico utilizzando l'iniettore di bootstrap senza proxy

In alternativa, puoi utilizzare l'iniettore automatico per semplificare la procedura di configurazione del client. In questo modo, la configurazione è più semplice e si riduce l'intervento manuale. Questo risultato si ottiene applicando l'etichetta allo spazio dei nomi.

Entrambe le opzioni forniscono le funzionalità necessarie per il client. Scegli il metodo più adatto alle tue esigenze e preferenze.

Manuale

Esegui un client gRPC e indirizzalo a utilizzare la configurazione di routing specificata da HTTPRoute:

C++

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-client
  namespace: proxyless-example
  labels:
    app: psm-grpc-client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: psm-grpc-client
  template:
    metadata:
      labels:
        app: psm-grpc-client
        service.istio.io/canonical-name: deployment-psm-grpc-client
    spec:
      containers:
      - name: psm-grpc-client
        image: grpc/csm-o11y-example-cpp-client:v1.68.1
        imagePullPolicy: Always
        args:
          - "--target=xds:///helloworld.proxyless-example.svc.cluster.local:50051"
        env:
          - name: GRPC_XDS_BOOTSTRAP
            value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
          - name: CSM_WORKLOAD_NAME
            value: psm-grpc-client
          - name: CSM_CANONICAL_SERVICE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.labels['service.istio.io/canonical-name']
          - name: CSM_MESH_ID
            value: proj-PROJECT_NUMBER
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: NAMESPACE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: CONTAINER_NAME
            value: psm-grpc-client
          - name: OTEL_RESOURCE_ATTRIBUTES
            value: k8s.pod.name=\$(POD_NAME),k8s.namespace.name=\$(NAMESPACE_NAME),k8s.container.name=\$(CONTAINER_NAME)
        volumeMounts:
          - mountPath: /tmp/grpc-xds/
            name: grpc-td-conf
            readOnly: true
      initContainers:
        - name: grpc-td-init
          image:  gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
          imagePullPolicy: Always
          args:
            - "--output=/tmp/bootstrap/td-grpc-bootstrap.json"
            - "--vpc-network-name=default"
            - "--xds-server-uri=trafficdirector.googleapis.com:443"
            - "--generate-mesh-id"
          volumeMounts:
            - mountPath: /tmp/bootstrap/
              name: grpc-td-conf
      volumes:
        - name: grpc-td-conf
          emptyDir:
            medium: Memory

EOF

Java

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-client
  namespace: proxyless-example
  labels:
    app: psm-grpc-client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: psm-grpc-client
  template:
    metadata:
      labels:
        app: psm-grpc-client
        service.istio.io/canonical-name: deployment-psm-grpc-client
    spec:
      containers:
      - name: psm-grpc-client
        image: grpc/csm-o11y-example-java-client:v1.68.2
        imagePullPolicy: Always
        args:
          - "world"
          - "xds:///helloworld.proxyless-example.svc.cluster.local:50051"
          - "9464"
        env:
          - name: GRPC_XDS_BOOTSTRAP
            value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
          - name: CSM_WORKLOAD_NAME
            value: psm-grpc-client
          - name: CSM_CANONICAL_SERVICE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.labels['service.istio.io/canonical-name']
          - name: CSM_MESH_ID
            value: proj-PROJECT_NUMBER
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: NAMESPACE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: CONTAINER_NAME
            value: psm-grpc-client
          - name: OTEL_RESOURCE_ATTRIBUTES
            value: k8s.pod.name=\$(POD_NAME),k8s.namespace.name=\$(NAMESPACE_NAME),k8s.container.name=\$(CONTAINER_NAME)
        volumeMounts:
          - mountPath: /tmp/grpc-xds/
            name: grpc-td-conf
            readOnly: true
      initContainers:
        - name: grpc-td-init
          image:  gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
          imagePullPolicy: Always
          args:
            - "--output=/tmp/bootstrap/td-grpc-bootstrap.json"
            - "--vpc-network-name=default"
            - "--xds-server-uri=trafficdirector.googleapis.com:443"
            - "--generate-mesh-id"
          volumeMounts:
            - mountPath: /tmp/bootstrap/
              name: grpc-td-conf
      volumes:
        - name: grpc-td-conf
          emptyDir:
            medium: Memory

EOF

Go

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-client
  namespace: proxyless-example
  labels:
    app: psm-grpc-client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: psm-grpc-client
  template:
    metadata:
      labels:
        app: psm-grpc-client
        service.istio.io/canonical-name: deployment-psm-grpc-client
    spec:
      containers:
      - name: psm-grpc-client
        image: grpc/csm-o11y-example-go-client:v1.69.4
        imagePullPolicy: Always
        args:
          - "--target=xds:///helloworld.proxyless-example.svc.cluster.local:50051"
        env:
          - name: GRPC_XDS_BOOTSTRAP
            value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
          - name: CSM_WORKLOAD_NAME
            value: psm-grpc-client
          - name: CSM_CANONICAL_SERVICE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.labels['service.istio.io/canonical-name']
          - name: CSM_MESH_ID
            value: proj-PROJECT_NUMBER
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: NAMESPACE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: CONTAINER_NAME
            value: psm-grpc-client
          - name: OTEL_RESOURCE_ATTRIBUTES
            value: k8s.pod.name=\$(POD_NAME),k8s.namespace.name=\$(NAMESPACE_NAME),k8s.container.name=\$(CONTAINER_NAME)
        volumeMounts:
          - mountPath: /tmp/grpc-xds/
            name: grpc-td-conf
            readOnly: true
      initContainers:
        - name: grpc-td-init
          image:  gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
          imagePullPolicy: Always
          args:
            - "--output=/tmp/bootstrap/td-grpc-bootstrap.json"
            - "--vpc-network-name=default"
            - "--xds-server-uri=trafficdirector.googleapis.com:443"
            - "--generate-mesh-id"
          volumeMounts:
            - mountPath: /tmp/bootstrap/
              name: grpc-td-conf
      volumes:
        - name: grpc-td-conf
          emptyDir:
            medium: Memory

EOF

Python

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-client
  namespace: proxyless-example
  labels:
    app: psm-grpc-client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: psm-grpc-client
  template:
    metadata:
      labels:
        app: psm-grpc-client
        service.istio.io/canonical-name: deployment-psm-grpc-client
    spec:
      containers:
      - name: psm-grpc-client
        image: grpc/csm-o11y-example-python-client:v1.68.1
        imagePullPolicy: Always
        args:
          - "--target=xds:///helloworld.proxyless-example.svc.cluster.local:50051"
        env:
          - name: GRPC_XDS_BOOTSTRAP
            value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
          - name: CSM_WORKLOAD_NAME
            value: psm-grpc-client
          - name: CSM_CANONICAL_SERVICE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.labels['service.istio.io/canonical-name']
          - name: CSM_MESH_ID
            value: proj-PROJECT_NUMBER
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: NAMESPACE_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: CONTAINER_NAME
            value: psm-grpc-client
          - name: OTEL_RESOURCE_ATTRIBUTES
            value: k8s.pod.name=\$(POD_NAME),k8s.namespace.name=\$(NAMESPACE_NAME),k8s.container.name=\$(CONTAINER_NAME)
        volumeMounts:
          - mountPath: /tmp/grpc-xds/
            name: grpc-td-conf
            readOnly: true
      initContainers:
        - name: grpc-td-init
          image:  gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
          imagePullPolicy: Always
          args:
            - "--output=/tmp/bootstrap/td-grpc-bootstrap.json"
            - "--vpc-network-name=default"
            - "--xds-server-uri=trafficdirector.googleapis.com:443"
            - "--generate-mesh-id"
          volumeMounts:
            - mountPath: /tmp/bootstrap/
              name: grpc-td-conf
      volumes:
        - name: grpc-td-conf
          emptyDir:
            medium: Memory

EOF

Automatico

Esegui un client gRPC e indirizzalo a utilizzare la configurazione di routing specificata da HTTPRoute:

C++

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-client
  namespace: proxyless-example
  labels:
    app: psm-grpc-client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: psm-grpc-client
  template:
    metadata:
      labels:
        app: psm-grpc-client
    spec:
      containers:
      - name: psm-grpc-client
        image: grpc/csm-o11y-example-cpp-client:v1.68.1
        imagePullPolicy: Always
        args:
          - "--target=xds:///helloworld.proxyless-example.svc.cluster.local:50051"
EOF

Java

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-client
  namespace: proxyless-example
  labels:
    app: psm-grpc-client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: psm-grpc-client
  template:
    metadata:
      labels:
        app: psm-grpc-client
    spec:
      containers:
      - name: psm-grpc-client
        image: grpc/csm-o11y-example-java-client:v1.68.2
        imagePullPolicy: Always
        args:
          - "world"
          - "xds:///helloworld.proxyless-example.svc.cluster.local:50051"
          - "9464"
EOF

Go

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-client
  namespace: proxyless-example
  labels:
    app: psm-grpc-client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: psm-grpc-client
  template:
    metadata:
      labels:
        app: psm-grpc-client
    spec:
      containers:
      - name: psm-grpc-client
        image: grpc/csm-o11y-example-go-client:v1.69.4
        imagePullPolicy: Always
        args:
          - "--target=xds:///helloworld.proxyless-example.svc.cluster.local:50051"
EOF

Python

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: psm-grpc-client
  namespace: proxyless-example
  labels:
    app: psm-grpc-client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: psm-grpc-client
  template:
    metadata:
      labels:
        app: psm-grpc-client
    spec:
      containers:
      - name: psm-grpc-client
        image: grpc/csm-o11y-example-python-client:v1.68.1
        imagePullPolicy: Always
        args:
          - "--target=xds:///helloworld.proxyless-example.svc.cluster.local:50051"
EOF

L'output è simile a:

deployment.apps/psm-grpc-client created

Per verificare se il client è riuscito a raggiungere il servizio, visualizza i log del client:

kubectl logs -n proxyless-example $(kubectl get po -n proxyless-example | grep psm-grpc-client | awk '{print $1;}') -f

L'output è simile a:

Defaulted container "psm-grpc-client" out of: psm-grpc-client, grpc-td-init (init)
Greeter received: Hello from psm-grpc-server-xxxxxxx-xxxx world

Configurazione di Google Cloud Managed Service per Prometheus (facoltativo)

Puoi eseguire il deployment della risorsa Google Cloud Managed Service per Prometheus PodMonitoring per esportare le metriche in Cloud Monitoring.

  • Per i server, esegui il comando seguente:

    kubectl apply -f - <<EOF
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: psm-grpc-server-gmp
      namespace: proxyless-example
    spec:
      selector:
        matchLabels:
          app: psm-grpc-server
      endpoints:
      - port: 9464
        interval: 10s
    EOF
    
  • Per i client, esegui il comando seguente:

    kubectl apply -f - <<EOF
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: psm-grpc-client-gmp
      namespace: proxyless-example
    spec:
      selector:
        matchLabels:
          app: psm-grpc-client
      endpoints:
      - port: 9464
        interval: 10s
    EOF
    

    Dopo aver eseguito il deployment della risorsa PodMonitoring, ogni 10 secondi verrà eseguito lo scraping di localhost:9464/metrics di ogni pod corrispondente e i risultati verranno esportati in Cloud Monitoring.

Per visualizzare le metriche in Cloud Monitoring:

puoi andare alla sezione "Metrics Explorer" della tua Google Cloud console, selezionare Target Prometheus > Grpc per trovare le metriche.

Vai a Esplora metriche

Puoi osservare i workload e i servizi di cui è stato eseguito il deployment nella sezione "Mesh di servizi" della console Google Cloud .

Vai al mesh di servizi

Risolvere i problemi di osservabilità di Cloud Service Mesh

Questa sezione mostra come risolvere i problemi comuni.

Le metriche non vengono esportate / visualizzate

Assicurati che tutti i file binari coinvolti (sia client che server) siano configurati con Observability.

Se utilizzi l'esportatore Prometheus, verifica che l'URL dell'esportatore Prometheus sia configurato come previsto.

Assicurati che i canali gRPC siano abilitati per Cloud Service Mesh. I canali devono avere un target nel formato xds:///. I server gRPC sono sempre abilitati per Cloud Service Mesh.

Nessuna metrica esportata / il valore di un attributo di una metrica viene visualizzato come sconosciuto

Cloud Service Mesh Observability determina le informazioni topologiche del mesh tramite le etichette di ambiente. Assicurati che la specifica del pod o del servizio sia per il client che per il servizio specifichi tutte le etichette come descritto nell'esempio.

  1. Descrivi il deployment psm-grpc-server:

    kubectl describe Deployment psm-grpc-server -n proxyless-example \
    | grep "psm-grpc-server:" -A 12
    

    L'output è simile a:

    psm-grpc-server:
    Image:      grpc/csm-example-server:2024-02-13
    Port:       50051/TCP
    Host Port:  0/TCP
    Args:
      --port=50051
    Environment:
      GRPC_XDS_BOOTSTRAP:          /tmp/grpc-xds/td-grpc-bootstrap.json
      POD_NAME:                     (v1:metadata.name)
      NAMESPACE_NAME:               (v1:metadata.namespace)
      CSM_WORKLOAD_NAME:           psm-grpc-server
      OTEL_RESOURCE_ATTRIBUTES:    k8s.pod.name=$(POD_NAME),k8s.namespace.name=$(NAMESPACE_NAME),k8s.container.name=$(CONTAINER_NAME)
    
  2. Descrivi il deployment psm-grpc-client:

    kubectl describe Deployment psm-grpc-client -n proxyless-example \
    | grep "psm-grpc-client:" -A 12
    

    L'output è simile a:

    psm-grpc-client:
    Image:      grpc/csm-example-client:2024-02-13
    Port:       <none>
    Host Port:  <none>
    Args:
      --target=xds:///helloworld.proxyless-example.svc.cluster.local:50051
    Environment:
      GRPC_XDS_BOOTSTRAP:          /tmp/grpc-xds/td-grpc-bootstrap.json
      CSM_WORKLOAD_NAME:           test-workload-name
      POD_NAME:                     (v1:metadata.name)
      NAMESPACE_NAME:               (v1:metadata.namespace)
      CONTAINER_NAME:              psm-grpc-client