Desarrollo y Diseño

Cómo Redirigir a “www” con Nginx Ingress

A menudo querrás desplegar una aplicación web en la raíz de tu dominio, así como en el subdominio “www”. Esto ayuda a los usuarios a descubrir su servicio. Nginx Ingress tiene soporte incorporado para el procedimiento.

A continuación se muestra cómo desplegar una carga de trabajo con dos hosts de entrada, “www” y su dominio básico. Cualquiera que visite “www” procederá de forma normal. Los visitantes de la raíz del dominio serán redirigidos al subdominio “www”. Al utilizar una redirección, se reduce el riesgo de que ambos puntos finales puedan aparecer en los resultados de búsqueda.

Uso de la anotación

Nginx Ingress proporciona una anotación de Kubernetes que le permite configurar este comportamiento. Al añadir la anotación a su recurso Ingress, se habilita la infraestructura de redirección. No es necesario escribir manualmente la lógica de reescritura en la configuración de Nginx.

nginx.ingress.kubernetes.io/from-to-www-redirect: "true"

Establezca esta anotación en el campo metadata.annotations de la definición de su recurso Ingress. En la siguiente sección se proporciona un ejemplo de trabajo completo.

Configurando sus Hosts

Debes añadir la configuración de tu host Ingress de la forma habitual. Sólo necesita una línea de host. Usa el dominio “www” aquí – Nginx Ingress manejará automáticamente la redirección desde el dominio simple. Si lo prefiere, puede escribir el dominio simple en su lugar. Nginx Ingress entonces redirigirá a él, desde www.

Añade el resto de la configuración de ingress debajo de la línea de host. Tendrás que indicar la ruta HTTP a servir (normalmente /) y el servicio al que dirigir el tráfico.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  namespace: my-namespace
  annotations:
    kubernetes.io/ingress.class: nginx-ingress
    nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
  rules:
    - host: www.example.com
      http:
        paths:
        - path: /
          backend:
            serviceName: my-service
            servicePort: 80

Este ejemplo de funcionamiento mínimo debería permitirle ver la redirección en acción. Al visitar el dominio, el usuario será redirigido inmediatamente a “www”. Puede estar seguro de que los usuarios interactúan con su sitio a través de un único punto de entrada, aunque haya dos posibles hosts de entrada.

Añadir soporte para HTTPS

El manifiesto mostrado arriba carece de soporte para HTTPS. En un escenario real, es casi seguro que querrá asegurarse de que todos sus hosts de entrada están cubiertos por un certificado TLS.

Conseguir que HTTPS funcione con esta configuración requiere que añada sus dos hosts a un único certificado TLS. Aquí hay un manifiesto actualizado con soporte TLS:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  namespace: my-namespace
  annotations:
    kubernetes.io/ingress.class: nginx-ingress
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
  rules:
    - host: www.example.com
      http:
        paths:
        - path: /
          backend:
            serviceName: my-service
            servicePort: 80
  tls:
    - hosts:
        - example.com
        - www.example.com
      secretName: ingress-tls-secret

Con sólo cinco líneas más de YAML, ahora deberías tener HTTPS funcionando en los dos posibles hosts de entrada. Esto asume que tienes un emisor de certificados activo en tu cluster – estamos usando letsencrypt-prod, proporcionado por cert-manager. Debes seguir la documentación para instalar cert-manager si no hay un controlador de certificados disponible.

También puedes elegir un controlador de certificados alternativo. Tendrá que actualizar la anotación de entrada cluster-issuer con el nombre de un emisor proporcionado por su controlador. No tendrá que cambiar la sección tls del manifiesto, esto funcionará con todos los controladores de certificados de Kubernetes.

Convertir el dominio en una variable

Podemos convertir el manifiesto en un cuadro Helm para evitar tener que repetir el nombre del dominio. En este ejemplo, asumiremos que su nombre de dominio está establecido como ingressDomain en el values.yaml de su gráfico Helm.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  namespace: my-namespace
  annotations:
    kubernetes.io/ingress.class: nginx-ingress
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
  rules:
    - host: {{ print "www." .Values.ingressDomain }}
      http:
        paths:
        - path: /
          backend:
            serviceName: my-service
            servicePort: 80
  tls:
    - hosts:
        - {{ print .Values.ingressDomain }}
        - {{ print "www" .Values.ingressDomain }}
      secretName: ingress-tls-secret

Si alguna vez necesita cambiar su nombre de dominio, ahora sólo tendrá que actualizar el valor en un lugar. Esto también permite el uso del manifiesto dentro de los entornos CI. Su servidor CI podría utilizar su gráfico para hacer girar un nuevo entorno de preparación para cada rama, creando un dominio dinámico (por ejemplo, my-branch.example.com) para establecer como ingressDomain.

Manejando los entornos de desarrollo

¡Ahora tenemos una redirección www funcionando! Puedes parar aquí y desplegar a producción si quieres, ya que el objetivo principal de este tutorial se ha logrado.

Dicho esto, hay algunos problemas con el enfoque que hemos mostrado, particularmente cuando se trabaja dentro de los entornos de desarrollo CI. En la actualidad, cada entorno tendría www preestablecido a su dominio original.

Una forma de resolver esto es reemplazar ingressDomain con dos variables independientes:

  • ingressBase – su dominio base, por ejemplo, example.com
  • ingressDomain – el dominio utilizado actualmente, para este despliegue, por ejemplo, my-branch.example.com

Entonces puede utilizar las comparaciones de variables de Helm para habilitar la redirección a las www sólo cuando esté en un entorno de producción.

spec:
  rules:
    {{ if eq .Values.ingressDomain .Values.ingressBase }}
    - host: {{ print "www." .Values.ingressDomain }}
    {{ else }}
    - host: {{ print .Values.ingressDomain }}
    {{ end }}
      http:
        paths:
          - path: /
            backend:
              serviceName: my-service
              servicePort: 80
  tls:
    - hosts:
      - {{ .Values.ingressDomain }}
      {{ if eq .Values.ingressDomain .Values.ingressBase }}
      - {{ print "www." .Values.ingressDomain }}
      {{ end }}
      secretName: {{ .Values.ingressTlsSecret }}

Al desplegar en producción, establezca ingressDomain al dominio base – debe tener el mismo valor que ingressBase. La condición “if” será igualada, por lo que se creará el ingress www.

Cuando se despliega en un entorno de subdominio, los valores diferentes de ingressDomain e ingressBasedeshabilitarán la redirección www.

Conclusión

La redirección de un dominio al subdominio “www” es una expectativa fundamental de muchos sitios web de cara al público. Usando Nginx Ingress, puedes aplicar este comportamiento tradicional a tus cargas de trabajo en contenedores desplegadas en la nube.

Añade la anotación a tu recurso ingress y asegúrate de que ambos hosts están listados en su especificación. Termina comprobando que el par también aparece en cualquier certificado TLS. Los usuarios nunca deben hablar con un punto final no seguro, incluso si van a ser redirigidos fuera de él.

Síguenos en Facebook