Before we install Cilium with Gateway API, we need to make sure we install the Gateway API CRDs prior to the Cilium install (Gateway API is a Custom Resource Definition (CRD) based API so you’ll need to install the CRDs onto a cluster to use the API):

kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v0.5.1/config/crd/standard/gateway.networking.k8s.io_gatewayclasses.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v0.5.1/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v0.5.1/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v0.5.1/config/crd/experimental/gateway.networking.k8s.io_referencegrants.yaml

You can check the CRDs have been installed with the following command:

root@server:~# kubectl get crd gatewayclasses.gateway.networking.k8s.io
kubectl get crd gateways.gateway.networking.k8s.io
kubectl get crd httproutes.gateway.networking.k8s.io
kubectl get crd referencegrants.gateway.networking.k8s.io
NAME                                       CREATED AT
gatewayclasses.gateway.networking.k8s.io   2023-03-09T13:39:22Z
NAME                                 CREATED AT
gateways.gateway.networking.k8s.io   2023-03-09T13:39:22Z
NAME                                   CREATED AT
httproutes.gateway.networking.k8s.io   2023-03-09T13:39:23Z
NAME                                        CREATED AT
referencegrants.gateway.networking.k8s.io   2023-03-09T13:39:23Z

Let’s double check it was successfully set up:

root@server:~# cilium config view | grep "enable-gateway-api"
enable-gateway-api                             true
enable-gateway-api-secrets-sync                true

What is a GatewayClass and a Gateway?

Before we actually start routing traffic into the cluster, we should explain what these CRDs were and why they were required.

If the CRDs have been deployed beforehand, a GatewayClass will be deployed by Cilium during its installation (assuming the Gateway API option has been selected).

Let’s verify that a GatewayClass has been deployed and accepted:

root@server:~# kubectl get gatewayclasses.gateway.networking.k8s.io 
NAME     CONTROLLER                     ACCEPTED   AGE
cilium   io.cilium/gateway-controller   True       13m

The GatewayClass is a type of Gateway that can be deployed: in other words, it is a template. This is done in a way to let infrastructure providers offer different types of Gateways. Users can then choose the Gateway they like.

For instance, an infrastructure provider may create two GatewayClasses named internet and private for two different purposes and possibly with different features: one to proxy Internet-facing services and one for private internal applications.

In our case, we will instantiate Cilium Gateway API (io.cilium/gateway-controller).

HTTP Routing

Let’s now deploy an application and set up GatewayAPI HTTPRoutes to route HTTP traffic into the cluster. We will use bookinfo as a sample application.

This demo set of microservices provided by the Istio project consists of several deployments and services:

  • 🔍 details
  • ⭐ ratings
  • ✍ reviews
  • 📕 productpage

We will use several of these services as bases for our Gateway APIs.

img

Deploy an application

Let’s deploy the sample application in the cluster.

root@server:~#  kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.12/samples/bookinfo/platform/kube/bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created

Check that the application is properly deployed:

root@server:~# kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
details-v1-586577784f-nr5t2       1/1     Running   0          61s
productpage-v1-589b848cc9-prrnh   1/1     Running   0          61s
ratings-v1-679fc7b4f-g48xz        1/1     Running   0          61s
reviews-v1-7b76665ff9-6g7fq       1/1     Running   0          61s
reviews-v2-6b86c676d9-v65k9       1/1     Running   0          61s
reviews-v3-b77c579-pqmgl          1/1     Running   0          61s

You should see multiple pods being deployed in the default namespace.

Notice that with Cilium Service Mesh, there is no Envoy sidecar created alongside each of the demo app microservices. With a sidecar implementation, the output would show 2/2 READY: one for the microservice and one for the Envoy sidecar.

Have a quick look at the Services deployed:

root@server:~# kubectl get svc
NAME          TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
details       ClusterIP   10.96.41.65    <none>        9080/TCP   2m3s
kubernetes    ClusterIP   10.96.0.1      <none>        443/TCP    11m
productpage   ClusterIP   10.96.147.97   <none>        9080/TCP   2m3s
ratings       ClusterIP   10.96.105.89   <none>        9080/TCP   2m3s
reviews       ClusterIP   10.96.149.14   <none>        9080/TCP   2m3s

Note these Services are only internal-facing (ClusterIP) and therefore there is no access from outside the cluster to these Services.