Module 3.4: Ingress
Complexity:
[MEDIUM]- HTTP/HTTPS routingTime to Complete: 45-55 minutes
Prerequisites: Module 3.1 (Services), Module 3.3 (DNS)
What You’ll Be Able to Do
Section titled “What You’ll Be Able to Do”After this module, you will be able to:
- Create Ingress resources with path-based and host-based routing rules
- Configure TLS termination on Ingress using Secrets
- Deploy and configure an Ingress controller (NGINX) and explain its role vs the Ingress resource
- Debug Ingress routing failures by checking controller logs, backend services, and annotations
Why This Module Matters
Section titled “Why This Module Matters”While Services expose applications to the network, Ingress provides HTTP/HTTPS routing with features like path-based routing, virtual hosts, and TLS termination. Instead of exposing many NodePorts, you expose one Ingress controller that routes traffic based on URLs.
The CKA exam tests Ingress creation, path routing, and understanding how Ingress connects to Services. You’ll need to create Ingress resources quickly and debug routing issues.
Important: Ingress-NGINX Controller Retirement
The popular ingress-nginx controller reached end-of-life on March 31, 2026. After this date, it receives no releases, bug fixes, or security patches. However, the Ingress API itself (
networking.k8s.io/v1) is NOT deprecated and remains fully supported in Kubernetes. You should learn Ingress (it’s still on the exam and widely deployed) but use Gateway API (Module 3.5) for new deployments. Alternative controllers that support both Ingress and Gateway API include Envoy Gateway, Traefik, Kong, Cilium, and NGINX Gateway Fabric.If you’re migrating from ingress-nginx, use the Ingress2Gateway 1.0 tool to convert Ingress resources to Gateway API resources:
kubectl krew install ingress2gateway
The Hotel Reception Analogy
Think of Ingress as a hotel reception desk. Guests (HTTP requests) arrive at the main entrance (single IP). The receptionist (Ingress controller) asks where they want to go—Room 101 (path
/api) goes to the API service, Room 202 (path/web) goes to the web service. One entry point, intelligent routing inside.
What You’ll Learn
Section titled “What You’ll Learn”By the end of this module, you’ll be able to:
- Understand Ingress vs LoadBalancer vs NodePort
- Create Ingress resources with path and host rules
- Configure TLS termination
- Debug Ingress routing issues
- Work with different Ingress controllers
Did You Know?
Section titled “Did You Know?”-
Ingress requires a controller: The Ingress resource does nothing by itself. You need an Ingress controller (like Envoy Gateway, Traefik, or Kong) to actually route traffic.
-
Gateway API is the recommended successor: Gateway API (covered in Module 3.5) is now GA and the recommended standard for new deployments. Ingress remains supported and widely deployed, but new projects should prefer Gateway API.
-
One Ingress, many services: A single Ingress resource can route to dozens of backend services based on paths and hostnames.
-
Ingress-NGINX is retired: The once-dominant ingress-nginx controller reached end-of-life on March 31, 2026. The Ingress2Gateway 1.0 tool helps migrate existing Ingress resources to Gateway API.
Part 1: Ingress Architecture
Section titled “Part 1: Ingress Architecture”1.1 How Ingress Works
Section titled “1.1 How Ingress Works”┌────────────────────────────────────────────────────────────────┐│ Ingress Architecture ││ ││ External Traffic ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Load Balancer / NodePort │ ││ │ (Ingress Controller's Service) │ ││ └────────────────────────┬────────────────────────────────┘ ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Ingress Controller │ ││ │ (nginx, traefik, etc.) │ ││ │ │ ││ │ Reads Ingress resources and configures routing │ ││ └─────────────────────────┬────────────────────────────────┘ ││ │ ││ ┌─────────────┼─────────────┐ ││ │ │ │ ││ ▼ ▼ ▼ ││ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││ │ Service │ │ Service │ │ Service │ ││ │ /api │ │ /web │ │ /docs │ ││ └────┬─────┘ └────┬─────┘ └────┬─────┘ ││ │ │ │ ││ ▼ ▼ ▼ ││ ┌──────┐ ┌──────┐ ┌──────┐ ││ │ Pods │ │ Pods │ │ Pods │ ││ └──────┘ └──────┘ └──────┘ ││ │└────────────────────────────────────────────────────────────────┘1.2 Ingress vs Other Options
Section titled “1.2 Ingress vs Other Options”| Feature | NodePort | LoadBalancer | Ingress |
|---|---|---|---|
| Layer | L4 (TCP/UDP) | L4 (TCP/UDP) | L7 (HTTP/HTTPS) |
| Path routing | No | No | Yes |
| Virtual hosts | No | No | Yes |
| TLS termination | No | Limited | Yes |
| Cost | Free | $ per LB | One controller for many services |
| External IP | Node IP:Port | Cloud LB IP | Controller’s IP |
1.3 Components Needed
Section titled “1.3 Components Needed”| Component | Purpose | Who Creates |
|---|---|---|
| Ingress Controller | Actually routes traffic | Cluster admin |
| Ingress Resource | Defines routing rules | Developer |
| Backend Services | Target services | Developer |
| TLS Secret | HTTPS certificates | Developer/cert-manager |
Part 2: Ingress Controllers
Section titled “Part 2: Ingress Controllers”2.1 Popular Ingress Controllers
Section titled “2.1 Popular Ingress Controllers”| Controller | Description | Best For |
|---|---|---|
| nginx | Most common, feature-rich | General use |
| traefik | Auto-discovery, modern | Dynamic environments |
| haproxy | High performance | High-traffic sites |
| contour | Envoy-based | Service mesh users |
| AWS ALB | Native AWS integration | AWS environments |
2.2 Installing nginx Ingress Controller (kind/minikube)
Section titled “2.2 Installing nginx Ingress Controller (kind/minikube)”# For kindkubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
# For minikubeminikube addons enable ingress
# Verify installationkubectl get pods -n ingress-nginxkubectl get svc -n ingress-nginx2.3 Check Ingress Controller Status
Section titled “2.3 Check Ingress Controller Status”# Check podsk get pods -n ingress-nginx
# Check servicek get svc -n ingress-nginx
# Check IngressClassk get ingressclassPart 3: Creating Ingress Resources
Section titled “Part 3: Creating Ingress Resources”3.1 Simple Ingress (Single Service)
Section titled “3.1 Simple Ingress (Single Service)”apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: simple-ingressspec: ingressClassName: nginx # Which controller to use rules: - http: paths: - path: / pathType: Prefix backend: service: name: web-service # Target service port: number: 80 # Service port3.2 Path-Based Routing
Section titled “3.2 Path-Based Routing”apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: path-ingressspec: ingressClassName: nginx rules: - http: paths: - path: /api pathType: Prefix backend: service: name: api-service port: number: 80 - path: /web pathType: Prefix backend: service: name: web-service port: number: 80 - path: / pathType: Prefix backend: service: name: default-service port: number: 80┌────────────────────────────────────────────────────────────────┐│ Path-Based Routing ││ ││ Request: http://mysite.com/api/users ││ │ ││ ▼ ││ ┌────────────────────────────────────────────────────────┐ ││ │ Ingress │ ││ │ │ ││ │ /api/* ──────────► api-service │ ││ │ /web/* ──────────► web-service │ ││ │ /* ──────────► default-service │ ││ │ │ ││ └────────────────────────────────────────────────────────┘ ││ │└────────────────────────────────────────────────────────────────┘Pause and predict: You have two Ingress path rules:
/apiwithpathType: Prefixand/api/v1withpathType: Exact. A request arrives for/api/v1/users. Which rule matches, and what happens to a request for/api/v1exactly?
3.3 Path Types
Section titled “3.3 Path Types”| PathType | Behavior | Example |
|---|---|---|
Exact | Exact match only | /api matches /api, not /api/ |
Prefix | Prefix match | /api matches /api, /api/users |
ImplementationSpecific | Controller decides | Varies by controller |
3.4 Host-Based Routing (Virtual Hosts)
Section titled “3.4 Host-Based Routing (Virtual Hosts)”apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: virtual-host-ingressspec: ingressClassName: nginx rules: - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: api-service port: number: 80 - host: web.example.com http: paths: - path: / pathType: Prefix backend: service: name: web-service port: number: 80┌────────────────────────────────────────────────────────────────┐│ Host-Based Routing ││ ││ api.example.com ──────────► api-service ││ web.example.com ──────────► web-service ││ *.example.com ──────────► default-service (if configured) ││ │└────────────────────────────────────────────────────────────────┘3.5 Combining Host and Path Routing
Section titled “3.5 Combining Host and Path Routing”apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: combined-ingressspec: ingressClassName: nginx rules: - host: app.example.com http: paths: - path: /api pathType: Prefix backend: service: name: api-service port: number: 80 - path: / pathType: Prefix backend: service: name: web-service port: number: 80 - host: admin.example.com http: paths: - path: / pathType: Prefix backend: service: name: admin-service port: number: 80Stop and think: Your Ingress serves both
api.example.comandweb.example.com. You want HTTPS for both but with different certificates. How many TLS secrets do you need, and where does TLS termination happen — at the Ingress controller or at the backend pods?
Part 4: TLS/HTTPS Configuration
Section titled “Part 4: TLS/HTTPS Configuration”4.1 Creating TLS Secret
Section titled “4.1 Creating TLS Secret”# Generate self-signed certificate (for testing)openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout tls.key -out tls.crt \ -subj "/CN=example.com"
# Create secretk create secret tls example-tls --cert=tls.crt --key=tls.key
# Or using kubectlk create secret tls example-tls \ --cert=path/to/tls.crt \ --key=path/to/tls.key4.2 Ingress with TLS
Section titled “4.2 Ingress with TLS”apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: tls-ingressspec: ingressClassName: nginx tls: - hosts: - example.com - www.example.com secretName: example-tls # TLS secret name rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: web-service port: number: 804.3 TLS Configuration Flow
Section titled “4.3 TLS Configuration Flow”┌────────────────────────────────────────────────────────────────┐│ TLS Termination ││ ││ Client (HTTPS) ││ │ ││ │ TLS/SSL encrypted ││ ▼ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Ingress Controller │ ││ │ (TLS terminates here) │ ││ │ │ ││ │ Uses certificate from Secret: example-tls │ ││ └─────────────────────────────────────────────────────────┘ ││ │ ││ │ Plain HTTP (inside cluster) ││ ▼ ││ ┌──────────────────┐ ││ │ Service │ ││ │ (port 80) │ ││ └──────────────────┘ ││ │└────────────────────────────────────────────────────────────────┘Part 5: Ingress Annotations
Section titled “Part 5: Ingress Annotations”5.1 Common nginx Annotations
Section titled “5.1 Common nginx Annotations”apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: annotated-ingress annotations: # Rewrite URL path nginx.ingress.kubernetes.io/rewrite-target: /
# SSL redirect nginx.ingress.kubernetes.io/ssl-redirect: "true"
# Timeouts nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
# Rate limiting nginx.ingress.kubernetes.io/limit-rps: "10"
# CORS nginx.ingress.kubernetes.io/enable-cors: "true"spec: ingressClassName: nginx rules: - http: paths: - path: / pathType: Prefix backend: service: name: web-service port: number: 805.2 URL Rewriting
Section titled “5.2 URL Rewriting”# Route /app/(.*) to backend /($1)apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: rewrite-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1spec: ingressClassName: nginx rules: - http: paths: - path: /app/(.*) pathType: ImplementationSpecific backend: service: name: web-service port: number: 80What would happen if: You create an Ingress resource but forget to specify
ingressClassName. There are two Ingress controllers installed in the cluster (nginx and traefik), and neither is marked as default. What happens to your Ingress?
Part 6: Debugging Ingress
Section titled “Part 6: Debugging Ingress”6.1 Debugging Workflow
Section titled “6.1 Debugging Workflow”Ingress Not Working? │ ├── kubectl get ingress (check ADDRESS) │ │ │ ├── No ADDRESS → Controller not processing │ │ Check IngressClass │ │ │ └── Has ADDRESS → Continue debugging │ ├── kubectl describe ingress (check events) │ │ │ └── Errors? → Fix configuration │ ├── Check backend service │ kubectl get svc,endpoints │ │ │ └── No endpoints? → Service has no pods │ ├── Check Ingress controller logs │ kubectl logs -n ingress-nginx <controller-pod> │ └── Test from inside cluster kubectl run test --rm -it --image=curlimages/curl -- \ curl <service>6.2 Common Ingress Commands
Section titled “6.2 Common Ingress Commands”# List ingressesk get ingressk get ing # Short form
# Describe ingressk describe ingress my-ingress
# Get ingress YAMLk get ingress my-ingress -o yaml
# Check IngressClassk get ingressclass
# Check Ingress controller podsk get pods -n ingress-nginx
# View controller logsk logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx6.3 Common Issues
Section titled “6.3 Common Issues”| Symptom | Cause | Solution |
|---|---|---|
| No ADDRESS assigned | No Ingress controller | Install ingress controller |
| ADDRESS assigned but 404 | Path doesn’t match | Check path and pathType |
| 503 Service Unavailable | No endpoints | Check service selector/pods |
| SSL error | Wrong/missing TLS secret | Verify secret exists and matches host |
| Wrong IngressClass | Multiple controllers | Specify correct ingressClassName |
Part 7: Default Backend
Section titled “Part 7: Default Backend”7.1 Configuring Default Backend
Section titled “7.1 Configuring Default Backend”apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: default-backend-ingressspec: ingressClassName: nginx defaultBackend: # Catch-all service: name: default-service port: number: 80 rules: - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: api-service port: number: 80Requests that don’t match any rule go to the defaultBackend.
Common Mistakes
Section titled “Common Mistakes”| Mistake | Problem | Solution |
|---|---|---|
| No IngressClass | Controller doesn’t process | Add ingressClassName to spec |
| Wrong pathType | Routes don’t match | Use Prefix for most cases |
| Service port mismatch | 503 errors | Match Ingress port to Service port |
| TLS secret wrong namespace | SSL errors | Secret must be in same namespace as Ingress |
| Missing Ingress controller | No ADDRESS assigned | Install controller first |
-
Your company runs 15 microservices, each needing external HTTPS access. A junior engineer proposes creating a LoadBalancer Service for each. What is wrong with this approach, and what would you recommend instead?
Answer
Each LoadBalancer Service provisions a separate cloud load balancer, meaning 15 external IPs and 15 times the cost. Instead, deploy a single Ingress controller (exposed via one LoadBalancer) and create Ingress resources with path-based and host-based routing rules to route to all 15 services. This uses one external IP, one load balancer, and gives you Layer 7 features like TLS termination, path routing, and virtual hosts. For new deployments, Gateway API is recommended over Ingress for even richer routing capabilities. -
You create an Ingress and
kubectl get ingressshows the resource but the ADDRESS column is empty. You wait 5 minutes and it is still empty. Walk through your troubleshooting steps.Answer
An empty ADDRESS means no controller is processing the Ingress. First, check if an Ingress controller is installed: `k get pods -n ingress-nginx` (or whichever namespace your controller uses). Second, verify the IngressClass: `k get ingressclass` and confirm your Ingress specifies a matching `ingressClassName`. If no IngressClass is marked as default and your Ingress omits `ingressClassName`, no controller will claim it. Third, check the controller logs for errors: `k logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx`. The ADDRESS populates only after a controller successfully processes the Ingress and assigns it an IP. -
You have an Ingress routing
/apito an API service and/to a frontend service. Users report that requests to/api/usersreturn the frontend page instead of the API response. The Ingress looks correct. What is going on?Answer
The order of path rules matters, and the `/` Prefix rule matches everything including `/api/users`. Check if the `pathType` is correct: both should be `Prefix`. With Prefix matching, the controller should match the longest prefix first (`/api` before `/`), but verify the Ingress controller's behavior. Also check if the rules are under the same host -- if they are split across different Ingress objects, the controller may not merge them correctly. Describe the Ingress and check the events for any warnings about overlapping paths. -
A security audit requires that your Ingress serves HTTPS only, with HTTP requests redirected to HTTPS. The TLS certificate is stored in a Secret named
prod-tls. Write the Ingress configuration and explain what happens if the Secret is in a different namespace than the Ingress.Answer
Add a `tls` section referencing the host and `secretName: prod-tls`, and set the annotation `nginx.ingress.kubernetes.io/ssl-redirect: "true"` to force HTTP-to-HTTPS redirect. The critical detail: the TLS Secret MUST be in the same namespace as the Ingress resource. If `prod-tls` is in a different namespace, the Ingress controller cannot access it and TLS will fail silently -- the controller will use a default/fake certificate instead. There is no cross-namespace Secret reference in the Ingress API. Gateway API solves this with ReferenceGrant. -
Your backend service expects requests at
/but the Ingress routes/app/(.*)to it. Users visiting/app/dashboardsee a 404 from the backend. How do you fix this, and why does the 404 occur?Answer
The 404 occurs because the Ingress forwards the full path `/app/dashboard` to the backend, but the backend only has routes defined under `/` (e.g., `/dashboard`, not `/app/dashboard`). Use the rewrite annotation to strip the prefix: set `nginx.ingress.kubernetes.io/rewrite-target: /$1` with path `/app/(.*)` and `pathType: ImplementationSpecific`. This rewrites `/app/dashboard` to `/dashboard` before forwarding to the backend. Note that rewrite annotations are controller-specific and not portable across different Ingress controllers, which is one reason Gateway API's native URLRewrite filter is preferred.
Hands-On Exercise
Section titled “Hands-On Exercise”Task: Create an Ingress with multiple services and TLS.
Steps:
- Create backend services:
# API servicek create deployment api --image=nginxk expose deployment api --port=80
# Web servicek create deployment web --image=nginxk expose deployment web --port=80- Create path-based Ingress:
cat << 'EOF' | k apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: multi-path-ingressspec: ingressClassName: nginx rules: - http: paths: - path: /api pathType: Prefix backend: service: name: api port: number: 80 - path: / pathType: Prefix backend: service: name: web port: number: 80EOF- Check Ingress:
k get ingressk describe ingress multi-path-ingress- Test routing (if ingress controller is installed):
# Get ingress addressINGRESS_IP=$(k get ingress multi-path-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
# Test paths (from inside cluster if needed)k run test --rm -it --image=curlimages/curl --restart=Never -- \ curl -H "Host: example.com" http://$INGRESS_IP/api- Create host-based Ingress:
cat << 'EOF' | k apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: host-ingressspec: ingressClassName: nginx rules: - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: api port: number: 80 - host: web.example.com http: paths: - path: / pathType: Prefix backend: service: name: web port: number: 80EOF- Create TLS secret (self-signed for testing):
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout tls.key -out tls.crt \ -subj "/CN=example.com"
k create secret tls example-tls --cert=tls.crt --key=tls.key- Create TLS Ingress:
cat << 'EOF' | k apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: tls-ingressspec: ingressClassName: nginx tls: - hosts: - secure.example.com secretName: example-tls rules: - host: secure.example.com http: paths: - path: / pathType: Prefix backend: service: name: web port: number: 80EOF- Cleanup:
k delete ingress multi-path-ingress host-ingress tls-ingressk delete deployment api webk delete svc api webk delete secret example-tlsrm tls.key tls.crtSuccess Criteria:
- Can create path-based routing Ingress
- Can create host-based routing Ingress
- Can configure TLS on Ingress
- Understand IngressClass
- Can debug Ingress issues
Practice Drills
Section titled “Practice Drills”Drill 1: Basic Ingress (Target: 3 minutes)
Section titled “Drill 1: Basic Ingress (Target: 3 minutes)”# Create servicek create deployment drill-app --image=nginxk expose deployment drill-app --port=80
# Create Ingresscat << 'EOF' | k apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: drill-ingressspec: ingressClassName: nginx rules: - http: paths: - path: / pathType: Prefix backend: service: name: drill-app port: number: 80EOF
# Checkk get ingress drill-ingressk describe ingress drill-ingress
# Cleanupk delete ingress drill-ingressk delete deployment drill-appk delete svc drill-appDrill 2: Multi-Path Ingress (Target: 4 minutes)
Section titled “Drill 2: Multi-Path Ingress (Target: 4 minutes)”# Create servicesk create deployment api --image=nginxk create deployment web --image=nginxk expose deployment api --port=80k expose deployment web --port=80
# Create Ingresscat << 'EOF' | k apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: multi-pathspec: ingressClassName: nginx rules: - http: paths: - path: /api pathType: Prefix backend: service: name: api port: number: 80 - path: / pathType: Prefix backend: service: name: web port: number: 80EOF
# Verifyk describe ingress multi-path
# Cleanupk delete ingress multi-pathk delete deployment api webk delete svc api webDrill 3: Host-Based Ingress (Target: 4 minutes)
Section titled “Drill 3: Host-Based Ingress (Target: 4 minutes)”# Create servicesk create deployment app1 --image=nginxk create deployment app2 --image=nginxk expose deployment app1 --port=80k expose deployment app2 --port=80
# Create Ingresscat << 'EOF' | k apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: host-basedspec: ingressClassName: nginx rules: - host: app1.example.com http: paths: - path: / pathType: Prefix backend: service: name: app1 port: number: 80 - host: app2.example.com http: paths: - path: / pathType: Prefix backend: service: name: app2 port: number: 80EOF
# Verifyk get ingress host-basedk describe ingress host-based
# Cleanupk delete ingress host-basedk delete deployment app1 app2k delete svc app1 app2Drill 4: TLS Ingress (Target: 5 minutes)
Section titled “Drill 4: TLS Ingress (Target: 5 minutes)”# Create servicek create deployment secure-app --image=nginxk expose deployment secure-app --port=80
# Generate certificateopenssl req -x509 -nodes -days 1 -newkey rsa:2048 \ -keyout tls.key -out tls.crt -subj "/CN=secure.local"
# Create secretk create secret tls tls-secret --cert=tls.crt --key=tls.key
# Create Ingress with TLScat << 'EOF' | k apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: tls-ingressspec: ingressClassName: nginx tls: - hosts: - secure.local secretName: tls-secret rules: - host: secure.local http: paths: - path: / pathType: Prefix backend: service: name: secure-app port: number: 80EOF
# Verifyk describe ingress tls-ingress
# Cleanupk delete ingress tls-ingressk delete deployment secure-appk delete svc secure-appk delete secret tls-secretrm tls.key tls.crtDrill 5: Check IngressClass (Target: 2 minutes)
Section titled “Drill 5: Check IngressClass (Target: 2 minutes)”# List IngressClassesk get ingressclass
# Describek describe ingressclass nginx
# Check which is defaultk get ingressclass -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.annotations.ingressclass\.kubernetes\.io/is-default-class}{"\n"}{end}'Drill 6: Ingress with Annotations (Target: 4 minutes)
Section titled “Drill 6: Ingress with Annotations (Target: 4 minutes)”# Create servicek create deployment annotated-app --image=nginxk expose deployment annotated-app --port=80
# Create Ingress with annotationscat << 'EOF' | k apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: annotated-ingress annotations: nginx.ingress.kubernetes.io/ssl-redirect: "false" nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"spec: ingressClassName: nginx rules: - http: paths: - path: / pathType: Prefix backend: service: name: annotated-app port: number: 80EOF
# Check annotationsk get ingress annotated-ingress -o yaml | grep -A5 annotations
# Cleanupk delete ingress annotated-ingressk delete deployment annotated-appk delete svc annotated-appDrill 7: Debug Ingress (Target: 4 minutes)
Section titled “Drill 7: Debug Ingress (Target: 4 minutes)”# Create Ingress with wrong service name (intentionally broken)cat << 'EOF' | k apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: broken-ingressspec: ingressClassName: nginx rules: - http: paths: - path: / pathType: Prefix backend: service: name: nonexistent-service port: number: 80EOF
# Debugk describe ingress broken-ingress# Look for warnings about backend
# Check ingress controller logs (if installed)k logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=10
# Fix: create the missing servicek create deployment fix-app --image=nginxk expose deployment fix-app --port=80 --name=nonexistent-service
# Verifyk describe ingress broken-ingress
# Cleanupk delete ingress broken-ingressk delete deployment fix-appk delete svc nonexistent-serviceDrill 8: Challenge - Complete Ingress Setup
Section titled “Drill 8: Challenge - Complete Ingress Setup”Without looking at solutions:
- Create deployments:
apiandfrontend(nginx) - Expose both as ClusterIP services on port 80
- Create Ingress with:
- Path
/apiroutes to api service - Path
/routes to frontend service - Host:
myapp.local
- Path
- Create TLS secret and add HTTPS
- Verify with describe
- Cleanup everything
# YOUR TASK: Complete in under 7 minutesSolution
# 1. Create deploymentsk create deployment api --image=nginxk create deployment frontend --image=nginx
# 2. Expose as ClusterIPk expose deployment api --port=80k expose deployment frontend --port=80
# 3. Create Ingresscat << 'EOF' | k apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: challenge-ingressspec: ingressClassName: nginx rules: - host: myapp.local http: paths: - path: /api pathType: Prefix backend: service: name: api port: number: 80 - path: / pathType: Prefix backend: service: name: frontend port: number: 80EOF
# 4. Add TLSopenssl req -x509 -nodes -days 1 -newkey rsa:2048 \ -keyout tls.key -out tls.crt -subj "/CN=myapp.local"k create secret tls myapp-tls --cert=tls.crt --key=tls.key
# Update Ingress with TLScat << 'EOF' | k apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: challenge-ingressspec: ingressClassName: nginx tls: - hosts: - myapp.local secretName: myapp-tls rules: - host: myapp.local http: paths: - path: /api pathType: Prefix backend: service: name: api port: number: 80 - path: / pathType: Prefix backend: service: name: frontend port: number: 80EOF
# 5. Verifyk describe ingress challenge-ingress
# 6. Cleanupk delete ingress challenge-ingressk delete deployment api frontendk delete svc api frontendk delete secret myapp-tlsrm tls.key tls.crtNext Module
Section titled “Next Module”Module 3.5: Gateway API - The next generation of Kubernetes ingress.