Documentation/network/servicemesh/gateway-api/grpc.rst
.. only:: not (epub or latex or html)
WARNING: You are looking at unreleased Cilium documentation.
Please use the official rendered version released here:
https://docs.cilium.io
.. _gs_gateway_grpc:
gRPC Example
This example demonstrates how to set up a Gateway that terminates TLS traffic and
routes requests to a gRPC service (i.e. using HTTP/2). In order for this example to
work, ALPN support needs to be enabled with the Helm flag gatewayAPI.enableAlpn
set to true. This enables clients to request HTTP/2 through the TLS negotiation.
.. literalinclude:: ../../../../examples/kubernetes/gateway/grpc-tls-termination.yaml :language: yaml
.. tabs::
.. group-tab:: Self-signed Certificate
This example uses a TLS certificate signed by a made-up, `self-signed <https://cert-manager.io/docs/faq/terminology/#what-does-self-signed-mean-is-my-ca-self-signed>`_
certificate authority (CA). One easy way to do this is with `mkcert <https://github.com/FiloSottile/mkcert>`_.
The certificate will validate the hostname ``grpc-echo.cilium.rocks`` used in this example.
.. code-block:: shell-session
$ mkcert bookinfo.cilium.rocks hispter.cilium.rocks
Created a new local CA 💥
Note: the local CA is not installed in the system trust store.
Run "mkcert -install" for certificates to be trusted automatically ⚠
Created a new certificate valid for the following names 📜
- "grpc-echo.cilium.rocks"
The certificate is at "./grpc-echo.cilium.rocks.pem" and the key at "./grpc-echo.cilium.rocks-key.pem" ✅
It will expire on 28 September 2027 🗓
Create a Kubernetes secret with this demo key and certificate:
.. code-block:: shell-session
$ kubectl create secret tls grpc-certificate --key=grpc-echo.cilium.rocks-key.pem --cert=grpc-echo.cilium.rocks.pem
.. group-tab:: cert-manager
Install cert-manager:
.. code-block:: shell-session
$ helm repo add jetstack https://charts.jetstack.io
$ helm install cert-manager jetstack/cert-manager --version v1.16.2 \
--namespace cert-manager \
--set crds.enabled=true \
--create-namespace \
--set config.apiVersion="controller.config.cert-manager.io/v1alpha1" \
--set config.kind="ControllerConfiguration" \
--set config.enableGatewayAPI=true
Now, create a CA Issuer:
.. parsed-literal::
$ kubectl apply -f \ |SCM_WEB|\/examples/kubernetes/servicemesh/ca-issuer.yaml
This sets up a simple gRPC echo server and a Gateway to expose it.
.. tabs::
.. group-tab:: Self-signed Certificate
.. parsed-literal::
$ kubectl apply -f \ |SCM_WEB|\/examples/kubernetes/gateway/grpc-tls-termination.yaml
The self-signed certificate Secrets from the previous step will be used by this Gateway.
.. group-tab:: cert-manager
.. parsed-literal::
$ kubectl apply -f \ |SCM_WEB|\/examples/kubernetes/gateway/grpc-tls-termination.yaml
To tell cert-manager that this Gateway needs a certificate, annotate the
Gateway with the name of the CA issuer you created previously:
.. code-block:: shell-session
$ kubectl annotate gateway tls-gateway cert-manager.io/issuer=ca-issuer
This creates a Certificate object along with a Secret containing the TLS
certificate.
.. code-block:: shell-session
$ kubectl get certificate,secret grpc-certificate
NAME READY SECRET AGE
certificate.cert-manager.io/grpc-certificate True grpc-certificate 83s
NAME TYPE DATA AGE
secret/grpc-certificate kubernetes.io/tls 3 78s
External IP address will be shown up in Gateway. Also, the host names should show up in related HTTPRoutes.
.. code-block:: shell-session
$ kubectl get gateway tls-gateway
NAME CLASS ADDRESS PROGRAMMED AGE
tls-gateway cilium 10.104.247.23 True 29s
$ kubectl get grpcroutes
NAME HOSTNAMES AGE
grpc-route 116s
Update /etc/hosts with the host names and IP address of the Gateway:
.. code-block:: shell-session
$ sudo perl -ni -e 'print if !/\.cilium\.rocks$/d' /etc/hosts; sudo tee -a /etc/hosts \
<<<"$(kubectl get gateway tls-gateway -o jsonpath='{.status.addresses[0].value}') grpc-echo.cilium.rocks"
You can use the grpcurl <https://github.com/fullstorydev/grpcurl>_ cli tool to verify
that the service works correctly. The echo server used in this example will respond
with information about the HTTP/2 request the client made.
.. tabs::
.. group-tab:: Self-signed Certificate
By specifying the CA's certificate on a curl request, you can say that you
trust certificates signed by that CA.
.. code-block:: shell-session
$ grpcurl -cacert ~/.local/share/mkcert/rootCA.pem grpc-echo.cilium.rocks:443 proto.EchoTestService/Echo
If you prefer, instead of supplying the CA you can specify ``-insecure`` to
tell the curl client not to validate the server's certificate. Without
either, you will get an error that the certificate was signed by an unknown
authority.
.. group-tab:: cert-manager
.. code-block:: shell-session
$ grpcurl grpc-echo.cilium.rocks:443 proto.EchoTestService/Echo
{
"message": "Host=grpc-echo.cilium.rocks:443\nRequestHeader=:authority:grpc-echo.cilium.rocks:443\nRequestHeader=content-type:application/grpc\nRequestHeader=grpc-accept-encoding:gzip\nRequestHeader=x-forwarded-proto:https\nRequestHeader=x-request-id:f7889cda-08b2-45cf-9329-833633ae8d9c\nRequestHeader=user-agent:grpcurl/dev-build (no version set) grpc-go/1.61.0\nRequestHeader=x-forwarded-for:172.22.0.7\nRequestHeader=x-envoy-internal:true\nStatusCode=200\nServiceVersion=\nServicePort=7070\nIP=10.244.1.101\nProto=GRPC\nEcho=\nHostname=grpc-echo-6879fc6969-2kh6r\n"
}