Set up a proxyless gRPC service mesh
This guide demonstrates how to configure a proxyless gRPC service mesh.
The configuration is supported for Preview customers but we do not recommended it for new Cloud Service Mesh users. For more information, see the Cloud Service Mesh overview.
Before you begin
Do not create a proxyless gRPC service mesh in a namespace where Envoy sidecar auto-injection is enabled. To determine whether sidecar injection is enabled, run the following command:
kubectl get namespace default --show-labels
If sidecar auto-injection is enabled, run this command to remove the label:
kubectl label namespace default istio-injection-
Deploy a gRPC service
In this section, you deploy a gRPC helloworld
example service. The
helloworld
example service is a gRPC server application that returns a simple
message in response to a gRPC client's request. The helloworld
service exposes
the gRPC service on port 8080 in the cluster.
In the
grpc-td-helloworld.yaml
file, save the following:apiVersion: v1 kind: Service metadata: name: helloworld namespace: default 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 namespace: default spec: selector: matchLabels: run: app1 replicas: 2 template: metadata: labels: run: app1 annotations: sidecar.istio.io/inject: "false" spec: containers: - image: grpc/java-example-hostname:1.37.0 name: app1 ports: - protocol: TCP containerPort: 50051
Apply the file
grpc-td-helloworld.yaml
:kubectl apply -f grpc-td-helloworld.yaml
Verify that the new
helloworld
service is created:kubectl get svc -n default
The output is similar to the following:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT (S) AGE helloworld ClusterIP 10.71.9.71 <none> 8080/TCP 41m [..skip..]
Verify that the application Pod is running:
kubectl get pods -n default
The output Pods should be similar to the following:
NAME READY STATUS RESTARTS AGE app1-6db459dcb9-zvfg2 1/1 Running 0 6m app1-6db459dcb9-hlvhj 1/1 Running 0 6m [..skip..]
Configure a gRPC service mesh
In this section, you configure a simple gRPC service mesh.
In the file
td-grpc-mesh.yaml
, save the followingmesh
manifest:kind: TDMesh apiVersion: net.gke.io/v1alpha1 metadata: name: td-grpc-mesh namespace: default spec: gatewayClassName: gke-td allowedRoutes: namespaces: from: All kinds: - group: net.gke.io kind: TDGRPCRoute
Apply the mesh manifest to
gke-1
:kubectl apply -f td-grpc-mesh.yaml
The example
TDMesh
allows onlyTDGRPCRoute
resources to be attached to it. The manifest defines which types of route are allowed.Verify that the new
td-grpc-mesh
mesh is created:kubectl describe tdmesh td-grpc-mesh -n default
The output is similar to the following:
... Status: Conditions: Last Transition Time: 2022-04-14T22:22:09Z Message: Reason: MeshReady Status: True Type: Ready Last Transition Time: 2022-04-14T22:21:41Z Message: Reason: Scheduled Status: True Type: Scheduled Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 79s mc-mesh-controller Processing mesh default/td-grpc-mesh Normal UPDATE 79s mc-mesh-controller Processing mesh default/td-grpc-mesh Normal SYNC 50s mc-mesh-controller SYNC on default/td-grpc-mesh was a success
In the file
helloworld-route.yaml
, save the following manifest:kind: TDGRPCRoute apiVersion: net.gke.io/v1alpha1 metadata: name: helloworld-route namespace: default spec: parentRefs: - name: td-grpc-mesh namespace: default group: net.gke.io kind: TDMesh hostnames: - helloworld rules: - backendRefs: - name: helloworld port: 8080 namespace: default
Apply the
helloworld-route.yaml
manifest togke-1
:kubectl apply -f helloworld-route.yaml
Verify that the new
helloworld-route
GRPCRoute
resource is created:kubectl get tdgrpcroute -n default
Verify the configuration
When the configuration process is complete, verify that you can reach the
helloworld
gRPC server using a proxyless gRPC client. This client connects to
Cloud Service Mesh, obtains information about the helloworld
service, and uses
this information to send traffic to the service's backends.
In the following example, you use the grpcurl
tool to verify that the
Cloud Service Mesh is routing traffic correctly in the mesh. You create a client
Pod, then open a shell and run the verification commands from the shell.
Set up the environment variable and bootstrap file
In a file
grpc-client.yaml
, save the following Pod manifest:apiVersion: v1 kind: Pod metadata: name: static-sleeper namespace: default annotations: sidecar.istio.io/inject: "false" spec: containers: - image: curlimages/curl:7.82.0 imagePullPolicy: IfNotPresent name: sleeper command: - sleep - 365d env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/ initContainers: - args: - --config-mesh-experimental - "gketd-td-grpc-mesh" - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: IfNotPresent name: grpc-td-init volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ volumes: - name: grpc-td-conf emptyDir: medium: Memory
Apply the Pod manifest in
gke-1
:kubectl apply -f grpc-client.yaml
When the Pod is ready, open a shell to the client Pod:
kubectl exec -it static-sleeper -- /bin/sh
You can use the grpcurl
tool as a proxyless gRPC client. The grpcurl
tool
uses environment variable and bootstrap information to connect to
Cloud Service Mesh. The tool then learns about the helloworld
service, which was
configured with Cloud Service Mesh.
To verify your configuration using the grpcurl
tool:
Download and install the
grpcurl
tool:cd /home/curl_user curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.8.1/grpcurl_1.8.1_linux_x86_64.tar.gz | tar -xz
Run the
grpcurl
tool withxds:///helloworld
as the service URI andhelloworld.Greeter/SayHello
as the service name and method to invoke. The parameters to theSayHello
method are passed using the-d
option:./grpcurl --plaintext \ -d '{"name": "world"}' \ xds:///helloworld helloworld.Greeter/SayHello
The output is similar to the following, where
INSTANCE_HOST_NAME
is the hostname of the Pod:Greetings: Hello world, from INSTANCE_HOST_NAME
The output verifies that the proxyless gRPC client successfully connected to
Cloud Service Mesh and learned about the backends for the helloworld
service
using the xds
name resolver. The client sent a request to one of the service's
backends without needing to know the IP address or performing DNS resolution.