drunk.charts

drunk-k8s-gateway

Kubernetes Gateway API CRDs and cluster-level Gateway resources for drunk.charts

Overview

The drunk-k8s-gateway chart automates the installation and configuration of:

This chart reuses drunk-lib to maintain consistency across the drunk.charts ecosystem.

Features

Prerequisites

Installation

Quick Start

# Install CRDs first
./scripts/install-crds.sh

# Install the chart with default settings
helm install gateway drunk-charts/drunk-k8s-gateway

# Or install from local directory
helm install gateway . -n gateway-system --create-namespace

Step-by-Step Installation

1. Build the Chart (For Local Development)

If you’re working with the chart locally, build it first to download Gateway API CRDs:

# Build the chart (downloads Gateway API CRDs automatically)
./build.sh

# This will:
# - Download Gateway API CRDs to templates/gateway-api-crds.yaml
# - Update chart dependencies
# - Package the chart

Note: Pre-built charts from the Helm repository already include the CRDs.

2. Install Gateway API CRDs

The Gateway API CRDs are now included in the chart and will be installed automatically.

Option A: Install with Helm (Recommended)

# CRDs are included in the chart
helm install gateway drunk-charts/drunk-k8s-gateway \
  -n gateway-system \
  --create-namespace

Option B: Install CRDs separately (if needed)

If you prefer to install CRDs separately or need to update them independently:

# Using the provided script
cd scripts
chmod +x install-crds.sh
./install-crds.sh

# Or manually with kubectl
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml

# For experimental features (GRPC, TCP, TLS, UDP routes)
./install-crds.sh --channel experimental

Verify installation:

kubectl get crd | grep gateway

Expected output:

gatewayclasses.gateway.networking.k8s.io
gateways.gateway.networking.k8s.io
httproutes.gateway.networking.k8s.io
referencegrants.gateway.networking.k8s.io

3. Install Gateway Controller

Choose and install a Gateway controller implementation. This chart vendors the official Traefik Helm chart for lightweight, K3s-friendly Gateway API support.

This chart vendors the official traefik Helm chart (version 33.2.0) with Kubernetes Gateway API support enabled. This is the lightest-weight option and perfect for K3s, kind, or minikube.

Minimal values enabling Traefik (disables duplicate parent GatewayClass):

gatewayClass:
  enabled: false # Let Traefik create the GatewayClass

traefik:
  enabled: true
  experimental:
    kubernetesGateway:
      enabled: true
  providers:
    kubernetesGateway:
      enabled: true
  service:
    type: NodePort # For kind/minikube/k3s; use LoadBalancer in cloud
  ports:
    web:
      nodePort: 31437
    websecure:
      nodePort: 31438

Install with the above saved as values-traefik.yaml:

helm upgrade --install gateway ./drunk-k8s-gateway \
  -n drunk-gateway --create-namespace \
  -f values-traefik.yaml

You can override any upstream chart setting under the traefik: key. For example to set resources:

helm upgrade --install gateway ./drunk-k8s-gateway \
  -n drunk-gateway --create-namespace \
  --set gatewayClass.enabled=false \
  --set traefik.enabled=true \
  --set traefik.resources.requests.memory=100Mi

Option B: Install Traefik Separately

If you prefer independent lifecycle management:

helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik \
  --namespace traefik --create-namespace \
  --set experimental.kubernetesGateway.enabled=true \
  --set providers.kubernetesGateway.enabled=true

Other Controllers

Istio:

istioctl install --set profile=default

Other implementations: See Gateway API Implementations

Azure AKS (internal Load Balancer)

For Azure AKS deployments, use values.aks.yaml:

4. (Optional) Install cert-manager

You have two options to install cert-manager:

Option A: Install as a dependency (Recommended)

cert-manager can be installed automatically with this chart:

# Install drunk-k8s-gateway with cert-manager
helm install gateway drunk-charts/drunk-k8s-gateway \
  --set certManager.install=true \
  --set certManager.installCRDs=true \
  -n gateway-system \
  --create-namespace

# Verify cert-manager installation
kubectl get pods -n cert-manager

