Configurare un mesh di servizi gRPC proxyless su GKE

In questa pagina viene descritto come eseguire il deployment di un client e un server gRPC senza proxy di esempio in un 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 proxyless all'interno del tuo mesh di servizi:

Metodo 1: configurazione manuale

Questo metodo richiede la configurazione manuale dei componenti necessari per il servizio gRPC proxyless.

  • InitContainer: utilizza un initContainer all'interno della specifica del pod per eseguire il generatore di bootstrap gRPC di Cloud Service Mesh. Questo generatore produce la configurazione richiesta per il tuo servizio.
  • Montaggio del volume: monta un volume contenente la configurazione generata dall'initContainer. In questo modo, l'applicazione può accedere alle impostazioni necessarie.
  • Variabili di ambiente: includi le variabili di ambiente appropriate per attivare l'emissione delle metriche di osservabilità CSM dalla tua applicazione. Queste metriche forniscono informazioni preziose sul rendimento del tuo servizio.

Metodo 2: automatico con Proxyless Bootstrap Injector

Anziché configurare manualmente il servizio gRPC proxyless, puoi optare per un approccio semplificato utilizzando Proxyless Bootstrap Injector.

Questa funzionalità automatizza la procedura di configurazione, semplificando l'implementazione del servizio. Per attivarla, aggiungi l'etichettamesh.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, facendoti risparmiare tempo e fatica.

Se hai bisogno di un controllo più granulare, puoi anche applicare questa etichetta direttamente ai singoli podi. In questo modo puoi eseguire l'override dell'impostazione a livello di spazio dei nomi e personalizzare il comportamento di inserimento in base al pod.

Seguendo uno di questi metodi, puoi stabilire correttamente un servizio gRPC senza proxy all'interno del tuo 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.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: 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.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: 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.0
        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

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 Proxyless Bootstrap Injector 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.0
        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
    

    Attendi che tutti i pod siano pronti e che lo stato Status sia In esecuzione prima di continuare.

  2. Esegui il deployment di una 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 parametro HTTPRoute denominato app1 e invia tutte le RPC al serviziohelloworld.

    Tieni presente che il servizio parentRef è anche helloworld, il che significa che la nostra route HTTP è collegata a questo servizio ed elaborerà tutte le RPC indirizzate a questo servizio. In caso di gRPC senza proxy, si riferisce a qualsiasi client che invia RPC su un canale gRPC per la destinazione xds:///helloworld.proxyless-example.svc.cluster.local:50051.

  3. Verifica che sia stato creato il nuovo percorso HTTP app1:

    kubectl get httproute
    

    L'output è simile a

    NAME   HOSTNAMES   AGE
    app1               72s
    

Configura il client gRPC proxyless

Questa sezione descrive come utilizzare un client gRPC per verificare che Cloud Service Mesh instrada 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 con Proxyless Bootstrap Injector

In alternativa, puoi utilizzare l'iniettore automatico per semplificare la procedura di configurazione del client. In questo modo, la configurazione viene semplificata e l'intervento manuale viene ridotto. Ciò si ottiene applicando l'etichetta allo spazio dei nomi.

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

Manuale

Esegui un client gRPC e invitalo 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.0
        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 invitalo 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.0
        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 relativi log:

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

L'output è simile al seguente:

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

(Facoltativo) Configurazione di Google Cloud Managed Service per Prometheus

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 seguente comando:

    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 seguente comando:

    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 disegnato la risorsa PodMonitoring, ogni localhost:9464/metrics del pod corrispondente verrà sottoposto a scansione ogni 10 secondi ed esporterà i risultati in Cloud Monitoring.

Per visualizzare le metriche in Cloud Monitoring, svolgi i seguenti passaggi:

Puoi andare alla sezione "Metrics Explorer" della consoleGoogle Cloud , selezionare Destinazione 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 "Service Mesh" della console Google Cloud .

Vai a Service Mesh

Risolvere i problemi di osservabilità di Cloud Service Mesh

Questa sezione mostra come risolvere i problemi più comuni.

Le metriche non vengono esportate / visualizzate

Assicurati che tutti i 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 del tipo xds:///. I server gRPC sono sempre abilitati per Cloud Service Mesh.

Nessuna metrica esportata / Un valore dell'attributo in una metrica viene visualizzato come sconosciuto

L'osservabilità di Cloud Service Mesh determina le informazioni sulla topologia del mesh tramite le etichette dell'ambiente. Assicurati che le specifiche del pod o del servizio sia per il client sia per il servizio specifichino tutte le etichette come descritto nell'esempio.

  1. Descrivi il deployment di psm-grpc-server:

    kubectl describe Deployment psm-grpc-server | grep "psm-grpc-server:" -A 12
    

    L'output è simile al seguente:

    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 di psm-grpc-client:

    kubectl describe Deployment psm-grpc-client | grep "psm-grpc-client:" -A 12
    

    L'output è simile al seguente:

    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