π CKA 2025 β Question 02
Migrate an existing web application from Ingress to Gateway API. HTTPS access must be maintained.
A GatewayClass named nginx is already installed in the cluster.
-
Create a Gateway named
web-gatewaywith hostname gateway.web.k8s.local, maintaining the existing TLS and listener configuration from the Ingress resource namedweb. -
Create an HTTPRoute named
web-routewith hostname gateway.web.k8s.local that maintains the same routing rules as the existing Ingress resource namedweb. -
Test with:
[candidate@cka2025] $ curl https://gateway.web.k8s.local
Finally, delete the existing Ingress resource named web.
β Prerequisite
Run the following command on any Kubernetes cluster:
curl -sL https://raw.githubusercontent.com/ibtisam-iq/SilverKube/main/gateway-stack-installation.sh | bash
This will:
- Install Gateway API CRDs
- Install NGINX Gateway Fabric CRDs
- Deploy the NGINX Gateway Fabric controller (NodePort)
β 1. Create TLS Certificate using OpenSSL
Generate self-signed cert
openssl req -x509 -nodes -days 365 \
-newkey rsa:2048 \
-keyout cert.key \
-out cert.crt \
-subj "/CN=web.k8s.local"
β 2. Create TLS Secret
kubectl create secret tls web-tls \
--cert=cert.crt \
--key=cert.key \
-n default
β 3. Deployment, Service, Ingress
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: html
initContainers:
- command:
- sh
- -c
- echo 'love you my sweetheart, Ibtisam' > /html/index.html
image: busybox:1.28
name: init-container
volumeMounts:
- mountPath: /html
name: html
volumes:
- emptyDir: {}
name: html
---
apiVersion: v1
kind: Service
metadata:
name: web-service
namespace: default
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
namespace: default
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
tls:
- hosts:
- web.k8s.local
secretName: web-tls
rules:
- host: web.k8s.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
EOF
β 4. Create Gateway (web-gateway)
β Note: We are migrating from the Ingressβs TLS + hostname (web.k8s.local) TO the new Gatewayβs hostname (gateway.web.k8s.local).
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: web-gateway
namespace: default
spec:
gatewayClassName: nginx
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: gateway.web.k8s.local
tls:
certificateRefs:
- name: web-tls
EOF
β 5. Create HTTPRoute (web-route)
Must match hostname: gateway.web.k8s.local
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web-route
namespace: default
spec:
parentRefs:
- name: web-gateway
hostnames:
- gateway.web.k8s.local
rules:
- backendRefs:
- name: web-service
port: 80
EOF
β 6. Delete old Ingress
kubectl delete ingress web -n default
controlplane ~ β k get no controlplane -owide
NAME STATUS ROLES AGE VERSION INTERNAL-IP
controlplane Ready control-plane 77m v1.34.0 192.168.121.233
controlplane ~ β echo "192.168.121.233 web.k8s.local" >> /etc/hosts
controlplane ~ β echo "192.168.121.233 gateway.web.k8s.local" >> /etc/hosts
controlplane ~ β curl -sL https://raw.githubusercontent.com/ibtisam-iq/SilverKube/main/gateway-stack-installation.sh | bash
===============================================
β All components installed successfully!
===============================================
controlplane ~ β k get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
web-deployment 1/1 1 1 12s
controlplane ~ β k get svc web-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web-service ClusterIP 172.20.246.187 <none> 80/TCP 11m
controlplane ~ β openssl req -x509 -nodes -days 365 \
-newkey rsa:2048 \
-keyout cert.key \
-out cert.crt \
-subj "/CN=gateway.web.k8s.local"
controlplane ~ β kubectl create secret tls web-tls \
--cert=cert.crt \
--key=cert.key \
-n default
secret/web-tls created
controlplane ~ β k get ingress web
NAME CLASS HOSTS ADDRESS PORTS AGE
web nginx web.k8s.local 80, 443 22s
controlplane ~ β k get svc -n ingress-nginx ingress-nginx-controller
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 172.20.211.75 <pending> 80:32573/TCP,443:32252/TCP 25m
controlplane ~ β curl https://web.k8s.local:32252 -k
love you my sweetheart, Ibtisam
controlplane ~ β k get gateway
NAME CLASS ADDRESS PROGRAMMED AGE
web-gateway nginx True 6m11s
controlplane ~ β k get gateway web-gateway -o jsonpath={.status.listeners[0].attachedRoutes}
1
controlplane ~ β k get httproute web-route
NAME HOSTNAMES AGE
web-route ["gateway.web.k8s.local"] 13m
controlplane ~ β k get svc -n nginx-gateway nginx-gateway
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-gateway NodePort 172.20.124.152 <none> 80:31391/TCP,443:32237/TCP 10m
controlplane ~ β curl https://gateway.web.k8s.local:32237 -k
love you my sweetheart, Ibtisam
controlplane ~ β k delete ingress web
ingress.networking.k8s.io "web" deleted from default namespace
controlplane ~ β curl https://web.k8s.local:32252 -k
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
controlplane ~ β curl https://gateway.web.k8s.local:32237 -k
love you my sweetheart, Ibtisam