Option B: Install separately

Install cert-manager independently before this chart:

# Install cert-manager using Helm
helm install cert-manager oci://quay.io/jetstack/charts/cert-manager \
  --version v1.19.1 \
  --namespace cert-manager \
  --create-namespace \
  --set crds.enabled=true

# Verify installation
kubectl get pods -n cert-manager

For more information: cert-manager documentation

5. Install drunk-k8s-gateway Chart

# Create a values file
cat > values-production.yaml << EOF
gatewayClass:
  enabled: true
  name: nginx
  controllerName: gateway.nginx.org/nginx-gateway-controller

gateway:
  enabled: true
  name: shared-gateway
  gatewayClassName: nginx
  listeners:
    - name: http
      protocol: HTTP
      port: 80
      hostname: "*"
      allowedRoutes:
        namespaces:
          from: All
    - name: https
      protocol: HTTPS
      port: 443
      hostname: "*"
      tls:
        mode: Terminate
        certificateRefs:
          - kind: Secret
            name: wildcard-tls
      allowedRoutes:
        namespaces:
          from: All
EOF

# Install the chart
helm install gateway drunk-charts/drunk-k8s-gateway \
  -f values-production.yaml \
  -n gateway-system \
  --create-namespace

Configuration

Basic Configuration

Parameter Description Default
gatewayAPI.version Gateway API version embedded at build v1.2.0
gatewayAPI.channel Installation channel (standard/experimental) standard
gatewayClass.enabled Create GatewayClass resource true
gatewayClass.name Name of the GatewayClass nginx
gatewayClass.controllerName Controller identifier gateway.nginx.org/nginx-gateway-controller
gateway.enabled Create default Gateway false
gateway.name Name of the Gateway shared-gateway
gateway.gatewayClassName GatewayClass to use nginx
certManager.enabled Install cert-manager as dependency false
certManager.installCRDs Install cert-manager CRDs true
certManager.clusterIssuersEnabled Create ClusterIssuers (ACME) false

Dealing with Existing Gateway API CRDs

If Gateway API CRDs were installed previously (manually or by another chart), helm install may fail with an ownership error similar to:

Error: Unable to continue with install: CustomResourceDefinition "gatewayclasses.gateway.networking.k8s.io" ... exists and cannot be imported ... missing key "app.kubernetes.io/managed-by" ... missing key "meta.helm.sh/release-name"

Options to resolve:

  1. Adopt existing CRDs into this release (recommended when versions match):
    ./scripts/adopt-crds.sh gateway drunk-gateway
    helm upgrade --install gateway ./drunk-k8s-gateway \
      -n drunk-gateway --create-namespace -f values.local.yaml
    
  2. Skip CRDs during install (if you are sure they are present and correct):
    helm install gateway ./drunk-k8s-gateway --skip-crds \
      -n drunk-gateway --create-namespace -f values.local.yaml
    
  3. Remove and reinstall CRDs (clean slate):
    kubectl delete crd gatewayclasses.gateway.networking.k8s.io \
      gateways.gateway.networking.k8s.io httproutes.gateway.networking.k8s.io \
      tcproutes.gateway.networking.k8s.io tlsroutes.gateway.networking.k8s.io \
      udproutes.gateway.networking.k8s.io grpcroutes.gateway.networking.k8s.io \
      referencegrants.gateway.networking.k8s.io
    helm upgrade --install gateway ./drunk-k8s-gateway \
      -n drunk-gateway --create-namespace -f values.local.yaml
    

Adoption simply adds Helm ownership annotations: meta.helm.sh/release-name, meta.helm.sh/release-namespace and label app.kubernetes.io/managed-by=Helm.

Domain-Specific Gateway Example

Create a Gateway specifically for your domain (e.g., drunk.dev):

# values-drunk-dev.yaml
gatewayClass:
  enabled: true
  name: nginx
  controllerName: gateway.nginx.org/nginx-gateway-controller

