This article provides step-by-step instructions on configuring a gRPC backend on Cloud Run and an Apigee X Proxy by updating an existing Envoy based Load Balancer. We'll show how to create unique URLs / routing urls on the GCP Load Balancer that will only work for gRPC / http2 services. This walkthrough compliments the instructions published here:
https://cloud.google.com/apigee/docs/api-platform/fundamentals/build-simple-api-proxy#creating-grpc-...
All the commands / instructions should be run in a GCP Cloud Shell (https://shell.cloud.google.com) session in the GCP project where Apigee is installed.
We'll use Docker containers and Cloud Run for the gRPC backend
export PROJECT=$GOOGLE_CLOUD_PROJECT
mkdir grpc-backend
cd grpc-backend
git clone https://github.com/grpc/grpc.git
cd $HOME/grpc-backend/grpc/examples/python/helloworld
touch Dockerfile
cloudshell edit Dockerfile
FROM python:3.7
WORKDIR /app
COPY . .
RUN pip install grpcio protobuf
EXPOSE 50051
CMD ["python", "greeter_server.py"]
docker build .
docker images -a
export DOCKER_IMAGE=<imageid>
docker run -p 8080:50051 -it $DOCKER_IMAGE
grpcurl -plaintext -import-path $HOME/grpc-backend/grpc/examples/protos \
-proto helloworld.proto -d '{"name":"Guest"}' \
localhost:8080 helloworld.Greeter/SayHello
gcloud artifacts repositories create grpcdemo \
--repository-format=Docker \
--location=us \
--description="gRPC Demo repo"
gcloud auth configure-docker us-docker.pkg.dev
export REGION=us-east1
docker tag $DOCKER_IMAGE us-docker.pkg.dev/$PROJECT/grpcdemo/my-grpc-service
docker push us-docker.pkg.dev/$PROJECT/grpcdemo/my-grpc-service
gcloud run deploy my-grpc-service \
--image us-docker.pkg.dev/$PROJECT/grpcdemo/my-grpc-service \
--platform managed --use-http2 --allow-unauthenticated \
--region $REGION --port 50051
grpcurl -import-path $HOME/grpc-backend/grpc/examples/protos -proto helloworld.proto \
-d '{"name":"Guest"}' <serviceurl>:443 helloworld.Greeter/SayHello
If you get a successful response you’re ready to update the GCP LB to support gRPC!
For this step, we’ll create a unique path for gRPC traffic. We'll use a unique ssl certificate and a route rule for the domain name using the nip.io service. This assumes that your backend is using a PSC NEG connected to Apigee. If you’re using MIGs, you can follow the public documentation for these steps.
gcloud compute forwarding-rules list
export FORWARDING_RULE=<NAME from above>
export IP_ADDRESS=<IP_ADDRESS from above>
export TARGET_PROXY=<TARGET from above>
gcloud compute target-https-proxies describe $TARGET_PROXY
export URL_MAP=<url map name from above>
export SSL_CERT=<certificate name from above>
gcloud compute ssl-certificates describe $SSL_CERT --format json | jq .managed.domains
export DOMAINS="<existing domain name>","grpc.$IP_ADDRESS.nip.io"
gcloud compute ssl-certificates create apigee-ssl-grpc \
--domains $DOMAINS
gcloud compute target-https-proxies update $TARGET_PROXY \
--ssl-certificates apigee-ssl-grpc
gcloud compute backend-services create apigee-grpc \
--load-balancing-scheme=EXTERNAL_MANAGED \
--protocol=HTTP2 \
--global --project=$PROJECT
gcloud compute network-endpoint-groups list
export APIGEE_NEG=<NAME from above>
gcloud compute backend-services add-backend apigee-grpc \
--network-endpoint-group=$APIGEE_NEG \
--network-endpoint-group-region=<LOCATION from above> \
--global --project=$PROJECT
gcloud compute url-maps edit $URL_MAP
defaultService:<DO NOT REMOVE/MODIFY THE ORIGINAL OUTPUT. COPY AND PASTE ONLY THE hostRules THE BELOW>
hostRules:
- hosts:
- grpc.<IP-ADDRESS>.nip.io
pathMatcher: grpc-domain
name: apigee-lb
pathMatchers:
- defaultService: https://www.googleapis.com/compute/v1/projects/<PROJECT_ID>/global/backendServices/apigee-grpc
name: grpc-domain
<TargetEndpoint name="default">
<Description/>
<FaultRules/>
<HTTPTargetConnection>
<LoadBalancer>
<Server name="grpc-server"/>
</LoadBalancer>
<Path>/helloworld.Greeter/SayHello</Path>
</HTTPTargetConnection>
</TargetEndpoint>
grpcurl -import-path $HOME/grpc-backend/grpc/examples/protos -proto helloworld.proto -d '{"name":"Guest"}'grpc.<IP Address>.nip.io:443 helloworld.Greeter/SayHello
<VerifyAPIKey continueOnError="false" enabled="true" name="VA-VerifyKey">
<DisplayName>VA-VerifyKey</DisplayName>
<Properties/>
<APIKey ref="request.header.apikey"/>
</VerifyAPIKey>
grpcurl -import-path $HOME/grpc/examples/protos -proto helloworld.proto -H "apikey":"<api key>" -d '{"name":"Guest"}' grpc.<IP Address>nip.io:443 helloworld.Greeter/SayHello