Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: add basic grpc example #1905

Merged
merged 3 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 224 additions & 0 deletions examples/grpc-routing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
# gRPC Routing Example

In this example, we deploy NGINX Gateway Fabric, a simple gRPC web application, and then configure NGINX Gateway Fabric
to route traffic to that application using GRPCRoute resources.

## Running the Example

## 1. Deploy NGINX Gateway Fabric

1. Follow the [installation instructions](https://docs.nginx.com/nginx-gateway-fabric/installation/) to deploy NGINX Gateway Fabric.
> **Important**: Ensure the Gateway APIs from the experimental channel are installed and that NGF is deployed with the Gateway experimental features enabled.

1. Save the public IP address of NGINX Gateway Fabric into a shell variable:

```text
GW_IP=XXX.YYY.ZZZ.III
```

1. Save the port of NGINX Gateway Fabric:

```text
GW_PORT=<port number>
```

## 2. Deploy the Helloworld Application

1. Create the two helloworld Deployments and Services:

```shell
kubectl apply -f helloworld.yaml
```

1. Check that the Pods are running in the `default` Namespace:

```shell
kubectl -n default get pods
```

```text
NAME READY STATUS RESTARTS AGE
grpc-infra-backend-v1-766c7d6788-rg92p 1/1 Running 0 12s
grpc-infra-backend-v2-546f7c8d48-mjkkx 1/1 Running 0 12s
```

Save these pod names into variables:

```text
POD_V1=<grpc-infra-backend-v1-xxxxxxxxxx-xxxxx>
POD_V2=<grpc-infra-backend-v2-xxxxxxxxxx-xxxxx>
```

## 3. Configure Routing

There are 3 options to configure gRPC routing. To access the application and test the routing rules, we will use [grpcurl](https://github.com/fullstorydev/grpcurl?tab=readme-ov-file#installation).

### 3a. Configure exact method matching based routing

1. Create the Gateway and GRPCRoute resources:

```shell
kubectl apply -f exact-method.yaml
```

2. Test the Application:

```shell
grpcurl -plaintext -proto grpc.proto -authority bar.com -d '{"name": "exact"}' ${GW_IP}:${GW_PORT} helloworld.Greeter/SayHello
```

```text
{
"message": "Hello exact"
}
```

3. Clean up the Gateway and GRPCRoute resources:

```shell
kubectl delete -f exact-method.yaml
```

### 3b. Configure hostname based routing

1. Create the Gateway and GRPCRoute resources:

```shell
kubectl apply -f hostname.yaml
```

2. Test the Application:

```shell
grpcurl -plaintext -proto grpc.proto -authority bar.com -d '{"name": "bar server"}' ${GW_IP}:${GW_PORT} helloworld.Greeter/SayHello
```

```text
{
"message": "Hello bar server"
}
```

To make sure this came from the correct server, we can check the application server logs:

```shell
kubectl logs ${POD_V1}
```

```text
2024/04/29 09:26:54 server listening at [::]:50051
2024/04/29 09:28:54 Received: bar server
```

Now we'll send a request to `foo.bar.com`

```shell
grpcurl -plaintext -proto grpc.proto -authority foo.bar.com -d '{"name": "foo bar server"}' ${GW_IP}:${GW_PORT} helloworld.Greeter/SayHello
```

```text
{
"message": "Hello foo bar server"
}
```

This time, we'll check the POD_V2 logs:

```shell
kubectl logs ${POD_V2}
```

```text
2024/04/29 09:26:55 server listening at [::]:50051
2024/04/29 09:29:46 Received: foo bar server
```

3. Clean up the Gateway and GRPCRoute resources:

```shell
kubectl delete -f hostname.yaml
```

### 3c. Configure headers based routing

1. Create the Gateway and GRPCRoute resources:

```shell
kubectl apply -f headers.yaml
```

2. Test the Application:

```shell
grpcurl -plaintext -proto grpc.proto -authority bar.com -d '{"name": "version one"}' -H 'version: one' ${GW_IP}:${GW_PORT} helloworld.Greeter/SayHello
```

```text
{
"message": "Hello version one"
}
```

To make sure this came from the correct server, we can check the application server logs:

```shell
kubectl logs ${POD_V1}
```

```text
<...>
2024/04/29 09:30:27 Received: version one
```

Now we'll send a request with the header `version: two`

```shell
grpcurl -plaintext -proto grpc.proto -authority bar.com -d '{"name": "version two"}' -H 'version: two' ${GW_IP}:${GW_PORT} helloworld.Greeter/SayHello
```

```text
{
"message": "Hello version two"
}
```

This time, we'll check the POD_V2 logs:

```shell
kubectl logs ${POD_V2}
```

```text
<...>
2024/04/29 09:32:46 Received: version two
```

Finally, we'll send a request with the headers `version: two` and `color: orange`

```shell
grpcurl -plaintext -proto grpc.proto -authority bar.com -d '{"name": "version two orange"}' -H 'version: two' -H 'color: orange' ${GW_IP}:${GW_PORT} helloworld.Greeter/SayHello
```

```text
{
"message": "Hello version two orange"
}
```

Now check the POD_V1 logs again:

```shell
kubectl logs ${POD_V1}
```

```text
<...>
2024/04/29 09:30:27 Received: version one
2024/04/29 09:33:26 Received: version two orange
```

3. Clean up the Gateway and GRPCRoute resources:

```shell
kubectl delete -f headers.yaml
```
29 changes: 29 additions & 0 deletions examples/grpc-routing/exact-method.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: same-namespace
spec:
gatewayClassName: nginx
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
metadata:
name: exact-matching
spec:
parentRefs:
- name: same-namespace
rules:
- matches:
- method:
service: helloworld.Greeter
method: SayHello
backendRefs:
- name: grpc-infra-backend-v1
port: 8080
38 changes: 38 additions & 0 deletions examples/grpc-routing/grpc.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

option go_package = "google.golang.org/grpc/examples/helloworld/helloworld";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";

package helloworld;

// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
string name = 1;
}

// The response message containing the greetings
message HelloReply {
string message = 1;
}
70 changes: 70 additions & 0 deletions examples/grpc-routing/headers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: same-namespace
spec:
gatewayClassName: nginx
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
metadata:
name: grpc-header-matching
spec:
parentRefs:
- name: same-namespace
rules:
# Matches "version: one"
- matches:
- headers:
- name: version
value: one
backendRefs:
- name: grpc-infra-backend-v1
port: 8080
# Matches "version: two"
- matches:
- headers:
- name: version
value: two
backendRefs:
- name: grpc-infra-backend-v2
port: 8080
# Matches "version: two" AND "color: orange"
- matches:
- headers:
- name: version
value: two
- name: color
value: orange
backendRefs:
- name: grpc-infra-backend-v1
port: 8080
# Matches "color: blue" OR "color: green"
- matches:
- headers:
- name: color
value: blue
- headers:
- name: color
value: green
backendRefs:
- name: grpc-infra-backend-v1
port: 8080
# Matches "color: red" OR "color: yellow"
- matches:
- headers:
- name: color
value: red
- headers:
- name: color
value: yellow
backendRefs:
- name: grpc-infra-backend-v2
port: 8080
Loading
Loading