domains:
  - name: drunk-dev
    enabled: true
    gatewayClassName: nginx
    annotations:
      cert-manager.io/cluster-issuer: letsencrypt-prod
    listeners:
      - name: http
        protocol: HTTP
        port: 80
        hostname: "*.drunk.dev"
        allowedRoutes:
          namespaces:
            from: Same
      - name: https
        protocol: HTTPS
        port: 443
        hostname: "*.drunk.dev"
        tls:
          mode: Terminate
          certificateRefs:
            - kind: Secret
              name: drunk-dev-tls
        allowedRoutes:
          namespaces:
            from: Same

Install:

helm install drunk-gateway drunk-charts/drunk-k8s-gateway \
  -f values-drunk-dev.yaml \
  -n default

cert-manager Integration

Prerequisites: Ensure cert-manager is installed (see Step 3 above).

Automatically create ClusterIssuers for TLS certificate management:

# values-with-certmanager.yaml
certManager:
  enabled: true
  clusterIssuers:
    - name: letsencrypt-prod
      email: admin@drunk.dev
      server: https://acme-v02.api.letsencrypt.org/directory
      privateKeySecretRef:
        name: letsencrypt-prod-key
      solvers:
        - http01:
            gatewayHTTPRoute:
              parentRefs:
                - kind: Gateway
                  name: shared-gateway
                  namespace: default

    - name: letsencrypt-staging
      email: admin@drunk.dev
      server: https://acme-staging-v02.api.letsencrypt.org/directory
      privateKeySecretRef:
        name: letsencrypt-staging-key
      solvers:
        - http01:
            gatewayHTTPRoute:
              parentRefs:
                - kind: Gateway
                  name: shared-gateway
                  namespace: default

gateway:
  enabled: true
  name: shared-gateway
  gatewayClassName: nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      hostname: "*.drunk.dev"
      tls:
        mode: Terminate
        certificateRefs:
          - kind: Secret
            name: drunk-dev-tls

For wildcard certificates, use DNS-01 challenge:

certManager:
  enabled: true
  clusterIssuers:
    - name: letsencrypt-prod
      email: admin@drunk.dev
      server: https://acme-v02.api.letsencrypt.org/directory
      privateKeySecretRef:
        name: letsencrypt-prod-key
      solvers:
        - dns01:
            cloudflare:
              apiTokenSecretRef:
                name: cloudflare-api-token
                key: api-token
          selector:
            dnsZones:
              - "drunk.dev"

Installing cert-manager

If you haven’t installed cert-manager yet, use Helm:

# Install cert-manager with CRDs
helm install cert-manager oci://quay.io/jetstack/charts/cert-manager \
  --version v1.19.1 \
  --namespace cert-manager \
  --create-namespace \
  --set crds.enabled=true

# Verify the installation
kubectl get pods -n cert-manager
kubectl get crd | grep cert-manager

For more information and configuration options:

Usage Examples

Example 1: Simple HTTP Gateway

gateway:
  enabled: true
  name: http-gateway
  gatewayClassName: nginx
  listeners:
    - name: http
      protocol: HTTP
      port: 80
      hostname: "*"
      allowedRoutes:
        namespaces:
          from: All

Example 2: Multi-Domain Production Gateway

domains:
  - name: production
    enabled: true
    gatewayClassName: nginx
    annotations:
      cert-manager.io/cluster-issuer: letsencrypt-prod
    listeners:
      - name: https-prod
        protocol: HTTPS
        port: 443
        hostname: "*.prod.example.com"
        tls:
          mode: Terminate
          certificateRefs:
            - name: prod-tls

  - name: staging
    enabled: true
    gatewayClassName: nginx
    annotations:
      cert-manager.io/cluster-issuer: letsencrypt-staging
    listeners:
      - name: https-staging
        protocol: HTTPS
        port: 8443
        hostname: "*.staging.example.com"
        tls:
          mode: Terminate
          certificateRefs:
            - name: staging-tls

Example 3: Using the Gateway with Applications

Once your Gateway is deployed, use it with drunk-app:

# Application values
httpRoute:
  enabled: true
  parentRefs:
    - name: shared-gateway
      namespace: default
  hostnames:
    - myapp.drunk.dev
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: myapp-service
          port: 80

Deploy:

