Configuración de reglas de reescritura de URL para ingresos de Nginx
En algunos escenarios de aplicación, el URL de acceso proporcionada por el servicio de backend es diferente de la ruta especificada en la regla de ingreso. La entrada reenvía directamente la ruta de acceso a la misma ruta de backend. Si no se configura la reescritura de URL, se devuelve 404 para todas las solicitudes de acceso. Por ejemplo, si la ruta de acceso en la regla de ingreso se establece en /app/demo y la ruta de acceso proporcionada por el servicio de back-end es /demo, las solicitudes de acceso se reenvían directamente a la ruta /app/demo del servicio de back-end, que no coincide con la ruta de acceso (/demo real) proporcionada por el servicio de backend. Como resultado, se devuelve 404.
En este caso, puede utilizar el método Rewrite para implementar la reescritura de URL. Es decir, puede utilizar la anotación nginx.ingress.kubernetes.io/rewrite-target para implementar reglas de reescritura para diferentes rutas.
Configuración de reglas de reescritura
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-test
namespace: default
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: 'rewrite.bar.com'
http:
paths:
- path: '/something(/|$)(.*)'
backend:
service:
name: <your_service_name> # Replace it with the name of your target Service.
port:
number: <your_service_port> # Replace 8080 with the port number of your target Service.
property:
ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
pathType: ImplementationSpecific
ingressClassName: nginx
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-test
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: 'rewrite.bar.com'
http:
paths:
- path: '/something(/|$)(.*)'
backend:
serviceName: <your_service_name> # Replace it with the name of your target Service.
servicePort: <your_service_port> # Replace 8080 with the port number of your target Service.
Mientras se especifique rewrite-target para una entrada, todas las rutas bajo el mismo host en todas las definiciones de entrada distinguen entre mayúsculas y minúsculas, incluidas las entradas que no tienen rewrite-target especificado.
En el ejemplo anterior, el marcador de posición $2 indica que todos los caracteres coincidentes con el segundo paréntesis (.*) se rellenan en la anotación nginx.ingress.kubernetes.io/rewrite-target.
- rewrite.bar.com/something rewrites to rewrite.bar.com/.
- rewrite.bar.com/something/ rewrites to rewrite.bar.com/.
- rewrite.bar.com/something/new rewrites to rewrite.bar.com/new.
En el contenedor nginx-ingress-controlador, puede ver todas las configuraciones de ingreso en el archivo nginx.conf en el directorio /etc/nginx. La regla de reescritura del ejemplo anterior genera un comando Rewrite y lo escribe en el campo location del archivo nginx.conf.
## start server rewrite.bar.com server { server_name rewrite.bar.com ; ... location ~* "^/something(/|$)(.*)" { set $namespace "default"; set $ingress_name "ingress-test"; set $service_name "<your_service_name>"; set $service_port "80"; ... rewrite "(?i)/something(/|$)(.*)" /$2 break; ... } } ## end server rewrite.bar.com
rewrite regex replacement [flag];
- regex: expresión regular para URI coincidentes. En el ejemplo anterior, (?i)/something(/|$)(.*) es la expresión regular para URI coincidentes, donde (?i) indica que no distingue entre mayúsculas y minúsculas.
- replacement: contenido para reescribir. En el ejemplo anterior, el /$2 indica que la ruta se reescribe en todos los caracteres coincidentes con el segundo paréntesis (.*).
- flag: reescritura de formato.
- last: continúa haciendo coincidir la siguiente regla después de que se haga coincidir la regla actual.
- break: deja de coincidir una vez coincidente la regla actual.
- redirect: devuelve un redireccionamiento temporal con el código 302.
- permanent: devuelve un redireccionamiento permanente con el código 301.
Configuración avanzada de reescritura
Algunos requisitos complejos y avanzados de Rewrite se pueden implementar modificando el archivo de configuración de Nginx nginx.conf. Sin embargo, la función de anotación nginx.ingress.kubernetes.io/rewrite-target se puede personalizar para cumplir con requisitos de Rewrite más complejos.
- nginx.ingress.kubernetes.io/server-snippet: Agregue una configuración personalizada al campo server en el archivo nginx.conf.
- nginx.ingress.kubernetes.io/configuration-snippet: Agregue una configuración personalizada al campo location en el archivo nginx.conf.
Puede utilizar las dos anotaciones anteriores para insertar un comando de Rewrite en el campo server o location del archivo nginx.conf para reescribir el URL. A continuación se presenta un ejemplo:
annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/configuration-snippet: | rewrite ^/stylesheets/(.*)$ /something/stylesheets/$1 redirect; # Add the /something prefix. rewrite ^/images/(.*)$ /something/images/$1 redirect; # Add the /something prefix.
- Cuando un usuario accede a rewrite.bar.com/stylesheets/new.css vuelve a escribir en rewrite.bar.com/something/stylesheets/new.css.
- Cuando un usuario accede a rewrite.bar.com/images/new.jpg vuelve a escribir en rewrite.bar.com/something/images/new.jpg.
Redireccionando HTTP a HTTPS
De forma predeterminada, si una entrada utiliza TLS, las solicitudes se redirigirán (código de estado 308) a HTTPS cuando se utilice HTTP para el acceso. También puede utilizar la siguiente anotación para redirigir a la fuerza las solicitudes a HTTPS.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-test namespace: default annotations: nginx.ingress.kubernetes.io/ssl-redirect: 'true' spec: rules: - host: '' http: paths: - path: / backend: service: name: <your_service_name> # Replace it with the name of your target Service. port: number: <your_service_port> # Replace 8080 with the port number of your target Service. property: ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH pathType: ImplementationSpecific ingressClassName: nginx
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: ingress-test namespace: default annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/ssl-redirect: 'true' spec: rules: - host: '' http: paths: - path: / backend: serviceName: <your_service_name> # Replace it with the name of your target Service. servicePort: <your_service_port> # Replace 8080 with the port number of your target Service.