Gateway

4 minutes read
  1. Prerequisites

Make sure you have installed the helm client on your host machine.

  1. Install the Gateway API CRDs and Envoy Gateway controller
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.4.2 -n envoy-gateway-system --create-namespace

Wait for Envoy Gateway to be ready.

kubectl wait --timeout=5m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available

Create the GatewayClass.

cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: eg
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
EOF
  1. Create a pod named ghost based on the ghost:4 image and expose it with a ClusterIP service
  1. Create a Gateway resource

  2. Create an HTTPRoute resource to expose the ghost service

  3. Verify you can access the ghost web interface

  4. Create a self-signed TLS certificate for the ghost application

  5. Update the Gateway to support HTTPS with TLS

  6. Verify HTTPS access through the Gateway API

  7. Clean up all resources

https://kubernetes.io/docs/concepts/services-networking/gateway/

https://gateway-api.sigs.k8s.io/

  1. Install the Gateway API CRDs and Envoy Gateway controller

Commands provided in instructions.

  1. Create a pod named ghost based on the ghost:4 image and expose it with a ClusterIP service
kubectl run ghost --image=ghost:4 --port 2368 --expose
  1. Create a Gateway resource
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: ghost
spec:
  gatewayClassName: eg
  listeners:
  - name: http
    port: 80
    protocol: HTTP
EOF

The Gateway will create a LoadBalancer service.

$ kubectl get svc -n envoy-gateway-system -l gateway.envoyproxy.io/owning-gateway-name=ghost
NAME                           TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
envoy-default-ghost-c7075eaa   LoadBalancer   10.96.231.63   <pending>     80:31283/TCP   2m38s

The following command gets the value of the NodePort assigned to the HTTP (80) port.

HTTP_NODEPORT=$(kubectl get svc -n envoy-gateway-system -l gateway.envoyproxy.io/owning-gateway-name=ghost -o jsonpath='{.items[0].spec.ports[?(@.port==80)].nodePort}')
echo "Gateway HTTP accessible on NodePort: $HTTP_NODEPORT"
  1. Create an HTTPRoute resource to expose the ghost service

We create the following HTTPRoute (this is the Gateway API equivalent of an Ingress resource).

cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: ghost
spec:
  parentRefs:
  - name: ghost
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: ghost
      port: 2368
EOF
  1. Verify you can access the ghost web interface
# Get node IP
NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}')

# Get the NodePort (if not already set from previous step)
HTTP_NODEPORT=$(kubectl -n envoy-gateway-system get svc -l gateway.envoyproxy.io/owning-gateway-name=ghost -o jsonpath='{.items[0].spec.ports[?(@.port==80)].nodePort}')

echo "Ghost application accessible at: http://$NODE_IP:$HTTP_NODEPORT"

# Test HTTP access
curl http://$NODE_IP:$HTTP_NODEPORT/

The ghost web interface should be accessible at http://$NODE_IP:$HTTP_NODEPORT

  1. Create a self-signed TLS certificate for the ghost application
# Generate private key and certificate
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout ghost-tls.key \
  -out ghost-tls.crt \
  -subj "/CN=ghost.local"

# Create Kubernetes Secret
kubectl create secret tls ghost-tls-secret \
  --cert=ghost-tls.crt \
  --key=ghost-tls.key
  1. Update the Gateway to support HTTPS with TLS
# Update Gateway to include HTTPS listener
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: ghost
spec:
  gatewayClassName: eg
  listeners:
  - name: http
    port: 80
    protocol: HTTP
  - name: https
    port: 443
    protocol: HTTPS
    tls:
      mode: Terminate
      certificateRefs:
      - name: ghost-tls-secret
EOF
  1. Verify HTTPS access through the Gateway API
# Get the NodePort assigned to HTTPS (port 443)
HTTPS_NODEPORT=$(kubectl -n envoy-gateway-system get svc -l gateway.envoyproxy.io/owning-gateway-name=ghost -o jsonpath='{.items[0].spec.ports[?(@.port==443)].nodePort}')
echo "Gateway HTTPS accessible on NodePort: $HTTPS_NODEPORT"

# Test HTTPS access (with self-signed cert)
curl -k https://$NODE_IP:$HTTPS_NODEPORT/
  1. Clean up all resources, and remove envoy gateway
kubectl delete httproute ghost
kubectl delete gateway ghost
kubectl delete secret ghost-tls-secret
kubectl delete pod ghost
kubectl delete service ghost
rm ghost-tls.key ghost-tls.crt
helm uninstall eg -n envoy-gateway-system