helm install myapp drunk-charts/drunk-app \
  --set httpRoute.enabled=true \
  --set httpRoute.parentRefs[0].name=shared-gateway

Verification

Check GatewayClass

kubectl get gatewayclass
kubectl describe gatewayclass nginx

Check Gateway Status

kubectl get gateway -A
kubectl describe gateway shared-gateway

Expected status:

status:
  conditions:
    - type: Programmed
      status: "True"
  addresses:
    - type: IPAddress
      value: "10.96.100.100"

Get Gateway Address

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

Test Gateway

GATEWAY_IP=$(kubectl get gateway shared-gateway -o jsonpath='{.status.addresses[0].value}')
curl -H "Host: myapp.drunk.dev" http://$GATEWAY_IP/

Upgrading

Upgrade Gateway API CRDs

# Check current version
kubectl get crd gateways.gateway.networking.k8s.io -o jsonpath='{.metadata.labels.gateway\.networking\.k8s\.io/bundle-version}'

# Upgrade to new version
./scripts/install-crds.sh --version v1.2.0

Upgrade Chart

helm upgrade gateway drunk-charts/drunk-k8s-gateway \
  -f values-production.yaml \
  --reuse-values

Uninstallation

Uninstall Chart

helm uninstall gateway -n gateway-system

Remove CRDs

Warning: This will delete ALL Gateway API resources (Gateways, HTTPRoutes, etc.)

./scripts/uninstall-crds.sh

Troubleshooting

Gateway Not Ready

Symptom: Gateway shows Programmed: False

Solutions:

# Check Gateway events
kubectl describe gateway <gateway-name>

# Check controller logs
kubectl logs -n gateway-system -l app=gateway-controller

# Verify GatewayClass exists
kubectl get gatewayclass

TLS Certificate Issues

Symptom: HTTPS not working or certificate errors

Solutions:

# Check if secret exists
kubectl get secret <tls-secret-name>

# If using cert-manager, check Certificate
kubectl get certificate
kubectl describe certificate <cert-name>

# Check ClusterIssuer
kubectl get clusterissuer
kubectl describe clusterissuer <issuer-name>

HTTPRoute Not Attaching

Symptom: HTTPRoute shows no parent

Solutions:

# Verify Gateway name and namespace
kubectl get gateway -A

# Check allowed routes in Gateway
kubectl get gateway <gateway-name> -o yaml | grep -A 10 allowedRoutes

# Verify HTTPRoute parent references
kubectl describe httproute <route-name>

Advanced Configuration

Custom GatewayClass Parameters

gatewayClass:
  enabled: true
  name: nginx-custom
  controllerName: gateway.nginx.org/nginx-gateway-controller
  parametersRef:
    group: gateway.nginx.org
    kind: NginxProxy
    name: nginx-proxy-config

Multiple GatewayClasses

Deploy separate charts for different controllers:

# NGINX Gateway
helm install nginx-gateway drunk-charts/drunk-k8s-gateway \
  --set gatewayClass.name=nginx \
  --set gatewayClass.controllerName=gateway.nginx.org/nginx-gateway-controller

# Istio Gateway
helm install istio-gateway drunk-charts/drunk-k8s-gateway \
  --set gatewayClass.name=istio \
  --set gatewayClass.controllerName=istio.io/gateway-controller

Integration with drunk-app

This chart is designed to work seamlessly with drunk-app:

  1. Deploy shared Gateway with drunk-k8s-gateway
  2. Deploy applications with drunk-app using HTTPRoute
  3. Applications reference the shared Gateway via parentRefs

Example workflow:

# 1. Deploy Gateway infrastructure
helm install gateway drunk-charts/drunk-k8s-gateway -f gateway-values.yaml

# 2. Deploy application with HTTPRoute
helm install myapp drunk-charts/drunk-app \
  --set httpRoute.enabled=true \
  --set httpRoute.parentRefs[0].name=shared-gateway \
  --set httpRoute.hostnames[0]=myapp.drunk.dev

Resources

Contributing

Contributions are welcome! Please see the main drunk.charts repository for contribution guidelines.

License

This chart is part of the drunk.charts project and follows the same license.

Author