Skip to content

Commit

Permalink
endpoints: add gRPC getting started sample (#217)
Browse files Browse the repository at this point in the history
The gRPC code is based off gRPC's hello world:
https://github.com/grpc/grpc-go/tree/master/examples/helloworld
  • Loading branch information
broady committed Apr 3, 2017
1 parent 3e3d902 commit ba055b8
Show file tree
Hide file tree
Showing 9 changed files with 574 additions and 0 deletions.
13 changes: 13 additions & 0 deletions endpoints/getting-started-grpc/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM golang:alpine

RUN apk update \
&& apk add git

COPY . /go/src/app

# Don't do this in production! Use vendoring instead.
RUN go get -v app/server

RUN go install app/server

ENTRYPOINT ["/go/bin/server"]
144 changes: 144 additions & 0 deletions endpoints/getting-started-grpc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Google Cloud Endpoints Sample for Go using gRPC

This sample demonstrates how to use Google Cloud Endpoints using Go and gRPC.

For a complete walkthrough, see the following guides:

* [Quickstart with gRPC on Container Engine](https://cloud.google.com/endpoints/docs/quickstart-grpc-container-engine)
* [Quickstart with gRPC on Compute Engine](https://cloud.google.com/endpoints/docs/quickstart-grpc-compute-engine-docker)

## Test the code locally (optional)

Run the backend using `go run`:

```bash
$ go run server/main.go
```

Send a request from another terminal:

```bash
$ go run client/main.go
2017/03/30 17:08:32 Greeting: Hello world
```

## Deploying service config

1. First, generate `out.pb` from the proto file:

```bash
protoc --include_imports --include_source_info helloworld/helloworld.proto --descriptor_set_out out.pb
```

1. Edit `api_config.yaml`. Replace `YOUR_PROJECT_ID`:

```yaml
name: hellogrpc.endpoints.YOUR_PROJECT_ID.cloud.goog
```

1. Deploy your service:

```bash
gcloud service-management deploy out.pb api_config.yaml
```

Your config ID should be printed out, it looks like `2017-03-30r0`.
Take a note of it, you'll need it later.
You can list the config IDs using this command:
```bash
gcloud service-management configs list --service hellogrpc.endpoints.YOUR_PROJECT_ID.cloud.goog
```
## Building the server's Docker container

Build and tag your gRPC server, storing it in your private container registry:

```bash
gcloud container builds submit --tag gcr.io/YOUR_PROJECT_ID/go-grpc-hello:1.0 .
```

## Deploy to GCE or GKE

### Deploy to GCE

1. Create an instance and SSH into it:

```bash
gcloud compute instances create grpc-host --image-family gci-stable --image-project google-containers --tags=http-server
gcloud compute ssh grpc-host
```

1. Set some environment variables (you'll need to manually set the service config ID):
```bash
GCLOUD_PROJECT=$(curl -s "http://metadata.google.internal/computeMetadata/v1/project/project-id" -H "Metadata-Flavor: Google")
SERVICE_NAME=hellogrpc.endpoints.${GCLOUD_PROJECT}.cloud.goog
SERVICE_CONFIG_ID=<Your Config ID>
```
1. Pull your credentials to access your private container registry:
```bash
/usr/share/google/dockercfg_update.sh
```
1. Run your gRPC server's container:

```bash
docker run -d --name=grpc-hello gcr.io/${GCLOUD_PROJECT}/go-grpc-hello:1.0
```

1. Run Endpoints proxy:

```bash
docker run --detach --name=esp \
-p 80:9000 \
--link=grpc-hello:grpc-hello \
gcr.io/endpoints-release/endpoints-runtime:1 \
-s ${SERVICE_NAME} \
-v ${SERVICE_CONFIG_ID} \
-P 9000 \
-a grpc://grpc-hello:50051
```

1. Get the IP address of your secured gRPC server:

```bash
gcloud compute instances list --filter=grpc-host
```

1. Send a request to the API server (see "Running the client" below)

### Deploy to GKE

If you haven't got a cluster, first [create one](https://cloud.google.com/container-engine/docs/clusters/operations).
1. Edit `container-engine.yaml`. Replace `<YOUR_PROJECT_ID>` and `<SERVICE_CONFIG_ID>`.
1. Create the deployment and service:
```
kubectl apply -f container-engine.yaml
```
1. Wait until the load balancer is active:
```
kubectl get svc grpc-hello --watch
```
1. Send a request to the API server (see "Running the client" below)
## Running the client
1. First, [create a project API key](https://console.developers.google.com/apis/credentials).
1. Then, after you have your server's IP address (via GKE's `kubectl get svc` or your GCE instance's IP), run:

```bash
go run client/main.go -api-key=AIza.... -addr=YOUR_SERVER_IP_ADDRESS:80 [message]
```

[1]: https://cloud.google.com/endpoints/docs/quickstarts
16 changes: 16 additions & 0 deletions endpoints/getting-started-grpc/api_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# An example API configuration.
#
# Below, replace YOUR_PROJECT_ID with your Google Cloud Project ID.

# The configuration schema is defined by service.proto file
# https://github.com/googleapis/googleapis/blob/master/google/api/service.proto
type: google.api.Service
config_version: 3

# Name of the service configuration.
name: hellogrpc.endpoints.YOUR_PROJECT_ID.cloud.goog

# API title to appear in the user interface (Google Cloud Console).
title: Hello gRPC API
apis:
- name: helloworld.Greeter
77 changes: 77 additions & 0 deletions endpoints/getting-started-grpc/client/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

package main

import (
"flag"
"log"

"golang.org/x/net/context"
"google.golang.org/grpc"
pb "google.golang.org/grpc/examples/helloworld/helloworld"
"google.golang.org/grpc/metadata"
)

const defaultName = "world"

var (
addr = flag.String("addr", "127.0.0.1:50051", "Address of grpc server.")
key = flag.String("api-key", "", "API key.")
)

func main() {
flag.Parse()

// Set up a connection to the server.
conn, err := grpc.Dial(*addr, grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewGreeterClient(conn)

ctx := context.Background()
ctx = metadata.NewContext(ctx, metadata.Pairs("x-api-key", *key))

// Contact the server and print out its response.
name := defaultName
if len(flag.Args()) > 0 {
name = flag.Arg(0)
}
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.Message)
}
40 changes: 40 additions & 0 deletions endpoints/getting-started-grpc/container-engine.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
apiVersion: v1
kind: Service
metadata:
name: grpc-hello
spec:
ports:
- port: 80
targetPort: 9000
protocol: TCP
name: http
selector:
app: grpc-hello
type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: grpc-hello
spec:
replicas: 1
template:
metadata:
labels:
app: grpc-hello
spec:
containers:
- name: esp
image: gcr.io/endpoints-release/endpoints-runtime:1
args: [
"-P", "9000",
"-a", "grpc://127.0.0.1:50051",
"-s", "hellogrpc.endpoints.<YOUR_PROJECT_ID>.cloud.goog", # replace <YOUR_PROJECT_ID>
"-v", "<SERVICE_CONFIG_ID>", # e.g. "2017-03-30r0"
]
ports:
- containerPort: 9000
- name: echo
image: gcr.io/<YOUR_PROJECT_ID>/go-grpc-hello:1.0 # replace <YOUR_PROJECT_ID>
ports:
- containerPort: 50051
Loading

0 comments on commit ba055b8

Please sign in to comment.