github.com/projectcontour/contour@v1.28.2/site/content/guides/grpc.md (about) 1 --- 2 title: Configuring ingress to gRPC services with Contour 3 layout: page 4 --- 5 6 ## Example gRPC Service 7 8 The below examples use the [gRPC server][1] used in Contour end to end tests. 9 The server implements a service `yages.Echo` with two methods `Ping` and `Reverse`. 10 It also implements the [gRPC health checking service][2] (see [here][3] for more details) and is bundled with the [gRPC health probe][4]. 11 12 An example base deployment and service for a gRPC server utilizing plaintext HTTP/2 are provided here: 13 14 ```yaml 15 --- 16 apiVersion: apps/v1 17 kind: Deployment 18 metadata: 19 labels: 20 app.kubernetes.io/name: grpc-echo 21 name: grpc-echo 22 spec: 23 replicas: 2 24 selector: 25 matchLabels: 26 app.kubernetes.io/name: grpc-echo 27 template: 28 metadata: 29 labels: 30 app.kubernetes.io/name: grpc-echo 31 spec: 32 containers: 33 - name: grpc-echo 34 image: ghcr.io/projectcontour/yages:v0.1.0 35 ports: 36 - name: grpc 37 containerPort: 9000 38 readinessProbe: 39 exec: 40 command: ["/grpc-health-probe", "-addr=localhost:9000"] 41 --- 42 apiVersion: v1 43 kind: Service 44 metadata: 45 labels: 46 app.kubernetes.io/name: grpc-echo 47 name: grpc-echo 48 spec: 49 selector: 50 app.kubernetes.io/name: grpc-echo 51 ports: 52 - port: 9000 53 protocol: TCP 54 targetPort: grpc 55 ``` 56 57 ## HTTPProxy Configuration 58 59 Configuring proxying to a gRPC service with HTTPProxy is as simple as specifying the protocol Envoy uses with the upstream application via the `spec.routes[].services[].protocol` field. 60 For example, in the resource below, for proxying plaintext gRPC to the `yages` sample app, the protocol is set to `h2c` to denote HTTP/2 over cleartext. 61 For TLS secured gRPC, the protocol used would be `h2`. 62 63 Route path prefix matching can be used to match a specific gRPC message if required. 64 65 ```yaml 66 --- 67 apiVersion: projectcontour.io/v1 68 kind: HTTPProxy 69 metadata: 70 name: my-grpc-service 71 spec: 72 virtualhost: 73 fqdn: my-grpc-service.foo.com 74 routes: 75 - conditions: 76 - prefix: /yages.Echo/Ping # Matches a specific gRPC method. 77 services: 78 - name: grpc-echo 79 port: 9000 80 protocol: h2c 81 - conditions: 82 - prefix: / # Matches everything else. 83 services: 84 - name: grpc-echo 85 port: 9000 86 protocol: h2c 87 ``` 88 89 Using the sample deployment above along with this HTTPProxy example, you can test calling this plaintext gRPC server with the following [grpccurl][5] command: 90 91 ``` 92 grpcurl -plaintext -authority=my-grpc-service.foo.com <load balancer IP and port if needed> yages.Echo/Ping 93 ``` 94 95 If implementing a streaming RPC, it is likely you will need to adjust per-route timeouts to ensure streams are kept alive for the appropriate durations needed. 96 Relevant timeout fields to adjust include the HTTPProxy `spec.routes[].timeoutPolicy.response` field which defaults to 15s and should be increased as well as the global timeout policy configurations in the Contour configuration file `timeouts.request-timeout` and `timeouts.max-connection-duration`. 97 98 ## Ingress v1 Configuration 99 100 To configure routing for gRPC requests with Ingress v1, you must add an annotation on the upstream Service resource as below. 101 102 ```yaml 103 --- 104 apiVersion: v1 105 kind: Service 106 metadata: 107 labels: 108 app.kubernetes.io/name: grpc-echo 109 annotations: 110 projectcontour.io/upstream-protocol.h2c: "9000" 111 name: grpc-echo 112 spec: 113 selector: 114 app.kubernetes.io/name: grpc-echo 115 ports: 116 - port: 9000 117 protocol: TCP 118 targetPort: grpc 119 ``` 120 121 The annotation key must follow the form `projectcontour.io/upstream-protocol.{protocol}` where `{protocol}` is `h2c` for plaintext gRPC or `h2` for TLS encrypted gRPC to the upstream application. 122 The annotation value contains a comma-separated list of port names and/or numbers that must match with the ones defined in the Service definition. 123 124 Using the Service above with the Ingress resource below should achieve the same configuration as with an HTTPProxy. 125 126 ```yaml 127 --- 128 apiVersion: networking.k8s.io/v1 129 kind: Ingress 130 metadata: 131 name: my-grpc-service 132 spec: 133 rules: 134 - host: my-grpc-service.foo.com 135 http: 136 paths: 137 - path: / 138 backend: 139 service: 140 name: grpc-echo 141 port: 142 number: 9000 143 pathType: Prefix 144 ``` 145 146 ## Gateway API Configuration 147 148 At the moment, configuring gRPC routes with Gateway API resources is achieved by the same method as with Ingress v1: annotation to select a protocol and port on a Service referenced by HTTPRoute `spec.rules[].backendRefs`. 149 150 Gateway API does include a specific resource [GRPCRoute][6] for routing gRPC requests. 151 This may be supported in future versions of Contour. 152 153 ## gRPC-Web 154 155 Contour configures Envoy to automatically convert [gRPC-Web][7] HTTP/1 requests to gRPC over HTTP/2 RPC calls to an upstream service. 156 This is a convenience addition to make usage of gRPC web application client libraries and the like easier. 157 158 Note that you still must provide configuration of the upstream protocol to have gRPC-Web requests converted to gRPC to the upstream app. 159 If your upstream application does not in fact support gRPC, you may get a protocol error. 160 In that case, please see [this issue][8]. 161 162 For example, with the example deployment and routing configuration provided above, an example HTTP/1.1 request and response via `curl` looks like: 163 164 ``` 165 curl \ 166 -s -v \ 167 <load balancer IP and port if needed>/yages.Echo/Ping \ 168 -XPOST \ 169 -H 'Host: my-grpc-service.foo.com' \ 170 -H 'Content-Type: application/grpc-web-text' \ 171 -H 'Accept: application/grpc-web-text' \ 172 -d'AAAAAAA=' 173 ``` 174 175 This `curl` command sends and receives gRPC messages as base 64 encoded text over HTTP/1.1. 176 Piping the output to `base64 -d | od -c` we can see the raw text gRPC response: 177 178 ``` 179 0000000 \0 \0 \0 \0 006 \n 004 p o n g 200 \0 \0 \0 036 180 0000020 g r p c - s t a t u s : 0 \r \n g 181 0000040 r p c - m e s s a g e : \r \n 182 0000056 183 ``` 184 185 [1]: https://github.com/projectcontour/yages 186 [2]: https://pkg.go.dev/google.golang.org/grpc/health/grpc_health_v1 187 [3]: https://github.com/grpc/grpc/blob/master/doc/health-checking.md 188 [4]: https://github.com/grpc-ecosystem/grpc-health-probe 189 [5]: https://github.com/fullstorydev/grpcurl 190 [6]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRoute 191 [7]: https://github.com/grpc/grpc-web 192 [8]: https://github.com/projectcontour/contour/issues/4290