In the previous chapter you learned how Services provide stable addresses for Pods. But how do visitors from outside the cluster find their way in? If every service had its own public IP, you'd have tangled infrastructure. You need one controlled entrance. That's Ingress.
4.3.1 Why Ingress Exists
A LoadBalancer Service gives you a public IP for one service. But with a web frontend, API backend, and admin dashboard — each a separate Service — you'd need three public IPs and three cloud load balancers. Your bill grows with every new service.
Ingress provides a single entry point for all HTTP/HTTPS traffic. It sits in front of your Services and uses routing rules to direct each request — like a receptionist who sends visitors to different floors based on what they're looking for.
- Path-based routing:
/apigoes to the backend,/goes to the frontend. Multiple applications share one domain. - Host-based routing:
api.example.comroutes to one service,www.example.comto another.
Ingress also handles SSL/TLS termination — decrypting HTTPS at the edge and forwarding plain HTTP internally. Your application code needs no certificate awareness.
Visual Description:
One external IP feeds into the Ingress, routing to multiple ClusterIP Services. Far more cost-efficient than multiple LoadBalancers, with one place to manage routing and SSL.
4.3.2 Ingress Resources: Defining the Rules
An Ingress resource is routing rules in YAML. It does NOT route traffic — think of it as posted directions that someone must read and enforce. That "someone" is the Ingress Controller.
Here's an Ingress resource:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
The three path types behave differently:
- Prefix: Matches any path starting with the prefix —
/apimatches/api,/api/v1,/api/users. Most common. - Exact: Matches only the exact path —
/apimatches only/api, not/api/. - ImplementationSpecific: Matching depends on your Ingress Controller.
⚠️ Common Misconception: "Creating an Ingress resource automatically routes traffic." It does not. Without an Ingress Controller, the resource does nothing.
4.3.3 Ingress Controllers: The Implementation Engine
If the Ingress resource is posted directions, the Ingress Controller is the guard who enforces them. The controller is a pod that watches Ingress resources and configures a reverse proxy to implement their rules.
Popular controllers:
| Controller | Best For |
|---|---|
| NGINX Ingress Controller | General-purpose; most popular |
| Traefik | Cloud-native; auto-discovery |
| HAProxy | High-performance |
| Istio Gateway | Service mesh; advanced routing |
Multiple controllers can coexist using IngressClass to assign each Ingress:
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
spec:
controller: k8s.io/ingress-nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
🛑 PAUSE & RECALL — 2 minutes
- What is the difference between an Ingress resource and an Ingress Controller?
- Name the three path types. When would you use Prefix versus Exact?
- Why is Ingress more cost-efficient than multiple LoadBalancer Services?
Rate your confidence (0–4).
4.3.4 GCE Ingress Controller: GKE-Native Load Balancing
GKE Note: The GCE Ingress Controller integrates your Ingress directly with Google's global load balancing infrastructure — a key advantage of running Kubernetes on GKE.
On GKE, the GCE Ingress Controller provisions an actual Google Cloud HTTP(S) Load Balancer — globally distributed and Google-managed — instead of running NGINX inside your cluster.
Container-Native Load Balancing (CNLB) is what makes this special. Most controllers route to a Service's ClusterIP, then kube-proxy forwards to Pods: Load Balancer → Node → kube-proxy → Pod. With CNLB, the Google load balancer knows your individual Pod IPs directly. Traffic goes: Load Balancer → Pod. This is direct-to-pod routing.
Benefits: lower latency (one less hop), better health awareness (per-Pod health checks, not node-level), and more accurate load distribution.
GKE enables CNLB through Network Endpoint Groups (NEGs) — auto-created when you use the GCE Ingress, containing your Pod IPs attached to the load balancer.
Use it with ingressClassName: gce:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gce-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: my-static-ip
spec:
ingressClassName: gce
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
GKE Note: The GCE Ingress requires Pods to respond HTTP 200 on
/by default. Use aBackendConfigCRD to customize the health check path if your app doesn't serve/.
4.3.5 Advanced Ingress Patterns
SSL/TLS with Managed Certificates. On GKE, reference networking.gke.io/managed-certificates: my-cert in your Ingress. GKE handles request, validation, and renewal automatically.
Rate limiting — the NGINX Ingress Controller supports nginx.ingress.kubernetes.io/limit-rps: "10" for per-IP request limits.
Canary deployments route a percentage of traffic to a new version. NGINX Ingress uses nginx.ingress.kubernetes.io/canary: "true" and nginx.ingress.kubernetes.io/canary-weight: "20" for 20% canary traffic.
Rewrite rules transform URLs — e.g., /api/v2/users → /users via the rewrite-target annotation.
4.3.6 Service Mesh Introduction: Beyond Ingress
Ingress manages north-south traffic (external to internal). For east-west traffic (service-to-service inside the cluster), use a service mesh.
Istio is the most popular mesh; GKE offers it managed as Anthos Service Mesh. The core pattern is the sidecar proxy: every Pod gets an Envoy proxy alongside its app container. All traffic flows through this proxy, forming a mesh that enforces policies and encrypts traffic without code changes.
A mesh provides: mutual TLS (encrypted service calls), traffic shifting (1% → 100% to v2), observability (distributed tracing), and advanced routing (by headers, retries, circuit breakers).
Remember: Ingress manages external-to-internal; a service mesh manages internal service-to-service. They complement each other — Ingress gets users in; the mesh manages what happens inside.
4.3.7 Analogy: The Main Security Gatehouse
Analogy: The Main Security Gatehouse
Imagine a gated neighborhood with one grand entrance. This is your Ingress.
At the gatehouse, several things happen. There's only one entrance — a single controlled access point (your one external IP). Guards have routing directives: "Community center? Right fork. Admin office? Left fork." This is path-based and host-based routing.
Before entry, guards check visitor certificates. No certificate? Redirected to secure verification (HTTPS). Certificates are verified once at the gate — inside, residents don't check IDs at every building. This is SSL/TLS termination.
On busy days, the gatehouse manages crowd flow — letting visitors through at a controlled rate. This is rate limiting. When testing a new layout, 10% of visitors take the new route while 90% stay on the old path. This is canary traffic splitting.
Deep inside, every building has a trusted courier handling inter-building deliveries through secure tunnels. The gatehouse doesn't know about this internal system. This is your service mesh.
Stretch point: Unlike a real gatehouse, Kubernetes Ingress can inspect request content — URL paths, headers — to route. Real guards can't peek inside sealed envelopes; your Ingress reads every HTTP header.
4.3.8 Visual Description: The Gatehouse Architecture
Visual Description:
Picture the gatehouse as concentric zones:
- The Outer Wall (External Internet): Visitors approach. HTTP users are immediately redirected to HTTPS at the gate.
- The Gatehouse (Ingress): One public IP. SSL termination happens here — certificates verified, encryption stripped for internal use. A routing board:
/api → Building B,/ → Building A. - The Internal Streets (Cluster Network): ClusterIP Services carry traffic to destinations.
- The Buildings (Pods): Containers doing the actual work.
- The Courier Network (Service Mesh): Envoy sidecars in every Pod handle all inter-building communication through secure tunnels.
🤔 TRY BEFORE YOU SEE
You need to deploy a web app with three components: React frontend, REST API, and admin dashboard — all accessible from the internet via one domain. Sketch:
- How many Services, and what types?
- How many Ingress rules?
- What path-based routing rules?
- Where does SSL termination happen?
Draw traffic flow from user to each component.
Reveal: Three ClusterIP Services. Three path rules: / → frontend, /api → API, /admin → admin. SSL at the Ingress. Flow: User → Ingress → ClusterIP → Pod. One external IP shared.
🛑 PAUSE & RECALL — 3 minutes
- What is Container-Native Load Balancing, and why is direct-to-pod routing better?
- In the gatehouse analogy, what do SSL termination and rate limiting represent?
- What does Ingress manage (north-south) versus a service mesh (east-west)?
- Why must you install an Ingress Controller before creating an Ingress resource?
Rate your confidence (0–4).
GKE in Practice
The recommended production pattern on GKE: GCE Ingress Controller + Container-Native Load Balancing + Managed Certificates. Globally distributed load balancing, automatic SSL, and direct-to-pod routing — all Google-managed.
Steps:
- Reserve a static IP:
gcloud compute addresses create my-static-ip --global - Create a ManagedCertificate for automatic SSL
- Create Ingress with GCE class, referencing the static IP and certificate
- Use BackendConfig to tune health checks:
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: my-backend-config
spec:
healthCheck:
checkIntervalSec: 10
port: 8080
type: HTTP
requestPath: /healthz
timeoutSec: 60
GKE Note: The GCE Ingress Controller takes 5–10 minutes to provision the load balancer. Don't panic if
kubectl get ingressshows the IP as pending — check the Cloud Console under "Network Services → Load Balancing."
For advanced use cases, consider GKE's Gateway Controller, implementing the Kubernetes Gateway API — the successor to Ingress.
Lab: LAB-4.3 — Ingress and Traffic Management (75 minutes)
Deploy the NGINX Ingress Controller, create path-based routing, configure GCE Ingress with Container-Native LB, and set up a Managed SSL Certificate.
Prerequisites: GKE cluster, 2+ nodes.
Part 1: Deploy Sample Applications (15 min)
kubectl create namespace lab-ingress
kubectl create deployment frontend --image=gcr.io/google-samples/hello-app:1.0 -n lab-ingress
kubectl expose deployment frontend --port=8080 --target-port=8080 --type=ClusterIP -n lab-ingress
kubectl create deployment api --image=gcr.io/google-samples/hello-app:2.0 -n lab-ingress
kubectl expose deployment api --port=8080 --target-port=8080 --type=ClusterIP -n lab-ingress
Verify:
kubectl get services -n lab-ingress
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
# api ClusterIP 10.96.5.10 <none> 8080/TCP
# frontend ClusterIP 10.96.8.20 <none> 8080/TCP
Part 2: Deploy NGINX Ingress Controller (15 min)
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=90s
Part 3: Create Path-Based Routing (15 min)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path-routing
namespace: lab-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 8080
kubectl apply -f ingress-rules.yaml
kubectl get ingress -n lab-ingress
# Get the IP, then test:
curl http://<INGRESS-IP>/
curl http://<INGRESS-IP>/api
Part 4: GCE Ingress with Container-Native LB (15 min)
kubectl apply -f - <<'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gce-ingress
namespace: lab-ingress
annotations:
cloud.google.com/neg: '{"ingress": true}'
spec:
ingressClassName: gce
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 8080
EOF
Wait 5–10 minutes for the GCE Ingress IP, then check NEGs:
kubectl get ingress gce-ingress -n lab-ingress -w
# Once IP is assigned:
gcloud compute network-endpoint-groups list \
--filter="name~frontend" \
--format="table(name, zone, networkEndpointType)"
Part 5: HTTPS with Managed SSL Certificate (15 min)
GKE Note: You need a domain pointed at your GCE Ingress IP. If you don't have one, observe the provisioning process.
kubectl apply -f - <<'EOF'
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: lab-cert
namespace: lab-ingress
spec:
domains:
- lab.yourdomain.com
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gce-https
namespace: lab-ingress
annotations:
networking.gke.io/managed-certificates: lab-cert
kubernetes.io/ingress.global-static-ip-name: lab-static-ip
spec:
ingressClassName: gce
rules:
- host: lab.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 8080
EOF
Check status:
kubectl get managedcertificate lab-cert -n lab-ingress
Cleanup
kubectl delete namespace lab-ingress
kubectl delete namespace ingress-nginx
Chapter Summary
Ingress is your cluster's gatehouse — a single entry point for external HTTP/HTTPS traffic. An Ingress resource defines routing rules; an Ingress Controller implements them. You explored path-based and host-based routing and the resource-controller distinction. On GKE, the GCE Ingress Controller enables Container-Native Load Balancing for direct-to-pod routing. Advanced patterns include managed SSL certificates, rate limiting, canary deployments, and rewrite rules. The service mesh — Istio and Anthos Service Mesh — handles encrypted internal traffic, complementing Ingress.
📇 KEY CONCEPT CARDS
- Q: What is the difference between an Ingress resource and an Ingress Controller?
A: The Ingress resource is a YAML declaration of routing rules. The Ingress Controller is a running component (like NGINX) that watches those rules and implements them. Without a controller, an Ingress resource does nothing.
- Q: What are the three Ingress path types, and when would you use each?
A:Prefixmatches any path starting with the prefix — most common.Exactmatches only the exact character-for-character path.ImplementationSpecificdelegates matching to the specific Ingress Controller.
- Q: What is Container-Native Load Balancing on GKE, and why is it better?
A: CNLB routes directly from the Google Cloud Load Balancer to individual Pods, bypassing nodes. Benefits: lower latency, better per-Pod health awareness, more accurate load distribution.
- Q: What traffic does Ingress manage versus what a service mesh manages?
A: Ingress manages north-south traffic (external users into the cluster). A service mesh like Istio manages east-west traffic (internal service-to-service), adding mTLS, traffic shifting, and observability.
ce mesh like Istio manages east-west traffic (internal