Top Kubernetes Ingress Interview Questions

Kubernetes Ingress — Interview Questions & Answers


Section 1 — Fundamentals


Q1. What is Kubernetes Ingress and why do we need it?

Ingress is a Kubernetes API object that manages external HTTP/HTTPS access to services inside a cluster. It provides a single entry point that can route traffic to multiple services based on host, path, or headers — without needing a separate LoadBalancer service per application.

Without Ingress:
Service A → LoadBalancer → public IP 20.x.x.1 ($$$)
Service B → LoadBalancer → public IP 20.x.x.2 ($$$)
Service C → LoadBalancer → public IP 20.x.x.3 ($$$)
With Ingress:
Single LoadBalancer → public IP 20.x.x.1
/api → Service A
/app → Service B
/admin → Service C
One IP, one LB, one TLS certificate

Q2. What is the difference between Ingress and a Service of type LoadBalancer?

LoadBalancer ServiceIngress
LayerL4 (TCP/UDP)L7 (HTTP/HTTPS)
RoutingIP + port onlyhost, path, headers
TLS termination
CostOne LB per serviceOne LB for all services
Path-based routing
Host-based routing

Q3. What are the components of an Ingress resource?

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
namespace: production
annotations: # controller-specific config
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx # which controller handles this
tls: # TLS configuration
- hosts:
- app.contoso.com
secretName: tls-secret
rules: # routing rules
- host: app.contoso.com # host-based routing
http:
paths:
- path: /api # path-based routing
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- path: / # default backend
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80

Q4. What is an Ingress Controller? Is it included in Kubernetes by default?

An Ingress Controller is the implementation — it reads Ingress resources and configures an actual reverse proxy or load balancer accordingly. Kubernetes defines the Ingress API but ships with no controller by default — you must install one.

Popular controllers:

ControllerBest for
NGINX Ingress ControllerGeneral purpose — most widely used
TraefikDynamic config, microservices
HAProxyHigh performance, enterprise
AWS ALB Ingress ControllerEKS on AWS
Azure Application Gateway Ingress (AGIC)AKS on Azure
GCE Ingress ControllerGKE on GCP
Istio GatewayService mesh environments

Q5. What are the three pathType values and how do they differ?

