Skip to content

cprey/applebanana2021

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Learning Kubernetes using Apple-Banana 🍎 🍌

Review the Kubernetes Gateway API docs which explain the Gateway API and how it replaces Ingress for routing traffic into a Kubernetes cluster.

Prerequisites

Some tool to view, edit, and interact with your K8s objects. Can be...

  • OpenLens
  • K9s recommended
  • Kubectl only

We'll use a mix of these

Let's get started

We're going to use minikube as our local Kubernetes cluster. We're going to do things by hand ✋

1. Install minikube

Follow the official minikube installation guide for your OS. You'll also need kubectl installed.

2. Start minikube

minikube start

3. Install the Gateway API CRDs

The Gateway API is not bundled with Kubernetes — you install the CRDs separately. Install the standard channel (which includes Gateway and HTTPRoute):

kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/latest/download/standard-install.yaml

Verify the CRDs are installed:

kubectl get crd gateways.gateway.networking.k8s.io httproutes.gateway.networking.k8s.io

4. Install NGINX Gateway Fabric

NGINX Gateway Fabric is the Gateway API implementation we use (it replaces what ingress-nginx used to do). Install it with:

kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/main/deploy/default/deploy.yaml

Wait for it to be ready:

kubectl wait --namespace nginx-gateway \
  --for=condition=ready pod \
  --selector=app.kubernetes.io/name=nginx-gateway \
  --timeout=90s

Verify a GatewayClass named nginx was created:

kubectl get gatewayclass

5. Pull down this repo and get started

git clone <repo-url>
cd applebanana2021

Create the Apple Deployment

  1. look at the apple.yaml file. It's set up to deploy two things, a k8s deployment and a k8s service
  2. apply the apple.yaml file using kubectl kubectl apply -f apple.yaml
  3. inspect what was created
    1. kubectl get pods
    2. kubectl get deployments
    3. kubectl get services
  4. hit the apple-service by creating a forwarded port
    1. kubectl port-forward service/apple-service 5678:5678 this will "take over" your terminal until you ctrl+c to stop it.
    2. open your browser and navigate to http://localhost:5678 or curl http://localhost:5678

Questions:

  1. What are the Pod labels for the apple pod?
  2. How many containers are in the apple pod?
  3. What happens if you delete the apple pod?
  4. What content is returned by the apple pod?
  5. What does the selector in the service section of apple.yaml say?
  6. Challenge: change the apple service to listen on port 8080 and check it by creating a port forward using kubectl.

What is the Gateway API?

Please bookmark kubernetes.io as you will use it frequently. You may also wish to add the CNCF Slack #gateway-api and #kubernetes channels.

kubernetes.io explains the Gateway API

The Gateway API works at TCP/IP layer 7. It is a set of CRDs (Custom Resource Definitions) that define how traffic enters a Kubernetes cluster. The key resources are:

  • GatewayClass — defines the type of gateway (provisioned by your infrastructure, e.g. nginx)
  • Gateway — represents a deployed gateway instance with one or more listeners (HTTP, HTTPS, etc.)
  • HTTPRoute — defines routing rules that map hostnames and paths to backend services

The Gateway API is more expressive and role-oriented than the older Ingress resource, supporting TLS termination, path-based routing, and more — all without controller-specific annotations.

Why we moved from ingress-nginx to Gateway API

What ingress-nginx was

ingress-nginx was (and still is) a widely-used Ingress controller. It watched for networking.k8s.io/v1 Ingress resources and configured an nginx reverse proxy to route external traffic to services inside the cluster. It worked well for simple cases, but any behavior beyond basic path routing — timeouts, retries, traffic splitting, header manipulation — had to be expressed through nginx-specific annotations like nginx.ingress.kubernetes.io/proxy-read-timeout. That tied your config tightly to one controller. Swap to a different Ingress controller and your annotations silently stop working.

The problem with the Ingress resource

The Ingress resource was intentionally kept minimal by Kubernetes. There was never a standard way to express advanced routing in the spec itself, so every controller invented its own annotation vocabulary. The result: non-portable YAML, inconsistent behavior across environments, and a growing gap between what teams actually needed and what the API provided.

Why Gateway API

ingress-nginx Gateway API
API group networking.k8s.io/v1 (core, minimal) gateway.networking.k8s.io/v1 (CRD, expressive)
Advanced routing Controller-specific annotations Native spec fields
Portability Tied to nginx controller Works with nginx, Istio, Envoy, Cilium, and more
Role separation Single resource owned by app teams GatewayClass/Gateway for infra, HTTPRoute for apps
Status Effectively frozen Actively developed, GA in Kubernetes 1.28

The Kubernetes community has signaled that Gateway API is the long-term successor to Ingress. Migrating now means writing YAML that is portable across gateway implementations, supported by all major service mesh and CNI projects, and backed by a stable, versioned API.

Let's add some TLS to the mix

NOTE: Google Chrome won't allow self-signed certificates. As of writing, Firefox and Safari will both work by adding exceptions. Use Firefox or Safari to load these pages in a web browser.

  1. create a self-signed TLS cert for laptop.int
    1. openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=laptop.int/O=gatewaysvc"
  2. create an /etc/hosts entry for laptop.int — get your minikube IP first:
    1. minikube ip — copy the output (e.g. 192.168.49.2)
    2. add a line to /etc/hosts: <minikube-ip> laptop.int
    • On Mac/Linux: echo "$(minikube ip) laptop.int" | sudo tee -a /etc/hosts
  3. add the certificate to the secrets manager in kubernetes
    1. kubectl create secret tls tls-secret --key tls.key --cert tls.crt
  4. apply gateway.yaml which creates both the Gateway (with TLS termination) and the HTTPRoute
    1. look at the file: cat gateway.yaml
    2. kubectl apply -f gateway.yaml
  5. verify what was created
    1. kubectl get gateway
    2. kubectl get httproute
  6. test with cURL curl -kL https://laptop.int/apple or open in Safari/Firefox.

Clean up

  1. kubectl delete -f gateway.yaml
  2. kubectl delete -f apple.yaml
  3. kubectl delete -f banana.yaml
  4. kubectl delete secret tls-secret
  5. minikube stop && minikube delete

About

k8s Gateway API apple banana tutorial

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors