Keywords: Kubernetes | Nginx Ingress | Path Rewriting
Abstract: This article provides a comprehensive analysis of the ingress.kubernetes.io/rewrite-target annotation in Kubernetes Nginx Ingress, based on practical use cases. Starting with basic path rewriting requirements, it examines the implementation differences across versions, with particular focus on the capture group mechanism introduced in version 0.22.0. Through detailed YAML configuration examples and Go backend code demonstrations, the article explores the critical importance of trailing slashes in rewrite rules, regex matching logic, and strategies to avoid common 404 errors. Finally, it summarizes best practices and considerations for implementing precise path rewriting in Kubernetes environments.
In Kubernetes microservices architecture, the Ingress controller serves as the entry point for external traffic, handling crucial routing and rewriting responsibilities. When backend services expect specific request path formats while external clients use different path patterns, path rewriting becomes essential for ensuring proper service communication. This article examines a typical scenario: a backend Pod responding to requests at /api/ path, requiring Ingress to rewrite external /auth/api/ paths to internal paths.
Basic Path Rewriting Requirements and Common Misconceptions
In initial configurations, developers might attempt simple rewrite annotations:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myapi-ing
annotations:
ingress.kubernetes.io/rewrite-target: /api
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: api.myapp.com
http:
paths:
- path: /auth/api
backend:
serviceName: myapi
servicePort: myapi-port
This configuration appears intuitive but actually passes the /auth/ portion to the backend service, causing 404 errors. The root cause lies in insufficient understanding of the rewriting mechanism.
Major Changes in Nginx Ingress Version 0.22.0
Starting with Nginx Ingress controller version 0.22.0, the rewriting mechanism underwent fundamental changes. Official documentation clearly states: "Any substrings within the request URI that need to be passed to the rewritten path must explicitly be defined in a capture group." This means older rewriting approaches are no longer compatible.
The correct configuration requires regex capture groups:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myapi-ing
annotations:
ingress.kubernetes.io/rewrite-target: /api/$2
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: api.myapp.com
http:
paths:
- path: /auth/api(/|$)(.*)
backend:
serviceName: myapi
servicePort: myapi-port
In this configuration, the /auth/api(/|$)(.*) regex contains two capture groups: the first (/|$) matches trailing slashes or string endings, while the second (.*) matches remaining path segments. The $2 in rewrite-target: /api/$2 references the second capture group's content.
The Critical Role of Trailing Slashes and Implementation Details
Practical testing reveals the rewriting mechanism's sensitivity to trailing slashes. Consider these test scenarios:
$ curl https://$(minikube ip)/auth/api/ --insecure
success - path: /api/
$ curl https://$(minikube ip)/auth/api --insecure
failure - path: /auth/api
$ curl https://$(minikube ip)/auth/api/blah/whatever --insecure
success - path: /api/blah/whatever
Only requests containing trailing slashes are correctly rewritten. Examining the generated Nginx configuration file reveals the corresponding rewrite rule:
rewrite /auth/api/(.*) /api/$1 break;
This rule explicitly requires paths to match the /auth/api/ pattern (including trailing slash) to trigger rewriting. While this design ensures precise matching, it introduces potential usage complexity.
Complete Example: From Configuration to Verification
To comprehensively verify the rewriting mechanism, we can deploy a complete test environment. First, create Kubernetes resource definitions:
---
apiVersion: v1
kind: Service
metadata:
name: ingress-rewrite-example
spec:
selector:
app: ingress-rewrite-example
ports:
- name: nginx
port: 80
protocol: TCP
targetPort: 80
type: NodePort
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: ingress-rewrite-example
spec:
template:
metadata:
labels:
app: ingress-rewrite-example
spec:
containers:
- name: ingress-rewrite-example
image: fbgrecojr/office-hours:so-47837087
imagePullPolicy: Always
ports:
- containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-rewrite-example
annotations:
ingress.kubernetes.io/rewrite-target: /api
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- http:
paths:
- path: /auth/api
backend:
serviceName: ingress-rewrite-example
servicePort: 80
The backend service, implemented in Go, specifically validates path rewriting effectiveness:
package main
import (
"fmt"
"strings"
"net/http"
)
func httpHandler(w http.ResponseWriter, r *http.Request) {
var response string
if strings.HasPrefix(r.URL.Path, "/api") {
response = "success"
} else {
response = "failure"
}
fmt.Fprintf(w, response + " - path: " + r.URL.Path + "\n")
}
func main() {
http.HandleFunc("/", httpHandler)
panic(http.ListenAndServe(":80", nil))
}
This backend service checks whether request paths start with /api, thereby verifying rewrite success.
Best Practices and Considerations
Based on the above analysis, we can summarize best practices for using path rewriting in Kubernetes Nginx Ingress:
- Version Compatibility Verification: First confirm the Nginx Ingress controller version; version 0.22.0 and above require capture group syntax.
- Precise Regex Pattern Design: Design matching patterns according to actual requirements, paying special attention to trailing slash handling. The
/auth/api(/|$)(.*)pattern handles both slashed and unslashed cases. - Comprehensive Testing Validation: Test with various path patterns, including slashed, unslashed, and additional path segments.
- Monitoring and Log Analysis: Regularly review Ingress controller logs to ensure rewrite rules function as expected.
- Gradual Deployment Strategy: In production environments, test new rewrite rules with limited traffic first, then expand after confirmation.
As a core API gateway feature, proper path rewriting implementation directly impacts microservices architecture reliability and maintainability. By deeply understanding Nginx Ingress rewriting mechanisms, developers can build more robust and flexible traffic management solutions.