# Use Gateway API on SKS

The [Gateway API](https://gateway-api.sigs.k8s.io/) is the successor to Kubernetes Ingress, providing a more expressive, extensible, and role-oriented approach to managing traffic routing. It introduces resources like `Gateway` and `HTTPRoute` that offer finer control over how traffic enters and flows through your cluster.

## Key Benefits

- **Role-oriented**: Separates concerns between infrastructure providers, cluster operators, and application developers
- **Expressive**: Native support for header-based routing, traffic splitting, and request manipulation
- **Extensible**: Custom resources can extend functionality without modifying core APIs
- **Portable**: Standard API works across multiple implementations (Traefik, Cilium, Envoy, Istio, Kong, and more)

## Prerequisites

- An Exoscale SKS cluster with kubectl access
- [Helm](https://helm.sh/docs/intro/install/) installed
- Basic Kubernetes knowledge

If you don't have access to an SKS cluster, follow the [Quick Start Guide]({{< ref "/product/compute/containers/quick-start/">}}).

## Install Gateway API CRDs

First, install the Gateway API Custom Resource Definitions (CRDs):

```bash
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yaml
```

> [!NOTE]
> Check the [Gateway API releases](https://github.com/kubernetes-sigs/gateway-api/releases) for the latest version.

## Install Traefik with Gateway API Provider

Add the Traefik Helm repository and install Traefik with the Gateway API provider enabled:

```bash
helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik -n traefik --create-namespace \
  --skip-crds \
  --set providers.kubernetesGateway.enabled=true \
  --set providers.kubernetesCRD.enabled=false \
  --set providers.kubernetesIngress.enabled=false
```

> [!NOTE]
> The `--skip-crds` flag prevents the Helm chart from reinstalling Gateway API CRDs that were
> already applied in the previous step. The Traefik Helm chart bundles Gateway API CRDs and would
> otherwise conflict with the manually installed ones.
>
> This configuration enables Gateway API support while disabling traditional Ingress.
> If you need both Gateway API and Ingress support, omit the `kubernetesCRD` and
> `kubernetesIngress` flags, or set them to `true`.

This installation creates a `LoadBalancer` service, which automatically provisions an Exoscale Network Load Balancer through the CCM.

Verify the installation:

```bash
kubectl get pods -n traefik -l app.kubernetes.io/name=traefik
kubectl get svc -n traefik traefik
```

> [!NOTE]
> The commands above assume Traefik is installed in the `traefik` namespace, as shown in the Helm command.

## How Traffic Flows on Exoscale

When you create the Traefik Service of type `LoadBalancer`, Exoscale provisions a Network Load Balancer (NLB) through the CCM. Traffic then follows this path:

- Client -> Exoscale NLB (Service `LoadBalancer`)
- NLB -> NodePort on cluster nodes
- NodePort -> Traefik pod
- Traefik -> `Gateway` -> `HTTPRoute` -> Service -> Pods

This is why you must allow NodePort traffic in the node security group.

## Configure Security Group for NodePort Traffic

The Network Load Balancer routes traffic to NodePorts on your cluster nodes. You need to allow this traffic through a security group.

Create a security group and add a rule for the NodePort range:

```bash
exo compute security-group create traefik-nodeports

exo compute security-group rule add traefik-nodeports \
  --protocol tcp \
  --port 30000-32767 \
  --network 0.0.0.0/0
```

Attach the security group to your nodepool. You can do this via the Portal or CLI:

```bash
exo compute sks nodepool update <cluster-name> <nodepool-name> \
  --security-group traefik-nodeports \
  --security-group <existing-security-group>
```

> [!IMPORTANT]
> The `--security-group` flag replaces all security groups on the nodepool. Make sure to include any existing security groups in the command to avoid removing them.


## Create Gateway API Resources

Gateway API separates concerns across different roles:

- **`GatewayClass`**: Defined by the infrastructure provider (e.g., Traefik). Typically set up once per cluster.
- **`Gateway`**: Managed by platform or cluster operators. Defines entry points, ports, and TLS configuration.
- **`HTTPRoute`**: Owned by application developers. Defines routing rules and can be bundled alongside applications in Helm charts.

### GatewayClass

The `GatewayClass` defines which controller handles Gateways. Create a file named `gatewayclass.yaml`:

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

Apply it:

```bash
kubectl apply -f gatewayclass.yaml
```

### Gateway

The `Gateway` resource defines the entry point for traffic. Create a file named `gateway.yaml`:

```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: traefik-gateway
spec:
  gatewayClassName: traefik
  listeners:
    - name: http
      protocol: HTTP
      port: 8000
```

> [!NOTE]
> Traefik uses port 8000 for its `web` entryPoint by default. The external LoadBalancer maps port 80 to this internal port, so the Gateway listener must match the Traefik entryPoint port (8000 unless you override Helm values). If you set `ports.web.port=80`, update the Gateway listener to `port: 80`.

Apply it:

```bash
kubectl apply -f gateway.yaml
```

### Example Application

Deploy a simple application to test the setup. Create a file named `app.yaml`:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello
  labels:
    app: hello
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello
  template:
    metadata:
      labels:
        app: hello
    spec:
      containers:
        - name: hello
          image: nginxdemos/hello:plain-text
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: hello
spec:
  selector:
    app: hello
  ports:
    - port: 80
      targetPort: 80
```

Apply it:

```bash
kubectl apply -f app.yaml
```

### HTTPRoute

The `HTTPRoute` defines how traffic is routed to your services. It only becomes active when it is attached to a `Gateway` via `parentRefs`. Create a file named `httproute.yaml`:

```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: hello-route
spec:
  parentRefs:
    - name: traefik-gateway
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: hello
          port: 80
```

Apply it:

```bash
kubectl apply -f httproute.yaml
```

## Verify the Setup

Check that the Gateway is ready:

```bash
kubectl get gateway traefik-gateway
```

Get the external IP of the LoadBalancer:

```bash
kubectl get svc -n traefik traefik -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
```

Test the route:

```bash
curl http://<EXTERNAL-IP>/
```

You should see the nginx hello response.

## Gateway API vs Ingress

Gateway API is a good fit when you need advanced routing, multi-team ownership boundaries, or a consistent policy model across teams and clusters. Ingress remains a good choice for simple routing and legacy setups.

> [!NOTE]
> Gateway API is still evolving, and feature support varies by controller. Always check your controller's Gateway API support matrix.

> [!TIP]
> You can run Ingress and Gateway API side by side in Traefik by enabling both providers. This can help with gradual migration, but increases operational complexity.

> [!IMPORTANT]
> Gateway API does not natively support Traefik's `TLSOption` CRD. If you need to customize TLS settings (such as minimum TLS version, cipher suites, or mTLS policies), use Ingress with `IngressRoute` instead, where `TLSOption` references work as expected.

| Feature | Ingress | Gateway API |
|---------|---------|-------------|
| Role separation | Single resource | GatewayClass, Gateway, HTTPRoute |
| Header routing | Annotation-dependent | Native support |
| Traffic splitting | Not supported | Native support |
| Request/response manipulation | Controller-specific | Standardized filters |
| Multi-tenancy | Limited | Built-in support |
| Extensibility | Annotations | Custom resources |

**When to use Ingress**: Simple routing needs, existing configurations, controller-specific features.

**When to use Gateway API**: Complex routing, multi-team environments, portability requirements, new deployments.

## Cleanup

When deleting resources, follow this order to avoid orphaned cloud resources:

> [!CAUTION]
> Always delete the LoadBalancer service before deleting the nodepool or cluster. Otherwise, the NLB may not be automatically cleaned up.

```bash
# Delete Gateway API resources
kubectl delete httproute hello-route
kubectl delete gateway traefik-gateway
kubectl delete gatewayclass traefik

# Delete the application
kubectl delete -f app.yaml

# Uninstall Traefik (this deletes the LoadBalancer service)
helm uninstall traefik

# Delete Gateway API CRDs
kubectl delete -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yaml

# Remove security group (after cluster deletion)
exo compute security-group delete traefik-nodeports
```

## Other Gateway API Controllers

While this guide uses Traefik, the Gateway API is supported by many controllers:

- **[Cilium Gateway API](https://docs.cilium.io/en/stable/network/servicemesh/gateway-api/gateway-api/)**: eBPF-based networking with Gateway API support
- **[Envoy Gateway](https://gateway.envoyproxy.io/)**: Managed Envoy proxy for Kubernetes
- **[Istio](https://istio.io/latest/docs/tasks/traffic-management/ingress/gateway-api/)**: Service mesh with Gateway API integration
- **[Kong](https://docs.konghq.com/kubernetes-ingress-controller/latest/concepts/gateway-api/)**: API gateway with Gateway API support

The concepts in this guide apply to other controllers with minor configuration differences.

## See Also

* For traditional load balancing and ingress, see [SKS Load Balancer and Ingress Controller]({{< ref "/product/compute/containers/how-to/loadbalancer-ingress/" >}})
* [Official Gateway API documentation](https://gateway-api.sigs.k8s.io/)
* [Traefik Gateway API documentation](https://doc.traefik.io/traefik/providers/kubernetes-gateway/)
* [Gateway API implementations](https://gateway-api.sigs.k8s.io/implementations/)
* For details on SKS service levels and shared responsibility, see [SKS Overview]({{< ref "/product/compute/containers/overview/" >}})

