Kong loves Kubernetes

Kong es el api gateway con más estrellas del CNCF en este momento.

Kong tiene mucha funcionalidad, pero me voy a centrar solo en su estupenda integración con Kubernetes. ¿Te imaginas poder definir en tu helm chart que tal aplicación solo pueda recibir un número de peticiones por minuto desde una IP?

Aviso a navegantes: en este post no trato cosas básicas. Si no tienes unos conocimientos mínimos de lo que es un api gateway o kubernetes (ingress, services, controllers, crds, ...) podrás seguir este post, pero probablemente no sepas muy bien que estás haciendo.

Instalando kubernetes

Me hubiera gustado usar microk8s pero no me vale por el plugin de red que utiliza así que vamos a usar k3s.

Lo instalamos sin traefik, que es el ingress controller que viene con k3s (hay vida más allá de nginx ;-) ):

sudo su -
curl -sfL https://get.k3s.io/ | sh -s - --disable=traefik
mkdir .kube
cat /etc/rancher/k3s/k3s.yaml > .kube/config

NOTA: para desinstalarlo en cualquier momento puedes ejecutar k3s-uninstall.sh.

Recuerda que no debes tener cosas escuchando en los puertos 80 y el 443 de tu pc.

Instalando Kong

Ahora vamos a instalar el ingress de kong:

helm repo add kong https://charts.konghq.com
helm repo update
helm upgrade --install kong \
  --set ingressController.installCRDs=false \
  kong/kong

Cuenta hasta 100, te conectas a localhost y verás esta pantalla:

no Route matched with those values.

Instalando una aplicación

Vamos a instalar Wordpress, para variar:

helm repo add bitnami https://charts.bitnami.com/bitnami
helm upgrade --install wordpress \
  --set wordpressUsername=admin \
  --set wordpressPassword=admin \
  --set service.type=ClusterIP \
  --set ingress.enabled=true \
  --set ingress.hostname=localhost \
  bitnami/wordpress

Contamos hasta 100 y ...:

wordpress with kong

¿Ves la magia? No la ves, sino no sería magia, pero sin saber nada de Kong ya estás usando Kong y mágicamente se ha ejecutado este procedimiento.

Plugins

Los plugins se pueden utilizar para casi cualquier cosa que imagines, desde poner una contraseña a una url a modificar las cabeceras de las peticiones. Además, si quieres, te puedes programar tus propios plugins en lua.

Vamos a usar el plugin rate limiting para que solo se admitan 20 peticiones cada minuto.

Aplica este manifiesto:

echo """
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: rate-limiting-example
config:
  minute: 20
  policy: local
plugin: rate-limiting
""" | kubectl apply -f -

Reconfigura wordpress para usarlo agregando --set ingress.annotations."plugins\.konghq\.com"=rate-limiting-example tal que así:

helm upgrade --install wordpress \
  --set wordpressUsername=admin \
  --set wordpressPassword=admin \
  --set service.type=ClusterIP \
  --set ingress.enabled=true \
  --set ingress.hostname=localhost \
  --set ingress.annotations."plugins\.konghq\.com"=rate-limiting-example \
  bitnami/wordpress

Ahora dale al F5 muchas veces y verás el resultado:

API rate limit exceeded

¡Magia!

Derivadas

Esta integración con Kubernetes tiene una serie de derivadas muy interesantes en las que seguro ya estás pensando.

Gitops

Si usas una aproximación gitops para el despliegue de tus aplicaciones en Kubernetes (con Terraform, Flux, o lo que sea), puedes tratar la configuración de Kong junto al resto de configuraciones de la aplicación.

Transferencia de responsabilidades

Los equipos son los que mejor conocen (o deberían conocer) las necesidades y capacidades de sus servicios así que si tienen acceso a su namespace de Kubernetes pueden gestionar los plugins de Kong que necesiten.

No seamos inocentes ... probablemente ya lo hagan pero construyendo y manteniendo sus microservicios en diversos lenguajes dependiendo del equipo, lo que va en contra de cualquier criterio de normalización en una compañía.

Pipelines más sencillas

Si prefieres no usar gitops (¿porqué?) cambiamos llamadas al api por un "kubectl apply" en los pasos de las pipelines.

Integración en helm charts

Imagina que tienes un helm chart con el que despliegas los microservicios de tu equipo.

Ahora imagina que agregas en el values.yaml algo así:

ingress:
  ## Configure kong plugins
  ##
  #plugins:
  #  - name: rate-limiting
  #    config:
  #      minute: 10
  #      limit_by: consumer
  #      policy: local
  plugins: []

Y que agregas una plantilla tal que así:

{{- range .Values.ingress.plugins }}
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: {{ .name }}
config: {{ toYaml .config | nindent 2 }}
plugin: {{ .name }}
{{- end }}

Y ya puestos, las anotaciones en el ingress de esta forma:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
...
  annotations:
...
    konghq.com/plugins: "{{- range .Values.ingress.plugins }}{{ .name }},{{- end }}"

¡Ya tienes Kong integrado en tus Helm Charts!

Base de datos

Si haces un kubectl get po verás con asombro que ¡no hay base de datos! así que ¿donde se guarda la configuración de Kong? La configuración se guarda en el etcd de Kubernetes así que no necesitas gestionar volúmenes persistentes ni bases de datos.

Por desgracia no todos los plugins son compatibles con este tipo de despliegue así que en muchas ocasiones no te quedará más remedio que usar una base de datos adicional.

En caso de usar un despliegue con base de datos podrás seguir usando CRDs tal como he descrito arriba peeeeeeero, si alguien toca a mano algo en la base de datos que entre en conflicto con los CRDs, gana lo que haya en la base de datos.

Arquitectura

Me he centrado en esta arquitectura porque es la que me conviene para mostrar lo que quiero, pero podemos mantener el ingress/rutas de tu Kubernetes/OpenShift y usar Kong de esta forma pasándole un subdominio para que lo gestione, o bien podemos no usar la integración con Kubernetes y tener un kong por namespace.

O a lo mejor te interesa tener un Kong central para temas de autenticación con base de datos y luego un kong dbless por cluster de Kubernetes para que los equipos gestionen sus cosas de forma autónoma.

En este post no me meto en ese tipo de decisiones de arquitectura pero a lo mejor esta información de despliegue junto a la política de tu empresa pueda ayudarte a tomar la mejor decisión.

Konga

Si eres más de interfaces gráficas y no te quieres gastar dinero en la versión Enterprise, puedes usar konga.