Exercise 7: Ingress with the Gateway API
In this exercise, you will expose your application using the Kubernetes Gateway API via the managed Application Routing add-on, giving it a single external IP address. The Gateway API is the successor to the older Ingress resource and is the recommended way to manage external access to services in your cluster.
Info
Your cluster was created with the Application Routing Gateway API add-on (--enable-app-routing-istio) and the Managed Gateway API CRDs (--enable-gateway-api) back in Exercise 1
. This add-on deploys a managed Istio control plane that provisions the infrastructure behind your Gateway API resources using the approuting-istio GatewayClass. You only work with standard Gateway and HTTPRoute you do not interact with Istio directly.resources
Task 1 - Confirm the Gateway API add-on is ready
Confirm the managed Gateway API CRDs are installed:
kubectl get crds | Select-String "gateway.networking.k8s.io"kubectl get crds | grep "gateway.networking.k8s.io"You should see CRDs such as
gateways.gateway.networking.k8s.ioandhttproutes.gateway.networking.k8s.io.Confirm the
approuting-istioGatewayClassexists and the control plane is running:kubectl get gatewayclass kubectl get pods -n aks-istio-systemkubectl get gatewayclass kubectl get pods -n aks-istio-systemYou should see a
GatewayClassnamedapprouting-istioandistiodpods running in theaks-istio-systemnamespace.
Task 2 - Create a Gateway
Create a
Gatewayresource that listens for HTTP traffic on port 80. This provisions a managed external load balancer for your ingress traffic.$gatewayYaml = @" apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: sample-gateway spec: gatewayClassName: approuting-istio listeners: - name: http port: 80 protocol: HTTP allowedRoutes: namespaces: from: Same "@ # Apply the Gateway manifest $gatewayYaml | kubectl apply -f -cat << EOF | kubectl apply -f - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: sample-gateway spec: gatewayClassName: approuting-istio listeners: - name: http port: 80 protocol: HTTP allowedRoutes: namespaces: from: Same EOFThe add-on provisions a
Deployment,Service, and load balancer namedsample-gateway-approuting-istio. Wait for theGatewayto be programmed and get its assigned public IP address:kubectl wait --for=condition=programmed gateway/sample-gateway --timeout=120s kubectl get gateway sample-gatewaykubectl wait --for=condition=programmed gateway/sample-gateway --timeout=120s kubectl get gateway sample-gatewayThe ADDRESS column shows the public IP you will use to access your app.
Task 3 - Create an HTTPRoute
Create an
HTTPRoutethat routes HTTP traffic to your existing service (sample-svc) on port 80 when requests are sent to thelab.kubernetes.demohost:$httpRouteYaml = @" apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: sample-route spec: parentRefs: - name: sample-gateway hostnames: - lab.kubernetes.demo rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: sample-svc port: 80 "@ # Apply the HTTPRoute manifest $httpRouteYaml | kubectl apply -f -cat << EOF | kubectl apply -f - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: sample-route spec: parentRefs: - name: sample-gateway hostnames: - lab.kubernetes.demo rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: sample-svc port: 80 EOFCheck that the
HTTPRouteis created and accepted:kubectl get httproutekubectl get httproute
Task 4 - Test Access via the Gateway
Important
At this point, if you were doing this for real, you would need to configure your DNS to point lab.kubernetes.demo to the Gateway’s public IP address. You would also want to set up a TLS certificate for secure access.
For the purposes of this lab, we will test the Gateway by calling its public IP from the command line, with a host header set to lab.kubernetes.demo.
Capture the Gateway’s public IP address into a variable:
$INGRESS_IP = kubectl get gateway sample-gateway -o jsonpath='{.status.addresses[0].value}' Write-Host $INGRESS_IPINGRESS_IP=$(kubectl get gateway sample-gateway -o jsonpath='{.status.addresses[0].value}') echo "$INGRESS_IP"Use the following command to test access to your service via the Gateway:
Invoke-WebRequest -Uri "http://$INGRESS_IP" -Headers @{ Host = "lab.kubernetes.demo" }curl -H "Host: lab.kubernetes.demo" http://$INGRESS_IPIf you used PowerShell, you should see the response from your service, with a
200 OKcode, indicating that the Gateway is correctly routing traffic to your service.If you used Bash, you will see the raw HTML of the webpage being displayed, and near the top you should see a line like this:
<title>Welcome to Color Demo</title>
Task 5 - Clean Up
Deleting any pod within our current Deployment will simply tell Kubernetes that the Deployment is not in its desired state and it will automatically create a replacement. You can only delete pods that were spawned by a Deployment by deleting the Deployment.
Delete the Deployment.
kubectl delete deployment sample-depkubectl delete deployment sample-depThe Service is independent of the pods it services, so it’s not affected when the Deployment is deleted. Anyone trying to access the service’s address will simply get an error message. If the Deployment is ever re-created, the Service will automatically start sending traffic to the new pods.
Delete the Service. This may take a little while to complete, as Kubernetes will first remove the public IP and then delete the Service.
kubectl delete service sample-svckubectl delete service sample-svcFinally, delete the
HTTPRouteandGateway:kubectl delete httproute sample-route kubectl delete gateway sample-gatewaykubectl delete httproute sample-route kubectl delete gateway sample-gateway