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