Una de las formas en que una malla de servicios puede hacer que sea más complicado administrar un entorno de Kubernetes es cuando debe configurarse por separado del controlador de Ingress . Las configuraciones separadas no sólo consumen mucho tiempo. Aumentan la probabilidad de errores de configuración que pueden impedir el enrutamiento adecuado del tráfico e incluso provocar vulnerabilidades de seguridad (como actores maliciosos que obtienen acceso a aplicaciones restringidas) y malas experiencias (como clientes que no pueden acceder a aplicaciones para las que están autorizados). Además del tiempo que lleva realizar configuraciones separadas, terminas gastando más tiempo solucionando errores.
Puede evitar estos problemas y ahorrar tiempo al integrar el controlador de ingreso NGINX basado en NGINX Plus con NGINX Service Mesh para controlar el tráfico mTLS de ingreso y egreso. En esta demostración en video, cubrimos los pasos completos.
La documentación de apoyo se referencia en las siguientes secciones:
Antes de comenzar la demostración real, realizamos estos requisitos previos:
Instalé el plano de control de NGINX Server Mesh en el clúster Kubernetes y configuré mTLS y la política estricta
para la malla de servicio .
Instalé NGINX Ingress Controller basado en NGINX Plus como una implementación (en lugar de un DaemonSet) en el clúster de Kubernetes, habilité egress y lo expuse como un servicio de tipo LoadBalancer
.
Nota: La demostración no funciona con el controlador de ingreso NGINX basado en código abierto. Para facilitar la lectura, en el resto de este blog nos referiremos al controlador de ingreso NGINX basado en NGINX Plus simplemente como “Controlador de ingreso NGINX”.
Seguí nuestras instrucciones para descargar la aplicación de muestra bookinfo
, inyectar el sidecar NGINX Service Mesh e implementar la aplicación.
Como resultado de la estricta
política creada en el Paso 1, las solicitudes a la aplicación bookinfo
desde clientes fuera de la malla se rechazan en el sidecar. Lo ilustramos en la demostración ejecutando primero el siguiente comando para configurar el reenvío de puertos:
> kubectl port-forward svc/product-page 9080 Reenvío desde 127.0.0.1:9080 -> 9080 Reenvío desde [::1]:9080 -> 9080 Manejo de conexión para 9080
Cuando intentamos acceder a la aplicación, obtenemos un código de estado503
porque nuestra máquina local no es parte de la malla de servicio:
> curl localhost:9080503
La primera etapa del proceso de exposición de una aplicación es implementar una instancia de controlador de ingreso NGINX. Las instrucciones correspondientes se proporcionan en nuestro tutorial, Implementar con NGINX Plus Ingress Controller para Kubernetes .
NGINX proporciona manifiestos de implementación y DaemonSet para este propósito. En la demostración, usamos el manifiesto de implementación, nginx-plus-ingress.yaml . Incluye anotaciones para enrutar el tráfico de ingreso y egreso a través de la misma instancia del controlador de ingreso NGINX:
El manifiesto permite la integración directa de NGINX Ingress Controller con Spire, la autoridad de certificación (CA) para NGINX Service Mesh, eliminando la necesidad de inyectar el sidecar de NGINX Service Mesh en NGINX Ingress Controller. En su lugar, NGINX Ingress Controller obtiene certificados y claves directamente de la CA de Spire para usarlos para mTLS con los pods en la malla. El manifiesto especifica la dirección del agente Spire:
y monta el socket UNIX del agente Spire en el pod del controlador de ingreso NGINX:
Lo último que hay que tener en cuenta sobre el manifiesto es el argumento CLI -enable-internal-routes
, que nos permite enrutar a los servicios de salida:
Antes de comenzar la demostración, ejecutamos el comando kubectl
apply
-f
nginx-plus-ingress.yaml
para instalar NGINX Ingress Controller y, en este punto, inspeccionamos la implementación en el espacio de nombres nginx-ingress
. Como se muestra en la columna LISTO
de la siguiente salida, solo hay un contenedor para el pod NGINX Ingress Controller, porque no lo hemos inyectado con un sidecar NGINX Service Mesh.
También hemos implementado un servicio de tipo LoadBalancer
para exponer la dirección IP externa del controlador de ingreso NGINX (aquí, 35.233.133.188) fuera del clúster. Accederemos a la aplicação de muestra bookinfo
en esa dirección IP.
> kubectl get pods --namespace=nginx-ingress NOMBRE LISTO ESTADO REINICIO EDAD pod/nginx-ingress-867f954b8f0fzdrm 1/1 En ejecución 0 3d3h NOMBRE TIPO IP DEL CLÚSTER IP EXTERNA ... service-nginx-ingress LoadBalancer 10.31.245.207 35.233.133.188 ... ... PUERTO(S) EDAD ... 80:31469/TCP,443:32481/TCP 4d2h ...
Ahora exponemos la aplicación bookinfo
en la malla, utilizando un recurso Ingress de Kubernetes estándar como se define en bookinfo-ingress.yaml . Las instrucciones correspondientes se proporcionan en nuestro tutorial, Exponer una aplicação con el controlador de ingreso NGINX Plus .
El recurso hace referencia a un secreto de Kubernetes para la aplicación bookinfo
en la línea 10 e incluye una regla de enrutamiento que especifica que las solicitudes para bookinfo.example.com se envían al servicio productpage
( líneas 11 a 18 ). El secreto se define en bookinfo-secret.yaml :
Ejecutamos este comando para cargar la clave y el certificado, que en la demo está autofirmado:
> kubectl apply -f bookinfo-secret.yaml secret/bookinfo-secret sin cambios
Activamos el recurso Ingress:
> kubectl apply -f bookinfo-ingress.yaml ingress.networking.k8s.io/bookinfo-ingress eliminado
y verificar que Ingress Controller agregó la ruta definida en el recurso, como lo confirma el evento al final de la salida:
> kubectl describe ingress bookinfo-ingress ...
Eventos:
Tipo Motivo Antigüedad Desde Mensaje ---- ------ ---- ---- ------- Normal Añadido o actualizado 5s nginx-ingress-controller Configuración para... ...default/bookinfo-ingress se añadió o actualizó
En la demostración ahora usamos un navegador para acceder a la aplicación bookinfo
en https://bookinfo.example.com/ . (Anteriormente hemos agregado una asignación en el archivo /etc/hosts local entre la dirección IP del servicio Ingress Controller – 35.233.133.188 en la demostración, como se indicó anteriormente – y bookinfo.example.com . Para obtener instrucciones, consulte la documentación .) La información en la sección Reseñas de libros de la página cambia periódicamente a medida que las solicitudes rotan entre las tres versiones del servicio de reseñas
definido en bookinfo.yaml ( descargar ).
A continuación inspeccionamos el tráfico de entrada a los clústeres. Ejecutamos el script generate-traffic.sh para realizar solicitudes al servicio productpage
a través de la dirección IP pública del controlador de ingreso NGINX y luego ejecutamos el comando nginx-meshctl
top
para monitorear el tráfico:
> nginxmesh-ctl top deploy/productpage-v1 Dirección de implementación Recurso Tasa de éxito P99 P90 P50 ... productpage-v1 A details-v1 100,00 % 3 ms 3 ms 2 ms A reviews-v2 100,00 % 99 ms 90 ms 20 ms A reviews-v3 100,00 % 99 ms 85 ms 18 ms A reviews-v1 100,00 % 20 ms 17 ms 9 ms Desde nginx-ingress 100,00 % 192 ms 120 ms 38 ms ... Número de solicitudes ... 14 ... 5 ... 5 ... 12
A continuación mostramos una forma alternativa de exponer una aplicación, utilizando un recurso NGINX VirtualServer . Es un recurso de controlador de ingreso NGINX personalizado que admite un manejo de tráfico más complejo, como división de tráfico y enrutamiento basado en contenido.
Primero eliminamos el recurso Ingress estándar:
> kubectl delete -f bookinfo-ingress.yaml ingress.networking.k8s.io "bookinfo-ingress" eliminado
Nuestro archivo bookinfo-vs.yaml configura mTLS con el mismo secreto que en bookinfo-ingress.yaml ( líneas 7-8 ). Las líneas 9 a 12 definen el servicio productpage
como el upstream, y las líneas 13 a 24 una ruta que envía todas las solicitudes GET
realizadas en bookinfo.example.com a ese upstream. Para los métodos HTTP distintos de GET
, devuelve el código de estado405
.
Aplicamos el recurso:
> kubectl apply -f bookinfo-vs.yaml virtualserver.kubernetes.nginx.org/bookinfo-vs creado
Luego realizamos los mismos pasos que con el recurso Ingress: ejecutamos el comando kubectl
describe
para confirmar la implementación correcta y acceder a la aplicación en un navegador. Otra confirmación de que la aplicación funciona correctamente es que rechaza el método POST
:
> curl -k -X POST https://bookinfo.example.com/ Método no permitido
Ahora mostramos cómo enrutar el tráfico de salida a través del controlador de ingreso NGINX. Nuestro tutorial Configurar una ruta de salida segura con NGINX Plus Ingress Controller cubre el proceso mediante el uso de diferentes aplicaciones de muestra.
Ya hemos definido un pod bash
simple en bash.yaml y lo hemos implementado en el espacio de nombres predeterminado desde donde enviamos solicitudes. Como se muestra en la columna LISTO
de esta salida, se ha inyectado con el sidecar NGINX Service Mesh.
> kubectl obtener todoNOMBRE LISTO ESTADO REINICIO ANTIGÜEDAD
pod/bash-6ccb678958-zsgm7 2/2 En ejecución 0 77 s
NOMBRE TIPO IP DEL CLÚSTER IP EXTERNA PUERTO(S) ANTIGÜEDAD
service/kubernetes IP del clúster 10.31.240.1 <none> 443/TCP 4d2h
...
Hay varios casos de uso en los que es posible que desee habilitar solicitudes desde dentro del pod a un servicio de salida , que es cualquier entidad que no sea parte de NGINX Service Mesh. Algunos ejemplos son los servicios implementados:
En la demostración, consideramos el caso de uso final. Tenemos una aplicação implementada en el espacio de nombres heredado
, que no está controlado por NGINX Service Mesh y donde la inyección automática del sidecar de NGINX Service Mesh está deshabilitada. Solo hay un pod ejecutándose para la aplicación.
> kubectl obtiene todos los --namespaces=legacyNOMBRE LISTO ESTADO REINICIO ANTIGÜEDAD
pod/target-5f7bcb96c6-km9lz 1/1 En ejecución 0 27m
NOMBRE TIPO IP DE CLÚSTER IP EXTERNA PUERTO(S) ANTIGÜEDAD
service/target-svc IP de clúster 10.31.245.213 <none> 80/TCP,443/TCP 27m
...
Recuerde que hemos configurado una política mTLS estricta
para NGINX Service Mesh; como resultado, no podemos enviar solicitudes directamente desde el pod bash
al servicio de destino, porque ambos no pueden autenticarse entre sí. Cuando lo intentamos, obtenemos un código de estado.503
como se ilustra aquí:
> kubectl exec -it bash-6ccb678958-zsgm7 -c bash -- curl target-svc.legacy curl: (56) Error de recepción: conexión restablecida por el comando peer 503 finalizado con el código de salida 56
La solución es permitir que el pod bash
envíe tráfico de salida a través del controlador de ingreso NGINX. Descomentamos la anotación en las líneas 14-15 de bash.yaml :
Luego aplicamos la nueva configuración:
> kubectl apply -f bash.yaml despliegue.apps/bash configurado
y verificar que se haya creado un nuevo pod bash
:
> kubectl get pods NOMBRE LISTO ESTADO REINICIO EDAD bash-678c8b4579-7sfml 2/2 En ejecución 0 6s bash-6ccb678958-zsgm7 2/2 Finalizando 0 3m28s
Ahora, cuando ejecutamos el mismo comando kubectl
exec
que antes, para enviar una solicitud desde el pod bash
al servicio de destino, obtenemos el código de estado404
en lugar de503
. Esto indica que el pod bash
ha enviado con éxito la solicitud al controlador de ingreso NGINX, pero este último no sabe dónde reenviarla porque no hay ninguna ruta definida.
Creamos la ruta requerida con la siguiente definición de recurso de Ingress en legacy-route.yaml . La anotación de ruta interna
en la línea 7 significa que el servicio de destino no está expuesto a Internet, sino solo a las cargas de trabajo dentro de NGINX Service Mesh.
Activamos el nuevo recurso y confirmamos que NGINX Ingress Controller agregó la ruta definida en el recurso:
> kubectl apply -f legacy-route.yaml ingress.networking.k8s.io/target-internal-route creado > kubectl describe ingress target-internal-route -n legacy ...
Eventos:
Tipo Motivo Antigüedad Desde Mensaje ---- ------ ---- ---- ------- Normal Añadido o actualizado 6s nginx-ingress-controller Configuración para... ...legacy/target-internal-route se añadió o actualizó
Ahora, cuando ejecutamos el comando kubectl
exec
, llegamos al servicio de destino:
{"req": {"método": "GET" "url": "/",
"host": "target-svc.legacy",
"remoteAddr": "10.28.2.76:56086"}}
Una ventaja de enrutar el tráfico de salida a través del controlador de ingreso NGINX es que puede controlar exactamente a qué servicios externos se puede acceder desde dentro del clúster: solo aquellos para los que define una ruta.
Una última cosa que mostramos en la demostración es cómo monitorear el tráfico de salida. Ejecutamos el comando kubectl
exec
para enviar varias solicitudes y luego ejecutamos este comando:
> nginxmesh-ctl top deploy/nginx-ingress -n nginx-ingress Dirección de implementación Recurso Tasa de éxito P99 P90 P50 Núm. de solicitudes nginx-ingress Al objetivo 100,00 % 1 ms 1 ms 1 ms 9 Desde bash 100,00 % 0 ms 0 ms 0 ms 9
Muchas mallas de servicios ofrecen opciones de puerta de enlace de entrada y salida, pero creemos que apreciará un beneficio adicional de la integración con NGINX: menor latencia. La mayoría de las mallas requieren que se inyecte un sidecar en el controlador de Ingress, lo que requiere que el tráfico haga un salto adicional en su camino hacia sus aplicaciones. Los segundos importan, y ese salto adicional que ralentiza sus experiencias digitales puede provocar que los clientes busquen en otra parte. NGINX Service Mesh no agrega latencia innecesaria porque no inyecta un sidecar en NGINX Ingress Controller. En cambio, al integrarse directamente con Spire, la CA de la malla, NGINX Ingress Controller se convierte en parte de NGINX Service Mesh. El controlador de ingreso NGINX simplemente obtiene certificados y claves del agente Spire y los usa para participar en el intercambio de certificados mTLS con pods en malla.
Hay dos versiones de NGINX Ingress Controller para Kubernetes: NGINX de código abierto y NGINX Plus. Para implementar NGINX Ingress Controller con NGINX Service Mesh como se describe en este blog, debe usar la versión NGINX Plus, que está disponible para una prueba gratuita de 30 días .
¡NGINX Service Mesh es completamente gratuito y está disponible para descarga inmediata y se puede implementar en menos de 10 minutos! Para comenzar, consulte la documentación y cuéntenos cómo va a través de GitHub .
"Esta publicación de blog puede hacer referencia a productos que ya no están disponibles o que ya no reciben soporte. Para obtener la información más actualizada sobre los productos y soluciones F5 NGINX disponibles, explore nuestra familia de productos NGINX . NGINX ahora es parte de F5. Todos los enlaces anteriores de NGINX.com redirigirán a contenido similar de NGINX en F5.com.