# Exact — must match exactly
- path: /api/v1
pathType: Exact
# Matches: /api/v1
# Does NOT match: /api/v1/, /api/v1/users
# Prefix — matches path prefix split by /
- path: /api
pathType: Prefix
# Matches: /api, /api/, /api/v1, /api/v1/users
# Does NOT match: /apiv1, /apiusers
# ImplementationSpecific — controller decides
- path: /api/*
pathType: ImplementationSpecific
# Behaviour depends on your ingress controller
# NGINX: regex support
# Traefik: glob support

Q6. What is the difference between host-based and path-based routing?

# Host-based routing — different subdomains → different services
rules:
- host: api.contoso.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- host: app.contoso.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
# Path-based routing — same host, different paths → different services
rules:
- host: contoso.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /static
pathType: Prefix
backend:
service:
name: cdn-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80

Q7. What is a default backend?

The default backend handles requests that match no rule in any Ingress. It returns a 404 or custom error page:

spec:
defaultBackend:
service:
name: default-404-service
port:
number: 80
rules:
- host: app.contoso.com
...
# Any request not matching app.contoso.com → default-404-service

Section 2 — Ingress Controllers


Q8. How does NGINX Ingress Controller work internally?

1. You apply an Ingress resource to the cluster
2. NGINX Ingress Controller watches Ingress objects via
Kubernetes API server watch stream
3. Controller translates Ingress rules into nginx.conf:
server {
server_name api.contoso.com;
location /v1 {
proxy_pass http://api-service.production.svc.cluster.local:8080;
}
}
4. Controller hot-reloads NGINX with new config
(without dropping existing connections)
5. Traffic arrives at NGINX pod → routes to upstream service

Q9. What is IngressClass and why was it introduced?

IngressClass was introduced in Kubernetes 1.18 to allow multiple ingress controllers in the same cluster, each handling different Ingress resources:

# Define an IngressClass
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx-internal
annotations:
ingressclass.kubernetes.io/is-default-class: "false"
spec:
controller: k8s.io/ingress-nginx
---
# Reference it in an Ingress
spec:
ingressClassName: nginx-internal # only nginx-internal controller handles this

Common multi-controller pattern:

nginx-external → handles public internet traffic
nginx-internal → handles internal VPN-only traffic
agic → handles Azure Application Gateway traffic

Q10. How do annotations work in Ingress and give examples?

Annotations configure controller-specific behaviour that the Ingress spec itself doesn’t support:

metadata:
annotations:
# NGINX — rewrite URL before forwarding
nginx.ingress.kubernetes.io/rewrite-target: /$2
# NGINX — rate limiting
nginx.ingress.kubernetes.io/limit-rps: "10"
# NGINX — enable CORS
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "https://contoso.com"
# NGINX — client body size limit
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
# NGINX — connection timeout
nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
# NGINX — sticky sessions
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "route"
# NGINX — whitelist specific IPs
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8"
# cert-manager — auto issue TLS certificate
cert-manager.io/cluster-issuer: "letsencrypt-prod"

Q11. What is the difference between NGINX Ingress Controller and AGIC (Azure Application Gateway Ingress Controller)?

NGINX IngressAGIC
Runs asPod inside clusterAzure resource outside cluster
Load balancerService type LB in frontAzure Application Gateway
WAFManual configAzure WAF built-in
TLScert-manager or manualAzure-managed certs
Health probesInternalAzure LB health probes
AutoscalingHPA on NGINX podsApp Gateway autoscales natively
Best forAny clusterAKS on Azure
ARO supportLimited

Section 3 — TLS and Security


Q12. How do you configure TLS termination in Ingress?

# Step 1: Create TLS secret
kubectl create secret tls tls-contoso \
--cert=tls.crt \
--key=tls.key \
-n production
# Step 2: Reference in Ingress
spec:
tls:
- hosts:
- app.contoso.com
- api.contoso.com
secretName: tls-contoso # must be in same namespace as Ingress
rules:
- host: app.contoso.com
...

TLS is terminated at the Ingress controller — traffic between the controller and backend pods travels unencrypted inside the cluster by default (unless you enable backend SSL).


Q13. How does cert-manager automate TLS certificate issuance?

# Install cert-manager, then create a ClusterIssuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@contoso.com
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
ingress:
class: nginx # cert-manager creates a temporary Ingress for ACME challenge
---
# Reference in Ingress — cert-manager auto-issues and renews
metadata:
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- app.contoso.com
secretName: tls-app-contoso # cert-manager creates this Secret automatically

cert-manager watches the Ingress → sees the annotation → calls Let’s Encrypt ACME API → completes HTTP-01 challenge → stores cert in the named Secret → auto-renews before expiry.


Q14. How do you enforce HTTPS redirect in Ingress?

metadata:
annotations:
# Force HTTP → HTTPS redirect (301)
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
# Add HSTS header
nginx.ingress.kubernetes.io/configuration-snippet: |
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Q15. How do you implement authentication at the Ingress level?

# Basic auth
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth-secret
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"
# External OAuth2 (with oauth2-proxy)
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-url: "http://oauth2-proxy.auth.svc.cluster.local/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://auth.contoso.com/oauth2/start"
# mTLS (client certificate authentication)
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-tls-secret: "production/ca-secret"
nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"

Section 4 — Advanced Routing


Q16. How do you implement canary deployments with Ingress?

# Production Ingress (main traffic)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-production
spec:
rules:
- host: app.contoso.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-v1
port:
number: 80
---
# Canary Ingress (10% of traffic)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10" # 10% to v2
spec:
rules:
- host: app.contoso.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-v2
port:
number: 80

Other canary strategies:

# Route by header — specific users get canary
nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
nginx.ingress.kubernetes.io/canary-by-header-value: "true"
# Route by cookie — sticky canary for logged-in users
nginx.ingress.kubernetes.io/canary-by-cookie: "canary_user"

Q17. How do you configure rate limiting in Ingress?

metadata:
annotations:
# Limit requests per second per IP
nginx.ingress.kubernetes.io/limit-rps: "10"
# Limit connections per IP
nginx.ingress.kubernetes.io/limit-connections: "5"
# Limit requests per minute
nginx.ingress.kubernetes.io/limit-rpm: "100"
# Whitelist IPs from rate limiting
nginx.ingress.kubernetes.io/limit-whitelist: "10.0.0.0/8,172.16.0.0/12"
# Return 429 when rate limit exceeded (default is 503)
nginx.ingress.kubernetes.io/limit-req-status-code: "429"

Q18. How does rewrite-target work and what is a common gotcha?

# Without capture group — rewrites entire path
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: contoso.com
http:
paths:
- path: /api
# Request: contoso.com/api/users
# Forwarded as: backend/ ← loses /users
# With capture group — preserves remainder of path
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: contoso.com
http:
paths:
- path: /api(/|$)(.*) # capture group $2
pathType: ImplementationSpecific
# Request: contoso.com/api/users
# Forwarded as: backend/users ✅

Q19. What is the difference between Ingress and Gateway API?

Gateway API is the next generation of Kubernetes ingress — more expressive, role-oriented, and extensible:

FeatureIngressGateway API
API stabilityStable (v1)Stable (v1 for core)
Role separationSingle resourceGatewayClass · Gateway · HTTPRoute
TCP/UDP routing✅ TCPRoute · UDPRoute
Header manipulationAnnotation onlyNative spec
Traffic weightingAnnotation onlyNative spec
Multi-tenantDifficultDesigned for it
TLS passthroughAnnotationNative
Future directionMaintenance modeActive development
# Gateway API example
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app-route
spec:
parentRefs:
- name: prod-gateway
hostnames:
- app.contoso.com
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
port: 8080
weight: 90
- name: api-service-v2
port: 8080
weight: 10 # native canary without annotations

Section 5 — Troubleshooting


Q20. A service is returning 404 from Ingress. How do you debug it?

# Step 1: Verify Ingress resource is created and has an address
kubectl get ingress -n production
# NAME CLASS HOSTS ADDRESS PORTS AGE
# my-ingress nginx app.contoso.com 20.x.x.x 80,443 5m
# If ADDRESS is empty → controller not reconciling → check controller pods
# Step 2: Describe Ingress — look for events
kubectl describe ingress my-ingress -n production
# Events show: backend service not found, port mismatch, etc.
# Step 3: Verify backend service exists and has endpoints
kubectl get svc api-service -n production
kubectl get endpoints api-service -n production
# If endpoints are empty → no pods matching service selector
# Step 4: Check service selector matches pod labels
kubectl get pods -n production --show-labels
kubectl get svc api-service -n production -o yaml | grep selector
# Step 5: Check Ingress controller logs
kubectl logs -n ingress-nginx \
-l app.kubernetes.io/name=ingress-nginx \
--tail=100
# Step 6: Verify IngressClass matches controller
kubectl get ingressclass
kubectl get ingress my-ingress -o yaml | grep ingressClassName

Q21. Ingress is returning 502 Bad Gateway. What are the causes?

# 502 means Ingress reached the backend but got an error
# Cause 1: Backend pod is crashing
kubectl get pods -n production
kubectl logs <pod-name> -n production --previous
# Cause 2: Port mismatch — Ingress port ≠ container port
kubectl get ingress -o yaml # check backend port
kubectl get svc api-service -o yaml # check targetPort
kubectl get pods -o yaml | grep containerPort
# Cause 3: Backend requires HTTPS but Ingress sending HTTP
metadata:
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" # add this
# Cause 4: Upstream timeout
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "120"
nginx.ingress.kubernetes.io/proxy-send-timeout: "120"
# Cause 5: Pod not ready — readiness probe failing
kubectl describe pod <pod-name> -n production
# Check: Readiness probe failed

Q22. How does Ingress handle WebSocket connections?

# WebSockets require long-lived connections — default timeouts too short
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
# NGINX automatically detects Upgrade header and handles WebSocket
# No additional annotation needed for basic WebSocket support
# For sticky sessions (WebSocket clients must hit same pod)
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "ws-route"
nginx.ingress.kubernetes.io/session-cookie-hash: "sha1"

Q23. What happens when two Ingress resources define the same host and path?

Two Ingress resources both define:
host: app.contoso.com
path: /api
Result: NGINX Ingress uses the OLDER resource (by creation timestamp)
The newer one is effectively ignored
Best practice:
- Use a single Ingress per namespace for overlapping hosts
- Or merge rules into one Ingress resource
- NGINX logs a warning about duplicate path
Check for conflicts:
kubectl get ingress -A | grep app.contoso.com

Q24. How do you expose an Ingress controller in different environments?

# Cloud (AKS, EKS, GKE) — LoadBalancer service (most common)
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx-controller
spec:
type: LoadBalancer # cloud provider provisions LB + public IP
ports:
- port: 80
- port: 443
# On-premises / bare metal — NodePort
spec:
type: NodePort
ports:
- port: 80
nodePort: 30080
- port: 443
nodePort: 30443
# On-premises with MetalLB — LoadBalancer with IP pool
# MetalLB assigns IP from your on-prem address pool
# ARO / OpenShift — use Route instead of Ingress
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: my-app
spec:
host: app.cluster.aroapp.io
to:
kind: Service
name: my-service
tls:
termination: edge

Quick-Reference Cheat Sheet

Ingress components:
ingressClassName → which controller handles this
tls → TLS secret reference
rules → host + path → service mapping
defaultBackend → catch-all for unmatched requests
annotations → controller-specific configuration
pathType values:
Exact → /api matches only /api
Prefix → /api matches /api, /api/v1, /api/users
ImplementationSpecific → controller decides (regex, glob)
Common debug commands:
kubectl get ingress -A
kubectl describe ingress <name>
kubectl get endpoints <service>
kubectl logs -n ingress-nginx -l app=ingress-nginx
Common HTTP errors:
404 → no matching rule / wrong path
502 → backend unreachable or crashing
503 → no healthy endpoints / rate limited
504 → backend timeout (increase proxy-read-timeout)
SSL certificate error → cert not in same namespace as Ingress

Leave a Reply