Skip to content

Ingress and Gateway objects

A Kubernetes Gateway controller is an API to manage external access to services in a cluster, generally HTTP but could also be TCP/UDP.

Gateway controllers generally manage things like load balancing, TLS termination, virtal host routing, etc.

You may see documentation referring to Kubernetes Ingress controllers. This is now a frozen API and effort is being put into it's replacement, Gateway API. Gateway API support is still being developed but for HTTP it's stable enough for use.

Ingress controller options

You've probably heard of some of the names behind popular ingress controllers, NGINX, HAProxy, Traefik. Cilium also has it's own Ingress and Gateway controllers, so why not just use those?

Installing the Cilium Gateway Controller

Back when we installed Cilium, our cluster CNI we passed the following option:

--set gatewayAPI.enabled=true

Create a Gateway object

For our example, we'll create a namespaced gateway for the whoami application below:

cat <<EOF | kubectl apply -f -
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: who-gateway
spec:
  gatewayClassName: cilium
  listeners:
  - protocol: HTTP
    port: 80
    name: http
    allowedRoutes:
      namespaces:
        from: Same
EOF

Create an example web service

First, let's create a small example whoami web service:

cat <<EOF | kubectl apply -f -
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: whoami
  labels:
    app: whoami

spec:
  replicas: 2
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
        - name: whoami
          image: traefik/whoami
          resources:
            requests:
              cpu: "10m"
              memory: "15Mi"
            limits:
              memory: "15Mi"
          ports:
            - name: web
              containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: who-svc
spec:
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  sessionAffinity: None
  type: LoadBalancer
  ports:
    - protocol: TCP
      name: http
      port: 80
  selector:
    app: whoami
EOF

Create some HTTPRoutes

Since we don't quite have DNS sorted out yet, let's use path-based request routing. Create the HTTPRoute config, routing requests to /whoami to our example web service.

cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: whoami-app-1
  namespace: who
spec:
  parentRefs:
  - name: my-gateway
    namespace: who
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /whoami
    backendRefs:
    - name: whoami
      port: 80
EOF

Test it out

Find the IP address of our gateway:

kubectl get gateways/who-gateway -o 'jsonpath={.status.addresses[0].value}'

If we now curl using the path /whoami and the IP address from the previous command we should see similar output to the following:

Hostname: whoami-6d9458855d-l29pw
IP: 127.0.0.1
IP: ::1
IP: 10.0.0.139
IP: fd00::a3
IP: fe80::38fc:5eff:fe89:2628
RemoteAddr: 10.0.0.61:52720
GET /whoami HTTP/1.1
Host: 192.168.239.100
User-Agent: curl/8.4.0
Accept: */*
X-Forwarded-For: 10.0.2.97
X-Forwarded-Host: 192.168.239.100
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Scheme: http
X-Real-Ip: 10.0.2.97
X-Request-Id: 2dafe4a4a5a9c5824e42ba7b83893696
X-Scheme: http

DNS, TLS, and next steps

This is a great start, but to be really useful you'll need to incorporate DNS, and TLS.

If you want to manually manage dns records, dnscontrol great. If you want to automatically generate records, and your provider has an API check out external-dns, a set of tools to create DNS entries based on ingress objects and annotations.

For TLS certificates likewise you can manually manage them or use a tool like cert-manager which operates very well with the Gateway API.