How Do Ingress Annotations Work?
Ingress annotations are controller-specific key-value pairs in the Ingress metadata that configure advanced features beyond the core Ingress spec — such as rate limiting, CORS, authentication, URL rewriting, and proxy timeouts. They are not standardized and vary between controllers.
Detailed Answer
The Kubernetes Ingress spec is intentionally minimal — it only defines hosts, paths, backends, and TLS. For features like rate limiting, authentication, CORS, and custom headers, you use annotations specific to your Ingress controller.
How Annotations Work
Annotations are key-value pairs in the Ingress metadata. The controller watches for Ingress objects and reads these annotations to configure its proxy:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
annotations:
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
nginx.ingress.kubernetes.io/cors-allow-origin: "https://myapp.com"
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
Common Nginx Ingress Annotations
TLS and HTTPS
annotations:
# Redirect HTTP to HTTPS
nginx.ingress.kubernetes.io/ssl-redirect: "true"
# Force HTTPS even behind a load balancer
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
# Enable TLS passthrough
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
Rate Limiting
annotations:
# Limit requests per second per IP
nginx.ingress.kubernetes.io/limit-rps: "50"
# Limit connections per IP
nginx.ingress.kubernetes.io/limit-connections: "10"
# Return 503 when rate limit is exceeded
nginx.ingress.kubernetes.io/limit-rate-after: "1m"
URL Rewriting
annotations:
# Rewrite /api/v1/users to /users
nginx.ingress.kubernetes.io/rewrite-target: /$2
# Used with regex path: /api(/|$)(.*)
Proxy Settings
annotations:
# Backend connection timeout
nginx.ingress.kubernetes.io/proxy-connect-timeout: "10"
# Backend read timeout
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
# Backend send timeout
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
# Max request body size
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
CORS
annotations:
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "https://myapp.com"
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE"
nginx.ingress.kubernetes.io/cors-allow-headers: "Authorization, Content-Type"
nginx.ingress.kubernetes.io/cors-max-age: "3600"
Authentication
annotations:
# Basic auth
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 proxy
nginx.ingress.kubernetes.io/auth-url: "https://auth.example.com/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://auth.example.com/oauth2/start"
Custom Headers
annotations:
# Add response headers
nginx.ingress.kubernetes.io/configuration-snippet: |
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header Strict-Transport-Security "max-age=31536000";
Portability Problem
The main drawback of annotations is that they are controller-specific:
| Feature | Nginx Annotation | Traefik Annotation | |---|---|---| | Rate limit | nginx.ingress.kubernetes.io/limit-rps | traefik.ingress.kubernetes.io/rate-limit | | Redirect | nginx.ingress.kubernetes.io/ssl-redirect | traefik.ingress.kubernetes.io/redirect-regex | | Body size | nginx.ingress.kubernetes.io/proxy-body-size | traefik.ingress.kubernetes.io/buffering |
Switching controllers requires rewriting all annotations. This is a key motivation behind Gateway API, which standardizes these features in the spec.
Best Practices
- Document your annotations: Maintain a reference of which annotations are in use and why
- Validate annotations: Wrong annotations are silently ignored — use CI/CD validation
- Minimize annotation use: Prefer defaults and use annotations only when needed
- Consider Gateway API: For new deployments, evaluate whether Gateway API can meet your needs without annotations
Why Interviewers Ask This
Interviewers ask this to test your practical experience with Ingress configuration in production, where annotations are the primary mechanism for customizing routing behavior.
Common Follow-Up Questions
Key Takeaways
- Annotations extend the Ingress spec with controller-specific features.
- They are not portable between controllers — switching controllers requires rewriting annotations.
- Common annotation categories include TLS, rate limiting, authentication, proxying, and CORS.