Una comparación exhaustiva de API Gateways, Kubernetes Gateways y Service Meshes
June 9, 2023
Aún existe mucha confusión sobre las puertas de enlace de API, las puertas de enlace de Kubernetes y las mallas de servicios. Gran parte de esto se debe a:
- Las personas suelen mencionar estas tecnologías con las mismas palabras clave, como implementaciones canarias, limitación de tasa y descubrimiento de servicios.
- Todas estas tecnologías utilizan proxies inversos.
- Algunas puertas de enlace de API tienen sus propias puertas de enlace de Kubernetes y mallas de servicios, y viceversa.
- Hay muchos artículos/vídeos que comparan las tres tecnologías y concluyen por qué una es mejor que la otra.
En este artículo, intentaré explicar estas tecnologías y compartir cómo difieren fundamentalmente y se adaptan a diferentes casos de uso.
Puertas de enlace de API
Una puerta de enlace de API se sitúa entre tus aplicaciones cliente y tus APIs. Acepta todas las solicitudes de los clientes, las reenvía a las APIs requeridas y devuelve la respuesta a los clientes en un paquete combinado.
Básicamente, es un proxy inverso con muchas capacidades.
Además, una puerta de enlace de API también puede tener características como autenticación, seguridad, control de tráfico granular y monitoreo, permitiendo que los desarrolladores de APIs se centren únicamente en las necesidades del negocio.
Hay muchas soluciones de puertas de enlace de API disponibles. Algunas de las soluciones gratuitas y de código abierto más populares son:
- Apache APISIX: Una puerta de enlace de API de alto rendimiento, extensible y nativa de la nube, construida sobre Nginx.
- Gloo Edge: Una puerta de enlace de API construida sobre el proxy Envoy.
- Kong: Una puerta de enlace de API plugable también construida sobre Nginx.
- Tyk: Una puerta de enlace de API escrita en Go que soporta protocolos REST, GraphQL, TCP y gRPC.
Plataformas en la nube como GCP, AWS y Azure también tienen sus propias puertas de enlace de API propietarias.
Las puertas de enlace de API, las puertas de enlace de Kubernetes y las mallas de servicios soportan implementaciones canarias: lanzar gradualmente una nueva versión de software a un pequeño subconjunto de usuarios antes de hacerla disponible de manera general.
El siguiente ejemplo muestra cómo configurar una implementación canaria en Apache APISIX.
Puedes enviar una solicitud a la API de administración de APISIX con la siguiente configuración:
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri":"/*",
"plugins":{
"traffic-split":{
"rules":[
{
"weighted_upstreams":[
{
"upstream":{
"name":"api-v1",
"type":"roundrobin",
"nodes":{
"api-v1:8080":1
}
},
"weight":95
},
{
"weight":5
}
]
}
]
}
},
"upstream":{
"type":"roundrobin",
"nodes":{
"api-v2:8080":1
}
}
}'
APISIX ahora enrutará el 95% del tráfico al servicio api-v1 y el 5% al servicio api-v2.
Puertas de enlace de Kubernetes
Las puertas de enlace de Kubernetes son simplemente puertas de enlace de API nativas de Kubernetes. Es decir, puedes gestionar estas puertas de enlace de API con la API de Kubernetes, similar a un pod, servicio o despliegue de Kubernetes.
En Kubernetes, tus APIs son pods y servicios desplegados en un clúster. Luego, usas una puerta de enlace de Kubernetes para dirigir el tráfico externo a tu clúster.
Kubernetes proporciona dos APIs para lograr esto: la API Ingress y la API Gateway.
API Ingress de Kubernetes
La API Ingress se creó para superar las limitaciones de los tipos de servicios predeterminados, NodePort y LoadBalancer, introduciendo características como enrutamiento y terminación SSL. También estandarizó cómo expones los servicios de Kubernetes al tráfico externo.
Tiene dos componentes: el Ingress y el controlador de Ingress.
El objeto nativo de Kubernetes Ingress define un conjunto de reglas sobre cómo el tráfico externo puede acceder a tus servicios.
Este ejemplo de configuración muestra cómo enrutar el tráfico basado en la ruta URI con el objeto Ingress de Kubernetes:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-routes
spec:
ingressClassName: apisix
rules:
- http:
paths:
- backend:
service:
name: api-v1
port:
number: 8080
path: /v1
pathType: Exact
- backend:
service:
name: api-v2
port:
number: 8080
path: /v2
pathType: Exact
Un controlador de Ingress implementa estas reglas y enruta el tráfico a tu clúster utilizando un proxy inverso.
Hay más de 20 implementaciones de controladores de Ingress. APISIX tiene un controlador de Ingress que envuelve la puerta de enlace de API de APISIX para funcionar como Ingress de Kubernetes.
El controlador de Ingress de APISIX convierte el objeto Ingress de Kubernetes en la configuración de APISIX.
APISIX luego implementa esta configuración.
Puedes intercambiar APISIX con cualquier otro controlador de Ingress, ya que la API Ingress no está ligada a ninguna implementación específica.
Esta neutralidad de proveedor funciona bien para configuraciones simples. Pero si deseas hacer enrutamientos complejos como una implementación canaria, debes depender de anotaciones específicas del proveedor.
El siguiente ejemplo muestra cómo configurar una implementación canaria usando Nginx Ingress. Las anotaciones personalizadas utilizadas aquí son específicas de Nginx:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "5"
name: api-canary
spec:
rules:
- http:
paths:
- backend:
serviceName: api-v2
servicePort: 8080
path: /
La configuración anterior enrutará el 5% del tráfico al servicio api-v2.
Además de las anotaciones, los controladores de Ingress como APISIX tienen CRDs personalizados de Kubernetes para superar las limitaciones de la API Ingress.
El siguiente ejemplo utiliza el CRD de APISIX, ApisixRoute, para configurar una implementación canaria:
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: api-canary
spec:
http:
- name: route
match:
paths:
- /*
backends:
- serviceName: api-v1
servicePort: 8080
weight: 95
- serviceName: api-v2
servicePort: 8080
weight: 5
Estos CRDs personalizados hicieron mucho más fácil configurar Ingress y aprovechar todas las capacidades de la puerta de enlace de API subyacente, pero a expensas de la portabilidad.
API Gateway de Kubernetes
La API Gateway es un nuevo objeto de Kubernetes que tiene como objetivo "arreglar" la API Ingress.
Toma inspiración de los CRDs personalizados desarrollados por los controladores de Ingress para agregar coincidencias basadas en encabezados HTTP, división de tráfico ponderada y otras características que requieren anotaciones propietarias personalizadas con la API Ingress.
El siguiente ejemplo muestra cómo configurar una implementación canaria con la API Gateway de Kubernetes:
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
name: api-canary
spec:
rules:
- backendRefs:
- name: api-v1
port: 8080
weight: 95
- name: api-v2
port: 8080
weight: 5
Cualquier controlador de Ingress (que implemente la API Gateway) puede ahora implementar esta configuración.
La API Gateway también hace muchas mejoras sobre la API Ingress, pero todavía está en fase alfa, y las implementaciones de la API Gateway están en constante cambio.
Mallas de servicios
Las puertas de enlace de API y las puertas de enlace de Kubernetes trabajan a través de los límites de las aplicaciones, resolviendo problemas de borde mientras abstraen tus APIs.
Las mallas de servicios resuelven un desafío diferente.
Una malla de servicios está más preocupada por la comunicación entre servicios (tráfico este-oeste) que por la comunicación entre servicios y clientes (tráfico norte-sur).
Normalmente, esto se logra desplegando proxies sidecar junto con las APIs/servicios.
Aquí, los proxies sidecar manejan la comunicación entre servicios en lugar de que el desarrollador tenga que codificar la lógica de red en los servicios.
Hay muchas mallas de servicios disponibles. Algunas de las más populares son:
- Istio: Hasta ahora, la malla de servicios más popular. Está construida sobre el proxy Envoy, que muchas mallas de servicios utilizan.
- Linkerd: Una malla de servicios ligera que utiliza linkerd2-proxy, escrito en Rust específicamente para Linkerd.
- Consul Connect: Una malla de servicios que enfatiza la seguridad y la observabilidad. Puede funcionar con un proxy integrado o con Envoy.
Nuevas ofertas de mallas de servicios como Cilium ofrecen alternativas a las mallas de servicios basadas en sidecar utilizando capacidades de red directamente desde el kernel a través de eBPF.
Una malla de servicios típica requiere 8 proxies para 8 servicios, mientras que las mallas de servicios basadas en eBPF como Cilium no lo hacen. Adaptado de Cilium Service Mesh – Everything You Need to Know.
Las mallas de servicios también tienen puertas de enlace de entrada/salida básicas para manejar el tráfico norte-sur hacia y desde los servicios. Las puertas de enlace de entrada son los puntos de entrada del tráfico externo a una malla de servicios, y las puertas de enlace de salida permiten que los servicios dentro de una malla accedan a servicios externos.
Apache APISIX también tiene una implementación de malla de servicios llamada Amesh. Funciona con el plano de control de Istio utilizando el protocolo xDS, reemplazando el proxy Envoy predeterminado en el sidecar.
Una malla de servicios te permite configurar implementaciones canarias. Por ejemplo, puedes dividir las solicitudes de un servicio entre dos versiones de otro servicio.
El siguiente ejemplo muestra cómo configurar una implementación canaria con la malla de servicios Istio:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: api-virtual-service
spec:
hosts:
- api
http:
- route:
- destination:
host: api
subset: v1
weight: 80
- destination:
host: api
subset: v2
weight: 20
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: api-destination-rule
spec:
host: api
subsets:
- name: v1
labels:
version: "1.0"
- name: v2
labels:
version: "2.0"
Estas configuraciones son específicas de Istio. Para cambiar a una malla de servicios diferente, debes crear una configuración diferente pero igualmente dependiente del proveedor.
La especificación Service Mesh Interface (SMI) se creó para resolver este problema de portabilidad.
La especificación SMI es un conjunto de CRDs de Kubernetes que un usuario de malla de servicios puede usar para definir aplicaciones sin vincularse a implementaciones de malla de servicios.
Un intento de estandarización solo funcionará si todos los proyectos están a bordo. Pero esto no sucedió con la especificación SMI, y solo unos pocos proyectos participaron activamente.
Más recientemente, el SIG Network de Kubernetes ha estado evolucionando la API Gateway para soportar mallas de servicios.
La iniciativa GAMMA (Gateway API for Mesh Management and Administration) es un grupo dedicado dentro del proyecto Gateway API con el objetivo de "investigar, diseñar y rastrear recursos, semántica y otros artefactos relacionados con la tecnología de malla de servicios y casos de uso."
La API Gateway es un paso natural después de la API Ingress, pero debemos esperar para ver cómo funcionará para las mallas de servicios. Istio ha anunciado su intención de usar la API Gateway como su API predeterminada para toda la gestión de tráfico y continúa impulsando el proyecto.
El siguiente ejemplo muestra cómo configurar una implementación canaria en Istio con la API Gateway. La idea subyacente es usar parentRefs para adjuntarse a otros servicios en lugar de la puerta de enlace:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: api-canary
spec:
parentRefs:
- kind: Service
name: api-a
port: 8080
rules:
- backendRefs:
- name: api-b-v1
port: 8080
weight: 95
- name: api-b-v2
port: 8080
weight: 5
Hay algunas preocupaciones de que el proyecto GAMMA podría sesgarse para servir las necesidades de un proyecto en particular en lugar de la comunidad en general, lo que eventualmente llevaría a otros proyectos a usar sus propias APIs, similar al escenario de CRDs personalizados después de la API Ingress de Kubernetes.
Pero el proyecto Gateway API ha sido el mejor intento de estandarizar la gestión de tráfico en mallas de servicios. El proyecto SMI también se unió a la iniciativa GAMMA con una visión compartida y ayudará a abogar por implementaciones consistentes de la API Gateway por parte de los proyectos de malla de servicios.
Otros proyectos como Flagger y Argo Rollouts también se han integrado con la API Gateway.
¿Qué deberías usar?
Solo hay una respuesta correcta a esta pregunta: "depende".
Si estás desarrollando APIs y necesitas autenticación, seguridad, enrutamiento o métricas, es mejor usar una puerta de enlace de API que construir esto por tu cuenta en tus APIs.
Si deseas hacer algo similar en un entorno de Kubernetes, deberías usar una puerta de enlace de Kubernetes en lugar de intentar hacer que tu puerta de enlace de API funcione en Kubernetes. Afortunadamente, muchas puertas de enlace de API también funcionan con configuraciones nativas de Kubernetes.
Pero a veces, las características ofrecidas por una puerta de enlace de API + controlador de Ingress pueden ser excesivas para un entorno de Kubernetes, y es posible que desees volver a una gestión de tráfico simple.
Las mallas de servicios, por otro lado, resuelven un conjunto de problemas completamente diferente. También traen sus propias puertas de enlace para manejar el tráfico norte-sur (generalmente suficiente), pero también te permiten usar tus propias puertas de enlace con más características.
La convergencia de la puerta de enlace de API y la malla de servicios a través de la API Gateway de Kubernetes debería facilitar que el desarrollador de aplicaciones se concentre en resolver problemas en lugar de preocuparse por la implementación subyacente.
Proyectos como Apache APISIX utilizan la misma tecnología para construir ofertas de puertas de enlace de API y mallas de servicios y se integran bien con estas especificaciones, incentivando elecciones neutrales de proveedor.
También es probable que no necesites ninguna de estas. Puede que ni siquiera necesites microservicios o una arquitectura distribuida, pero cuando las necesites, las puertas de enlace y las mallas pueden hacer tu vida mucho más fácil.