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