github.com/projectcontour/contour@v1.28.2/site/content/docs/1.23/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