Skip to content

Commit

Permalink
http2 gRPC go tutorial (#83)
Browse files Browse the repository at this point in the history
* (wip) http2 gRPC go tutorial

* complete readme + tutorial files

* add testing step

* replaced my container with placeholder

* Apply suggestions from code review

Co-authored-by: SamyOubouaziz <[email protected]>

* smoothen packages

---------

Co-authored-by: SamyOubouaziz <[email protected]>
  • Loading branch information
thomas-tacquet and SamyOubouaziz authored Apr 24, 2024
1 parent 3db6e78 commit e293672
Show file tree
Hide file tree
Showing 10 changed files with 584 additions and 14 deletions.
30 changes: 16 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Table of Contents:
- [🚀 Functions](#-functions)
- [📦 Containers](#-containers)
- [⚙️ Jobs](#️-jobs)
- [💬 Messaging and Queueing](#-mnq)
- [💬 Messaging and Queueing](#-messaging-and-queueing)
- [💜 Projects](#-projects)
- [Contributing](#contributing)

Expand All @@ -28,8 +28,9 @@ Table of Contents:
### 🚀 Functions

<!-- markdownlint-disable MD033 -->

| Example | Runtime | Deployment |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|------------------------|
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ---------------------- |
| **[Badge PHP](functions/badge-php/README.md)** <br/> A PHP function to generate repository badges. | php82 | [Serverless Framework] |
| **[CORS Go](functions/cors-go/README.md)** <br/> A Go function which allows CORS requests. | go119 | [Serverless Framework] |
| **[CORS Node](functions/cors-node/README.md)** <br/> A Node function which allows CORS requests. | node18 | [Serverless Framework] |
Expand Down Expand Up @@ -57,12 +58,12 @@ Table of Contents:
| **[Typescript with Node runtime](functions/typescript-with-node/README.md)** <br/> A Typescript function using Node runtime. | node18 | [Serverless Framework] |
| **[Serverless Gateway Python Example](functions/serverless-gateway-python/README.md)** <br/> A Python serverless API using Serverless Gateway. | python310 | [Python API Framework] |
| **[Go and Transactional Email](functions/go-mail/README.md)** <br/> A Go function that send emails using Scaleway SDK. | go121 | [Serverless Framework] |
| **[Rotate RDB Credentials](functions/secret-manager-rotate-secret/README.md)** <br/> A Go function that rotates RDB credentials stored in Secret Manager. | go120 | [Serverless Framework] |
| **[Rotate RDB Credentials](functions/secret-manager-rotate-secret/README.md)** <br/> A Go function that rotates RDB credentials stored in Secret Manager. | go120 | [Serverless Framework] |

### 📦 Containers

| Example | Language | Deployment |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|------------------------|
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ---------------------- |
| **[Container Bash Script](containers/bash-scheduled-job/README.md)** <br/> A Bash script runnning on a schedule using serverless containers. | Bash | [Serverless Framework] |
| **[Function Handler Java](containers/function-handler-java/README.md)** <br/> A Java function handler deployed on CaaS. | Java | [Serverless Framework] |
| **[NGINX CORS Private](containers/nginx-cors-private-python/README.md)** <br/> An NGINX proxy to allow CORS requests to a private container. | Python Flask | [Terraform] |
Expand All @@ -71,26 +72,27 @@ Table of Contents:
| **[Python S3 upload](containers/python-s3-upload/README.md)** <br/> A Python + Flask HTTP server that receives file uploads and writes them to S3. | Python | [Terraform] |
| **[Terraform NGINX hello world](containers/terraform-nginx-hello-world/README.md)** <br/> A minimal example running the base NGINX image in a serverless container deployed with Terraform. | N/A | [Terraform] |
| **[Triggers with Terraform](containers/terraform-triggers/README.md)** <br/> Configuring two SQS triggers, used to trigger two containers, one public, one private. | N/A | [Terraform] |
| **[gRPC HTTP2 in Go](containers/grpc-http2-go/README.md)** <br/> A Go gRPC Container using http2 | Go/Protobuf | [CLI] |

### ⚙️ Jobs

| Example | Language | Deployment |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|------------------------|
| **[Serverless Jobs Hello World](jobs/terraform-hello-world/README.md)** <br/> An example of building a container image and running it as a Serverless Job using Terraform. | N/A |[Terraform]-[Console]|
| **[Serverless MLOps](jobs/ml-ops/README.md)** <br/> An example of running a Serverless Machine Leaning workflow. | Python |[Terraform]-[Console]-[CLI]|
| Example | Language | Deployment |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------- |
| **[Serverless Jobs Hello World](jobs/terraform-hello-world/README.md)** <br/> An example of building a container image and running it as a Serverless Job using Terraform. | N/A | [Terraform]-[Console] |
| **[Serverless MLOps](jobs/ml-ops/README.md)** <br/> An example of running a Serverless Machine Leaning workflow. | Python | [Terraform]-[Console]-[CLI] |

### 💬 Messaging and Queueing

| Example | Services | Language | Deployment |
|---------------------------------------------------------------------------------------------------------------------------------------------------------|------------------|----------|-------------|
| **[Manage large message](mnq/large-messages/README.md)** <br/> An example of infrastructure to manage large messages. | PaaS & S3 | Python | [Terraform] |
| **[Serverless scraping](mnq/serverless-scraping/README.md)** <br/> An example of infrastructure to scrape the hackernews website. | PaaS & RDB | Python | [Terraform] |
| **[SNS Instances Notification System](mnq/sns-instances-notification-system/README.md)** <br/> An example of infrastructure to use SNS with Instances. | PaaS & Instances | Golang | [Terraform] |
| Example | Services | Language | Deployment |
| ------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | -------- | ----------- |
| **[Manage large message](mnq/large-messages/README.md)** <br/> An example of infrastructure to manage large messages. | PaaS & S3 | Python | [Terraform] |
| **[Serverless scraping](mnq/serverless-scraping/README.md)** <br/> An example of infrastructure to scrape the hackernews website. | PaaS & RDB | Python | [Terraform] |
| **[SNS Instances Notification System](mnq/sns-instances-notification-system/README.md)** <br/> An example of infrastructure to use SNS with Instances. | PaaS & Instances | Golang | [Terraform] |

### 💜 Projects

| Example | Services | Language | Deployment |
|-------------------------------------------------------------------------------------------------------------------------------------------|-------------|----------|------------------------|
| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -------- | ---------------------- |
| **[Kong API Gateway](projects/kong-api-gateway/README.md)** <br/> Deploying a Kong Gateway on containers to provide routing to functions. | CaaS & FaaS | Python | [Serverless Framework] |
| **[Serverless Gateway](https://github.com/scaleway/serverless-gateway)** <br/> Our serverless gateway for functions and containers. | API Gateway | Python | [Python API Framework] |
| **[Monitoring Glaciers](projects/blogpost-glacier/README.md)** <br/> A project to monitor glaciers and the impact of global warming. | S3 & RDB | Golang | [Serverless Framework] |
Expand Down
28 changes: 28 additions & 0 deletions containers/grpc-http2-go/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FROM golang:1.22-bookworm as build

# Set working directory
WORKDIR /app

# Copy required files
COPY go.mod .
COPY go.sum .
COPY server/*.go ./server/
COPY hello.proto ./

# We install the protobuf compilation stack on the image directly to simplify workflow
RUN apt-get update && apt-get install -y protobuf-compiler
RUN go install google.golang.org/protobuf/cmd/[email protected]
RUN go install google.golang.org/grpc/cmd/[email protected]

# Generate go protobuf files
RUN protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative hello.proto

# Build the executable
RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build server/main.go

# Put the executable in a light scratch image
FROM scratch

COPY --from=build /app/main /server

ENTRYPOINT ["/server"]
92 changes: 92 additions & 0 deletions containers/grpc-http2-go/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# gRPC HTTP2 Server in Go using CLI

This example demonstrates the deployment of a gRPC service on Scaleway Serverless Containers.

For this example, we will use the CLI to deploy the container, but you can use [other methods](https://www.scaleway.com/en/docs/serverless/containers/reference-content/deploy-container/).
You can also use the CLI directly from Scaleway console without having to use your credentials.

## Workflow

Here are the different steps we are going to proceed:

- Quick set-up of Container Registry to host our gRPC container
- Deploy the Serverless Container
- Run gRPC test command ot ensure everything is ok

## Deployment

### Requirements

To complete the actions presented below, you must have:
- installed and configured the [Scaleway CLI](https://www.scaleway.com/en/docs/developer-tools/scaleway-cli/quickstart/)
- installed [Docker](https://docs.docker.com/engine/install/) to build the image
- installed the common [gRPC stack](https://grpc.io/blog/installation/)) to test locally (optional)

### Building the image

1. Run the following command in a terminal to create Container Registry namespace to store the image:

```bash
scw registry namespace create name=hello-grpc
```

The registry namespace information displays.

1. Copy the namespace endpoint (in this case, `rg.fr-par.scw.cloud/hello-grpc`).

1. Log into the Container Registry namespace you created using Docker:

```bash
docker login rg.fr-par.scw.cloud/hello-grpc -u nologin --password-stdin <<< "$SCW_SECRET_KEY"
```

At this point, you have correctly set up Docker to be able to push your image online.

1. In a terminal, access this directory (containing the Dockerfile), and run the following command to build the image:

```bash
docker build -t grpc:latest .
```

1. Tag and push the image to the registry namespace:

```bash
docker tag grpc:latest rg.fr-par.scw.cloud/hello-grpc/grpc:latest
docker push rg.fr-par.scw.cloud/hello-grpc/grpc:latest
```

### Deploying the image

In a terminal, run the following command to create a Serverless Containers namespace:

```bash
scw container namespace create name=grpc-test
```
The namespace information displays.

1. Copy the namespace ID.

1. Run the following command to create and deploy the container (make sure to use the `h2c` protocol to connect via HTTP2):

```bash
scw container container create namespace-id=<PREVIOUS_NAMESPACE_ID> protocol=h2c name=grpc-test registry-image=rg.fr-par.scw.cloud/hello-grpc/grpc:latest
```
The container information displays.

1. Copy the DomainName (endpoint) to test your container.

### Testing

Make sure your container is in a `ready` status before testing it.

1. In the `client/client.go` file, replace the constant `containerEndpoint` with the `DomainName` copied previously.

1. Make sure to keep the `:80` port at the end even if you container port is set to 8080, as these are two different settings.

1. Run the command below to check if your container responds:

`go run client/client.go'
## Additional content
- [Basic Go gRPC tutorial](https://grpc.io/docs/languages/go/basics/)
36 changes: 36 additions & 0 deletions containers/grpc-http2-go/client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package main

import (
"context"
"flag"
"log"
"time"

pb "github.com/scaleway/serverless-examples/containers/grpc-http2-go"
"google.golang.org/grpc"
)

const containerEndpoint = "YOUR_CONTAINER_ENDPOINT:80"

func main() {
flag.Parse()
// Set up a connection to the server.
conn, err := grpc.Dial(containerEndpoint, grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}

defer conn.Close()
c := pb.NewGreeterClient(conn)

// Contact the server and print out its response.
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

r, err := c.SayHello(ctx, &pb.HelloRequest{Name: "Scaleway"})
if err != nil {
log.Fatalf("could not greet: %v", err)
}

log.Printf("Greeting: %s", r.GetMessage())
}
17 changes: 17 additions & 0 deletions containers/grpc-http2-go/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module github.com/scaleway/serverless-examples/containers/grpc-http2-go

go 1.22.1

require (
google.golang.org/grpc v1.63.2
google.golang.org/protobuf v1.33.0
)

require (
golang.org/x/net v0.24.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect
)

replace github.com/scaleway/serverless-examples/containers/grpc-http2-go => .
14 changes: 14 additions & 0 deletions containers/grpc-http2-go/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be h1:LG9vZxsWGOmUKieR8wPAUR3u3MpnYFQZROPIMaXh7/A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
Loading

0 comments on commit e293672

Please sign in to comment.