Por qué AISpeech elige Apache APISIX en lugar de NGINX como controlador de Ingress en k8s
Wei Jin
May 7, 2020
Prefacio
Hola a todos, soy Jin Wei de AISpeech, una empresa de alta tecnología especializada en reconocimiento y análisis de voz por computadora, y estoy aquí para hablar sobre la integración de Apache APISIX con K8s en lugar de usar el ingress nativo.
En el momento de escribir esto, Apache APISIX ya se ha aplicado a nuestro entorno de producción y ha asumido parte del tráfico de entrada de negocios. Estamos migrando gradualmente el tráfico del ingress nativo, como se muestra en la siguiente figura.
En realidad, APISIX-ingress-controller registra la IP del pod en el nodo upstream, lo que permite que el tráfico de negocios acceda directamente al pod y evite el DNS de kube. Puedes implementar algunas políticas de balanceo de carga particulares mediante plugins basados en esto. Por lo tanto, por un lado, dependemos de esta capacidad de enrutamiento dinámico de Apache APISIX para la distribución del tráfico. Por otro lado, agregamos algunos plugins personalizados para satisfacer las necesidades del negocio.
En el diagrama anterior, APISIX-ingress-controller parece repetitivo con el ingress nativo. En este artículo, explicaremos brevemente por qué hemos abandonado el ingress nativo y construido nuestro propio controlador de ingress basado en Apache APISIX.
¿Qué es Ingress?
En pocas palabras, Ingress es una forma en que Kubernetes maneja el tráfico externo.
¿Qué problema resuelve Ingress?
Dado que los servicios dentro de un clúster de Kubernetes son redes virtuales, el tráfico externo requiere al menos una IP pública y un puerto correctamente mapeado para acceder a los servicios internos dentro del clúster.
Kubernetes tiene varias formas (NodePort, LoadBalancer, Ingress, …) de exponer interfaces para acceder a los servicios internos de Kubernetes. En comparación, Ingress es definitivamente una forma más económica de lograr un proxy inverso al exponer un número limitado de IPs públicas.
Hablando de proxies inversos, también podríamos construir un NGINX directamente para hacerlo, pero es significativamente más difícil de mantener para sincronizar el estado de los servicios, que cambia fácilmente en Kubernetes, en NGINX.
La buena noticia es que Kubernetes proporciona y mantiene oficialmente un controlador de ingress de NGINX para ayudar a resolver el proxy inverso. Con este controlador de ingress de NGINX, podemos redirigir todo el tráfico que desea acceder a Kubernetes y apuntarlo correctamente a los servicios backend.
Problemas con el Controlador de Ingress Nativo de Kubernetes
El controlador de ingress de NGINX nos ayuda a mantener la sincronización de estado entre el clúster de Kubernetes y NGINX, y proporciona capacidades básicas de proxy inverso, entonces, ¿por qué construimos nuestro propio ingress? Esperamos más del controlador de ingress para satisfacer más necesidades del negocio.
Después de usar el controlador de ingress nativo de Kubernetes, encontramos que los siguientes problemas son prominentes:
-
Problema de recarga
El ingress nativo de Kubernetes está diseñado para pasar archivos de configuración YAML al controlador de ingress, convertirlos en archivos de configuración de NGINX y luego activar una recarga para que la configuración surta efecto.
Esto es inaceptable, especialmente cuando el tráfico utiliza conexiones largas, lo que puede llevar a accidentes.
En contraste, Apache APISIX soporta la recarga en caliente de configuraciones, por lo que puedes definir y modificar rutas en cualquier momento sin activar una recarga de NGINX.
-
Escribir scripts y llenar parámetros en anotaciones
El controlador de ingress nativo soporta fragmentos de script definidos por anotaciones en archivos YAML, lo que parece una solución temporal para soportar características avanzadas y, francamente, es realmente difícil de gestionar. La gran cantidad de scripts en anotaciones causa problemas al personal de DevOps.
En Apache APISIX, podemos escribir lógica mediante código de plugin para exponer una interfaz de configuración simple que facilita el mantenimiento de la configuración y evita la interferencia de scripts con el personal de DevOps.
-
Falta de soporte para balanceo de carga con estado
No se soportan políticas avanzadas de balanceo de carga, como "persistencia de sesión", etc. Kubernetes es un sistema de gestión de aplicaciones en contenedores orientado a operaciones, lo que puede tener que ver con el hecho de que Kubernetes promueve un enfoque de implementación sin estado, por lo que Kubernetes no soportará oficialmente estas políticas de balanceo de carga contradictorias en un futuro cercano. De hecho, Google ya ha intentado abordar estos problemas con su solución de malla de servicios (Istio). La arquitectura de Istio es perfecta, pero a expensas del rendimiento, lo que puede resolverse con mixer v2.
Dado que Kubernetes soporta escalado, también podemos extender Apache APISIX para satisfacer nuestras necesidades avanzadas de balanceo de carga, ya que Apache APISIX no solo soporta "persistencia de sesión" y otros balanceos de carga de forma nativa, sino que también tiene la capacidad de escalar la fase de balanceador.
-
Pesos dinámicos
Los servicios de negocio a menudo necesitan controlar el tráfico por porcentaje, lo que se convierte en un problema en Kubernetes.
Aunque Kubernetes soporta IPVS (IP Virtual Server) después de la versión 1.8, ni los parámetros de inicio de “kube-proxy” ni las anotaciones de “kube-route” son tan fáciles de usar como Apache APISIX, que internamente abstrae ruta, servicio, consumidor, upstream, plugin y otros objetos principales. Ajustar el peso de tales operaciones es naturalmente soportado, simplemente modificando el “peso del nodo” bajo “upstream”.
-
Capacidades de extensión inflexibles
Aunque Ingress fue diseñado originalmente para abordar el tráfico externo, no hay menos demanda para el tráfico externo que para el tráfico interno.
La liberación canaria a nivel de servicio, la ruptura de circuito, el control de flujo, la autenticación, el control de tráfico y otros requisitos se implementan más comúnmente en Ingress.
Apache APISIX proporciona soporte de plugins para escalabilidad, y además de los plugins oficiales, puedes personalizar plugins para satisfacer tus propias características.
También hay algunos problemas de configuración causados por ConfigMap y Namespaces, que están relacionados con la forma en que los usamos y no son genéricos, por lo que no entraré en ellos aquí.
Controlador de Ingress de Apache APISIX
Debido a las poderosas capacidades de enrutamiento y escalabilidad de Apache APISIX, usar Apache APISIX como una implementación de Ingress puede resolver fácilmente los puntos de dolor mencionados anteriormente y proporcionar a la comunidad una opción adicional de controlador de Ingress. El diagrama de tiempo es el siguiente:
Para implementar el controlador de ingress de Apache APISIX, necesitamos resolver dos tipos de problemas fundamentales: uno es resolver la sincronización entre el clúster de Kubernetes y el estado de Apache APISIX; el otro es definir los objetos en Apache APISIX en Kubernetes (CRD).
Para integrar rápidamente Apache APISIX y aprovecharlo, creamos el proyecto Apache APISIX ingress controller (todos son bienvenidos a participar), que actualmente implementa el primer tipo de problema básico: sincronizar la información del pod de Kubernetes con el upstream de Apache APISIX, mientras implementa una copia de seguridad primaria para resolver sus propios problemas de alta disponibilidad.
Dado que Kubernetes usa YAML para definir el estado del clúster de manera declarativa, necesitamos definir CRD (Definiciones de Recursos Personalizados) para los objetos (ruta/servicio/upstream/plugin) en Apache APISIX para integrarlos en Kubernetes.
Además, para facilitar la migración de los usuarios existentes de ingress de Kubernetes, intentaremos ser compatibles con los elementos de configuración de ingress existentes.
Estas características serán el objetivo de nuestros próximos esfuerzos, y les damos la bienvenida a participar.