Cart

    Sorry, we could not find any results for your search querry.

    Configuring a Kubernetes Gateway

    In a Kubernetes cluster, you can route HTTP and HTTPS traffic using the Kubernetes Gateway API. A Gateway replaces the traditional Ingress Controller and gives you a central place for SSL (TLS) termination, routing rules and security.

    In this guide, you’ll configure a Kubernetes Gateway step by step for a simple demo application. First you deploy an app and Service, then you configure a Gateway and HTTPRoute and add SSL security with a TLS certificate (for example via Cert-manager and Let’s Encrypt). At the end, you’ll test whether HTTPS works correctly.

    For this guide you’ll need:

    • A Kubernetes cluster.
    • A Gateway controller such as Traefik or Cilium. For example, follow our Traefik guide first.
    • Cert-manager: the Gateway API’s HTTPS listeners only support Kubernetes Secrets (not .json); Cert-manager uses Secrets, Traefik uses .json. For this reason, you’ll need Cert-manager in this setup to generate SSL certificates.
    • Kubectl
    • A domain name whose DNS points to the gateway (Traefik or Cilium).
     

     

    What is a Kubernetes Gateway?

     

    The Kubernetes Gateway API introduces new resource types, such as GatewayClass, Gateway and HTTPRoute. These resources describe how traffic flows from outside into your cluster and which Services are allowed to receive that traffic. Unlike a classic Ingress, the Gateway API clearly separates the role of infrastructure management (GatewayClass/Gateway) and application routing (HTTPRoute).

    Broadly speaking, a Gateway setup looks like this:

    • A GatewayClass describes which type of gateway controller you use (for example Traefik, NGINX or Cilium).
    • A Gateway defines one or more listeners (for example HTTP on port 8000 and HTTPS on port 8443) with (sub)domains (hostnames) and TLS settings.
    • An HTTPRoute maps (sub)domains and paths to Services in a namespace.

    In this tutorial, you’ll create your own Gateway in a separate namespace, configure an HTTPRoute and add SSL termination to the Gateway. This means you don’t have to manage TLS certificates per app, but centrally on the Gateway.


     

    Deploying a demo application behind the Gateway

     

    TL;DR: the quickest copy-and-paste

    Create a file, for example gateway-demo.yaml, with the contents below. 

    • At the very least, replace demo.voorbeeld.nl with your own domain and, if you wish, the namespace name as well:
    apiVersion: v1
    kind: Namespace
    metadata:
      name: demo-gateway
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: demo-app
      namespace: demo-gateway
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: demo-app
      template:
        metadata:
          labels:
            app: demo-app
        spec:
          containers:
          - name: demo-app
            image: traefik/whoami
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: demo-app
      namespace: demo-gateway
    spec:
      selector:
        app: demo-app
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
    ---
    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: demo-gateway
      namespace: demo-gateway
    spec:
      gatewayClassName: traefik
      listeners:
      - name: web
        protocol: HTTP
        port: 8000
        hostname: demo.voorbeeld.nl
        allowedRoutes:
          namespaces:
            from: Same
      - name: websecure
        protocol: HTTPS
        port: 8443
        hostname: demo.voorbeeld.nl
        tls:
          mode: Terminate
          certificateRefs:
          - kind: Secret
            name: demo-gateway-tls
        allowedRoutes:
          namespaces:
            from: Same
    ---
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: demo-route-redirect
      namespace: demo-gateway
    spec:
      parentRefs:
      - name: demo-gateway
        sectionName: web
      hostnames:
      - demo.voorbeeld.nl
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /
        filters:
        - type: RequestRedirect
          requestRedirect:
            scheme: https
            statusCode: 301
    ---
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: demo-route
      namespace: demo-gateway
    spec:
      parentRefs:
      - name: demo-gateway
        sectionName: websecure
      hostnames:
      - demo.voorbeeld.nl
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /
        backendRefs:
        - name: demo-app
          port: 80
    

    Next, create a namespace for your gateway and apply the .yaml file:

    kubectl create namespace demo-gateway
    kubectl apply -f gateway-demo.yaml
     
     

    You’ll need an application behind the Gateway to test your configuration. In this example, you’ll use a simple HTTP ‘whoami’ service on port 80 with a Deployment and Service. The app runs as a container in the cluster; for more background, read our explanation of what a container image is.


     

    Step 1

    Create a separate namespace for the demo app and the Gateway resources:

    kubectl create namespace demo-gateway

    The demo-gateway namespace helps to logically separate the demo resources from the rest of your cluster.


     

    Step 2

    Create the file demo-app.yaml on your computer/laptop with the following contents:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: demo-gateway
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: demo-app
      namespace: demo-gateway
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: demo-app
      template:
        metadata:
          labels:
            app: demo-app
        spec:
          containers:
          - name: demo-app
            image: traefik/whoami
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: demo-app
      namespace: demo-gateway
    spec:
      selector:
        app: demo-app
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP

    The Deployment starts two replicas of the traefik/whoami container (a small HTTP service that returns request information) and the Service makes these pods reachable on port 80 within the namespace.


     

    Step 3

    Deploy the demo application:

    kubectl apply -f demo-app.yaml

    Then check that the pods are running:

    kubectl get pods -n demo-gateway

    Once the pods are in the Running state, your backend is ready to be exposed via the Gateway.


     

    Step 4

    Now that the backend is running, first configure a GatewayClass (often already present). In this example, we’ll assume a Gateway controller such as Traefik that supports the Gateway API.

    Check whether (and which) GatewayClasses are already present in your cluster:

    kubectl get gatewayclass

    If your provider or gateway controller has already created a GatewayClass (for example traefik), use that name in your Gateway and continue to step 5

    Don’t see a GatewayClass yet? Then add one yourself. For example, if you want to define a GatewayClass for Traefik, create a file gatewayclass.yaml with the following contents:

    apiVersion: gateway.networking.k8s.io/v1
    kind: GatewayClass
    metadata:
      name: traefik
    spec:
      controllerName: traefik.io/gateway-controller

    Adjust the name if your controller expects a different GatewayClass (you can find this in the documentation for the GatewayClass you’re using). The controllerName value identifies which controller manages Gateways of this type; in this example, that’s the Traefik Gateway controller.

    kubectl apply -f gatewayclass.yaml

    With this step, you link the Gateway API to your chosen gateway controller.


     

    Step 5

    Create a .yaml file with the definition of the actual Gateway for HTTP and HTTPS traffic, for example demo-gateway-listener.yaml, with the contents below.

    Use your own domain instead of demo.voorbeeld.nl, the correct namespace (here demo-gateway) and the GatewayClass name (traefik in the example):

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: demo-gateway
      namespace: demo-gateway
    spec:
      gatewayClassName: traefik
      listeners:
      - name: web
        protocol: HTTP
        port: 8000
        hostname: demo.voorbeeld.nl
        allowedRoutes:
          namespaces:
            from: Same
      - name: websecure
        protocol: HTTPS
        port: 8443
        hostname: demo.voorbeeld.nl
        tls:
          mode: Terminate
          certificateRefs:
          - kind: Secret
            name: demo-gateway-tls
        allowedRoutes:
          namespaces:
            from: Same

     

    Step 6

    Deploy the Gateway:

    kubectl apply -f demo-gateway-listener.yaml

    This Gateway listens on port 8000 for HTTP traffic to demo.voorbeeld.nl and on port 8443 for HTTPS traffic. The allowedRoutes.namespaces.from: Same setting restricts routes to the same namespace as the Gateway (demo-gateway), which is safer in multi-tenant environments.


     

    Step 7

    Create an HTTPRoute that maps the (sub)domain/hostname and the path to the demo Service. For example, create the file httproute.yaml with the following contents:

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: demo-route
      namespace: demo-gateway
    spec:
      parentRefs:
      - name: demo-gateway
        sectionName: websecure
      hostnames:
      - demo.voorbeeld.nl
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /
        backendRefs:
        - name: demo-app
          port: 80

    The parentRefs link the route to the demo-gateway Gateway. All paths under / are sent to the demo-app Service on port 80.


     

    Step 8

    Apply the HTTPRoute to your Kubernetes cluster:

    kubectl apply -f httproute.yaml

    Then check whether the Gateway and HTTPRoute are ‘Ready’:

    kubectl get gateway -n demo-gateway
    kubectl get httproute -n demo-gateway

    Use kubectl describe for more details if the status is not ‘Programmed’ or ‘Accepted’. Any messages in the conditions provide a clue as to what’s wrong (for example, an unknown GatewayClass or (sub)domain/hostname).


     

    Step 9

    Now that HTTP works, add SSL security. In Kubernetes, that usually means TLS termination on the Gateway (via the ClusterIssuer created with Cert-manager): the Gateway presents the certificate to the client and forwards the traffic as unencrypted HTTP to the backend. The certificate is stored in a Secret in the same namespace as the Gateway.

    Create a Certificate resource so that Cert-manager automatically requests a certificate for your domain. Use the name of your (Cluster)Issuer, for example letsencrypt-issuer. Create the file certificate.yaml with the following contents:

    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: demo-cert
      namespace: demo-gateway
    spec:
      secretName: demo-gateway-tls
      issuerRef:
        name: letsencrypt-issuer
        kind: ClusterIssuer
      dnsNames:
      - demo.voorbeeld.nl

    The dnsNames and secretName fields must match your (sub)domain/hostname and the name you’ll use in the Gateway in a moment. Cert-manager stores the issued certificate and the private key in the demo-gateway-tls Secret.


     

    Step 10

    Apply the certificate.yaml you just created to your Kubernetes cluster:

    kubectl apply -f certificate.yaml

    To be safe, check that the certificate has been created successfully:

    kubectl describe certificate demo-cert -n demo-gateway

    Pay attention to the conditions; if the status is Ready and there are no DNS or HTTP challenge errors, the Secret containing the certificate is available. With -n demo-gateway you specify which namespace the Certificate is in.


     

    Step 11

    Finally, test whether HTTPS works using, for example, a curl command, or navigate to the (sub)domain in your browser:

    curl -v https://demo.voorbeeld.nl

    You should see a TLS handshake followed by the output from the whoami service. If your browser no longer shows warnings about an unsafe certificate, your SSL security is configured correctly.


     

    Troubleshooting: common mistakes

     

    Still not able to reach your application via HTTPS? The checks below will help you resolve the most common issues.


     

    Step 1

    Verify that the backend Service and pods are working:

    kubectl get svc -n demo-gateway
    kubectl get pods -n demo-gateway
    kubectl logs -l app=demo-app -n demo-gateway

    If the pods are crashing or not receiving traffic, fix that first before looking further at the Gateway configuration.


     

    Step 2

    Check DNS and reachability:

    nslookup demo.voorbeeld.nl
    ping demo.voorbeeld.nl

    If the (sub)domain/hostname does not point to the correct IP address or returns an error, check your domain’s DNS settings and your nameservers.


     

    Step 3

    Check the status of the Gateway and HTTPRoute:

    kubectl describe gateway demo-gateway -n demo-gateway
    kubectl describe httproute demo-route -n demo-gateway

    Look for conditions such as Programmed and Accepted and any error messages (for example, an unknown GatewayClass, an incorrect (sub)domain/hostname or a missing listener). These fields usually indicate straight away where the configuration is conflicting.


     

    Step 4

    Check that the TLS certificate and the Secret exist and are ‘Ready’:

    kubectl get certificate -n demo-gateway
    kubectl get secret demo-gateway-tls -n demo-gateway

    If the Secret is missing or the certificate is not Ready, view Cert-manager’s events with kubectl describe certificate and resolve any HTTP or DNS challenge issues (for example, incorrect DNS records or firewall rules).


     

    In this guide, you set up a Kubernetes Gateway for a demo application, configured HTTP and HTTPS listeners, linked a TLS certificate via Cert-manager and added an HTTP->HTTPS redirect. With this approach, you centralise your SSL security, make routing rules easier to manage, and you’re ready to use more advanced Kubernetes Gateway API features, such as multiple hostnames, per-environment paths and additional security filters.

    Need help?

    Receive personal support from our supporters

    Contact us