Setting up TLS for Kubernetes Gateway API with Cilium and Cert-Manager

Easily secure your Kubernetes apps with TLS using this step-by-step guide. Configure the Gateway API, Cilium, and Cert-Manager for HTTPS access. Simple instructions and code examples make setup a breeze.

Setting up TLS for Kubernetes Gateway API with Cilium and Cert-Manager

This guide demonstrates how to configure Transport Layer Security (TLS) for a Kubernetes Gateway using the Gateway API, Cilium, and Cert-Manager. We'll leverage Cilium's Envoy proxy integration for efficient and secure routing. This setup enables HTTPS access to your applications, enhancing security and providing a robust infrastructure.

Prerequisites:

  • A Kubernetes cluster (we'll use kind for this example).
  • Cilium installed (version 1.16.5 or later recommended). Upgrade instructions are included below.
  • Cert-Manager configured to manage certificates. A self-signed issuer will be used for simplicity in this tutorial.
  • Gateway API CRDs installed.

1. Setting up the Cilium LoadBalancer IP Pool:

Cilium's LoadBalancer allows assigning IPs from a defined range. Create an IP pool using the following command:

cat << EOF | kubectl apply -f -
apiVersion: "cilium.io/v2alpha1"
kind: CiliumLoadBalancerIPPool
metadata:
  name: "test-pool"
spec:
  blocks:
  - start: "172.18.0.10"
    stop: "172.18.0.50"
EOF

2. Configuring a Self-Signed Certificate Issuer with Cert-Manager:

For this tutorial, we'll utilize a self-signed certificate. Create a ClusterIssuer for Cert-Manager:

cat << EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: selfsigned-cluster-issuer
  namespace: cert-manager
spec:
  selfSigned: {}
EOF

3. Installing and Configuring Cilium with Gateway API Support:

Ensure Gateway API CRDs are installed before installing/upgrading Cilium:

kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.0/config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml

Install or upgrade Cilium with Gateway API enabled:

cilium install --version 1.16.5 --set kubeProxyReplacement=true --set gatewayAPI.enabled=true
# Or for upgrade: cilium upgrade --version 1.16.5 --set kubeProxyReplacement=true --set gatewayAPI.enabled=true

Verify Cilium GatewayClass is installed:

kubectl get gatewayclass

4. Creating the TLS Certificate:

Generate a certificate using Cert-Manager:

cat << EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: grafana-tls
  namespace: kube-system
spec:
  dnsNames:
  - gfn.zozoo.io
  issuerRef:
    kind: ClusterIssuer
    name: selfsigned-cluster-issuer
  secretName: grafana-tls
EOF

Verify certificate creation:

kubectl get certificates -n kube-system

5. Deploying the Gateway:

Create a Gateway resource to handle HTTP and HTTPS traffic:

cat << EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: cilium-gateway
  namespace: kube-system
spec:
  gatewayClassName: cilium
  listeners:
  - allowedRoutes:
      namespaces:
        from: Selector
        selector:
          matchLabels:
            gw-access: "true"
    name: http
    port: 80
    protocol: HTTP
  - allowedRoutes:
      namespaces:
        from: Selector
        selector:
          matchLabels:
            gw-access: "true"
    name: https
    port: 443
    protocol: HTTPS
    tls:
      certificateRefs:
      - group: ""
        kind: Secret
        name: grafana-tls
      mode: Terminate
EOF

6. Configuring HTTPRoutes:

Create HTTPRoutes to define routing rules. This example shows routing to a Grafana service and a redirect from HTTP to HTTPS:

(a) Grafana HTTPRoute:

cat << EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: grafana
  namespace: monitoring
spec:
  hostnames:
  - gfn.zozoo.io
  parentRefs:
  - group: gateway.networking.k8s.io
    kind: Gateway
    name: cilium-gateway
    namespace: kube-system
    sectionName: https
  rules:
  - backendRefs:
    - group: ""
      kind: Service
      name: grafana
      port: 80
      weight: 1
    matches:
    - path:
        type: PathPrefix
        value: /
EOF

(b) HTTP to HTTPS Redirect:

cat << EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: http-filter-redirect
  namespace: monitoring
spec:
  parentRefs:
  - name: cilium-gateway
    sectionName: http
    namespace: kube-system
  hostnames:
  - gfn.zozoo.io
  rules:
  - filters:
    - type: RequestRedirect
      requestRedirect:
        scheme: https
        statusCode: 301
EOF

7. Testing:

Verify the setup by accessing gfn.zozoo.io (remember to update your /etc/hosts file accordingly). You should observe a redirect from HTTP to HTTPS, followed by successful access to your application.

This comprehensive guide provides a robust foundation for securing your Kubernetes applications with TLS using the Gateway API, Cilium, and Cert-Manager. Remember to replace placeholder values (e.g., gfn.zozoo.io, namespaces) with your actual details.