Cómo crear una puerta de enlace API utilizando Ambassador en Kubernetes

API Gateway usando Ambassador en Kubernetes

API Gateway es un aspecto importante en la implementación de Kubernetes para sus servicios. Actúa como un único punto de entrada y puede ayudar a simplificar muchas tareas, como el descubrimiento de servicios, el rastreo distribuido, el enrutamiento y la limitación de velocidad. Puede ofrecer una gran flexibilidad y una mejor configuración para sus servicios.

Envoy es una de las puertas de enlace API muy populares actualmente disponibles que puede manejar cargas extensas. Con Kubernetes, Ambassador es la forma más popular y eficiente de usar Envoy.

Hoy, lo guiaré a través de los pasos detallados para implementar Ambassador en un clúster de Kubernetes que implementamos en mi publicación anterior, y configurarlo para usar el equilibrador de carga de AWS para el tráfico entrante y enrutarlo a varios servicios basados ​​en reglas.

Esta publicación se publicó originalmente en mi blog https://krish512.com/create-api-gateway-ambassador-kubernetes/

Prerrequisitos

Antes de comenzar esta guía, necesitará lo siguiente:

  • Clúster de Kubernetes según mi publicación anterior
  • Certificado SSL utilizando ACM para Dominio
  • Máquina Linux como servidor de implementación, preferiblemente Ubuntu 16.04 o posterior

Paso 1 - Implemente el Embajador en el Clúster de Kubernetes

Implementar Ambassador es más fácil con Kubernetes, ya que la configuración de YAML está disponible en el sitio de Ambassador. Si se ha referido a mi artículo anterior sobre la creación de un clúster de Kubernetes en AWS, entonces ya tiene RBAC habilitado.

Consulte la documentación oficial del Embajador en caso de que no tenga habilitado RBAC o algún problema con el comando anterior.

Inicie sesión en su servidor de implementación y ejecute el siguiente comando kubectl,

kubectl apply -f https://getambassador.io/yaml/ambassador/ambassador-rbac.yaml

También puedes usar Helm para desplegar Ambassador.

En primer lugar, agregue el repositorio Helm como lo mantiene Datawire (equipo de embajadores)

$ helm repo add datawire https://www.getambassador.io

Ahora despliegue Embajador con Helm como,

$ helm upgrade -install -wait ambassador datawire / ambassador

Esto llevará algún tiempo y creará la implementación de Ambassador y los pods en su espacio de nombres predeterminado. Verifique si los pods se crearon con el siguiente comando,

$ kubectl consigue vainas

Esperar siguiente salida

NOMBRE LISTO ESTADO RESTAURACIÓN EDAD
ambassador-6dfd64dd49-dgmcf 2/2 Ejecutando 0 1d
ambassador-6dfd64dd49-mz5bf 2/2 Ejecutando 0 1d
ambassador-6dfd64dd49-xd6g4 2/2 Ejecutando 0 1d

Si puede ver 3 pods de Ambassador ejecutándose, entonces ha configurado con éxito Ambassador. Pasemos al siguiente paso, donde crearemos un punto final de equilibrador de carga para exponer nuestra API Gateway.

Paso 2: crear el servicio de embajador y el equilibrador de carga

Todo el tráfico entrante a nuestros servicios de Kubernetes debe enrutarse a través de nuestro API Gateway Ambassador.

Ambassador utiliza un equilibrador de carga de AWS para recibir todo el tráfico y enrutarlos al servicio Ambassador para poder aplicar reglas y enrutarlos más a los servicios configurados.

Antes de crear nuestro equilibrador de carga, tengamos un certificado HTTPS listo con el servicio AWS ACM para nuestro dominio krish512.com y el dominio secundario * .dev.krish512.com. Puede agregar hasta 8 dominios secundarios según sus requisitos.

Creemos ahora un servicio para el Embajador. Cree un archivo como ambassador-service.yaml

$ touch ambassador-service.yaml

Ahora usando VIM o nano editor, abra el archivo e inserte el siguiente contenido yaml,

apiVersion: v1
tipo: servicio
metadatos:
  etiquetas:
  servicio: embajador
    nombre: embajador
  anotaciones:
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn: aws: acm: ap-south-1: 123403005789: certificado / 1a2b3c54-b001-12fg-9h33-f98f7f65432d"
    service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "verdadero"
    service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
    service.beta.kubernetes.io/aws-load-balancer-extra-security-groups: "sg-01a889992221b2cde"
    getambassador.io/config: |
      ---
      apiVersion: embajador / v1
      tipo: Módulo
      nombre: tls
      config:
        servidor:
          habilitado: verdadero
          redirect_cleartext_from: 80
especulación:
  loadBalancerSourceRanges:
  - 0.0.0.0/0
  tipo: LoadBalancer
  puertos:
  - nombre: embajador-http
    puerto: 80
    targetPort: 80
  - nombre: embajador-https
    puerto: 443
    targetPort: 80
  selector:
    servicio: embajador

En el yaml anterior, la sección de anotaciones especifica nuestros detalles del equilibrador de carga. Como AWS ALB no es compatible con Kubernetes actualmente, esto creará un equilibrador de carga clásico para Ambassador.

  • El valor del campo service.beta.kubernetes.io/aws-loadbalancer-ssl-cert es el ARN de nuestro certificado de AWS ACM
  • El valor para service.beta.kubernetes.io/aws-loadbalancer-ssl-ports establece nuestro puerto HTTPS para equilibrador de carga
  • La clave service.beta.kubernetes.io/aws-loadbalancer-extra-security-groups es opcional y nos permite agregar reglas de grupo de seguridad adicionales y adjuntarlas a nuestro equilibrador de carga especificando la identificación del grupo de seguridad como su valor.

En la sección de especificaciones, loadBalancerSourceRanges es nuevamente una clave opcional utilizada para restringir el acceso al equilibrador de carga utilizando su grupo de seguridad predeterminado. Lo hemos mantenido abierto, esto es solo para fines de demostración. Puede eliminar este campo o cambiar el valor según sus requisitos.

Permítanos crear el servicio ahora.

$ kubectl apply -f ambassador-service.yaml

Esto debería crear inmediatamente un servicio e iniciar una creación de equilibrador de carga en su consola AWS EC2.

Para evitar especificar la asignación de DNS para cada subdominio, apunte * .dev.krish512.com a este equilibrador de carga en el servicio AWS Route53.

Paso 3: Implemente servicios y rutas con Ambassador

Para probar nuestra configuración de Ambassador y sus características, implementaremos 2 servicios en Kubernetes y enrutaremos el tráfico hacia ellos a través de Ambassador mediante anotaciones.

Primero, creemos un espacio de nombres de desarrollo para nuestros nuevos servicios.

{
  "kind": "Espacio de nombres",
  "apiVersion": "v1",
  "metadatos": {
    "nombre": "desarrollo",
    "etiquetas": {
      "nombre": "desarrollo"
    }
  }
}

Guarde el json anterior como development-namespace.json y ejecute el siguiente comando kubectl para crear un espacio de nombres

$ kubectl create -f development-namespace.json

Ahora permítanos crear un pod httpd usando una implementación y exponerlo al embajador usando un servicio.

---
apiVersion: v1
tipo: servicio
metadatos:
  nombre: httpd-service
  espacio de nombres: desarrollo
  anotaciones:
    getambassador.io/config: |
      ---
      apiVersion: embajador / v1
      tipo: mapeo
      nombre: httpd-service_mapping
      host: service1.dev.krish512.com
      prefijo: /
      servicio: httpd-service.development: 80
especulación:
  selector:
    aplicación: httpd
    entorno: desarrollo
    rol: web
  puertos:
  - protocolo: TCP
    puerto: 80
---
apiVersion: extensiones / v1beta1
tipo: Despliegue
metadatos:
  nombre: httpd
  espacio de nombres: desarrollo
especulación:
  réplicas: 1
  estrategia:
    tipo: RollingUpdate
  modelo:
    metadatos:
      etiquetas:
        aplicación: httpd
        entorno: desarrollo
        rol: web
    especulación:
      contenedores:
      - nombre: httpd
        imagen: "httpd"
        puertos:
        - containerPort: 80

Guarde el yaml anterior como httpd.yaml.

En el yaml anterior, hemos creado una anotación getambassador.io/config que se utiliza para la configuración del embajador. Estas anotaciones se pueden configurar en el servicio Ambassador si desea administrarlas de forma centralizada.

En esta anotación, hemos asignado la configuración del embajador a un servicio y hemos especificado el nombre como httpd-service_mapping.

Para fines de enrutamiento, le hemos pedido al Embajador que enrute todas las solicitudes que vienen para el servicio host1.dev.krish512.com con ruta base / al servicio httpd-service.development: 80 donde httpd-service es el nombre del servicio, desarrollo es espacio de nombres y 80 es puerto expuesto para el servicio.

Creemos este servicio httpd en Kubernetes con el siguiente comando kubectl,

$ kubectl apply -f httpd.yaml

Esto debería tomar un minuto para crear el pod para nuestra implementación y estar disponible. Verifique si el pod está disponible usando lo siguiente,

$ kubectl get pods -n desarrollo

Esperar siguiente salida,

NOMBRE LISTO ESTADO RESTAURACIÓN EDAD
httpd-56ddd7c88b-ddksp 1/1 Ejecutando 0 28m

Ahora vaya a su navegador e ingrese la URL https://service1.dev.krish512.com, debería poder ver la salida como se muestra a continuación

Página predeterminada del servidor web HTTP

Del mismo modo, creemos un pod Nginx usando una implementación y expongamos al embajador usando un servicio como,

---
apiVersion: v1
tipo: servicio
metadatos:
  nombre: nginx-service
  espacio de nombres: desarrollo
  anotaciones:
    getambassador.io/config: |
      ---
      apiVersion: embajador / v1
      tipo: mapeo
      nombre: nginx-service_mapping
      host: service2.dev.krish512.com
      prefijo: / nginx
      servicio: nginx-service.development: 80
especulación:
  selector:
    aplicación: nginx
    entorno: desarrollo
    rol: web
  puertos:
  - protocolo: TCP
    puerto: 80
---
apiVersion: extensiones / v1beta1
tipo: Despliegue
metadatos:
  nombre: nginx
  espacio de nombres: desarrollo
especulación:
  réplicas: 1
  estrategia:
    tipo: RollingUpdate
  modelo:
    metadatos:
      etiquetas:
        aplicación: nginx
        entorno: desarrollo
        rol: web
    especulación:
      contenedores:
      - nombre: nginx
        imagen: "nginx"
        puertos:
        - containerPort: 80

Guarde el yaml anterior como nginx.yaml y ejecute,

$ kubectl apply -f nginx.yaml

Esto debería tomar nuevamente un minuto para crear el pod. Verifique si el pod se creó correctamente utilizando lo siguiente,

$ kubectl get pods -n desarrollo

Esperar siguiente salida,

NOMBRE LISTO ESTADO RESTAURACIÓN EDAD
httpd-56ddd7c88b-ddksp 1/1 Ejecutando 0 10m
nginx-6455785f94-z992f 1/1 Corriendo 0 1m

En este yaml, hemos señalado el dominio service2.dev.krish512.com con el servicio route / nginx a Nginx.

En su navegador, pruebe la url https://service2.dev.krish512.com/nginx y espere la siguiente pantalla,

Página predeterminada del servidor web Nginx

Intente agregar más pods y exponerlos utilizando el servicio con anotaciones Ambassador para poder enrutarlos y administrarlos. Consulte la documentación del Embajador para obtener más opciones de configuración.

Pasos Adicionales

Ambassador tiene una interfaz de usuario de diagnóstico que se puede utilizar con fines de depuración y diagnóstico. Todos los pods Ambassador exponen esta IU en el puerto 8877. Podemos crear un servicio para exponer esta IU que se ejecuta en el puerto 8877 de pods y podemos asignarla a un dominio ambassador.dev.krish512.com

Creemos un servicio para exponer la interfaz de usuario de diagnóstico de la siguiente manera:

---
apiVersion: v1
tipo: servicio
metadatos:
  nombre: embajador-diagnóstico
  anotaciones:
    getambassador.io/config: |
      ---
      apiVersion: embajador / v1
      tipo: mapeo
      nombre: mapeo-mapeo-diagnóstico
      anfitrión: ambassador.dev.krish512.com
      timeout_ms: 30000
      prefijo: /
      servicio: embajador-diagnóstico: 8877
especulación:
  selector:
    servicio: embajador
  puertos:
  - protocolo: TCP
    puerto: 8877

Ahora solo visite https://ambassador.dev.krish512.com/ y debería poder ver algo como esta interfaz de usuario:

Conclusión

Creamos una API Gateway para nuestros servicios alojados en Kubernetes. Con esto, podemos enrutar el tráfico a un servicio específico basado en encabezados de solicitud como nombre de host, URI, etc. Lo utilizaremos en el futuro para exponer más servicios a través de nuestra puerta de enlace API Ambassador.

Únete a nuestra comunidad Slack y lee nuestros temas semanales de Fauno ⬇

Si esta publicación fue útil, haga clic en el botón de aplaudir below a continuación para mostrar su apoyo al autor. ⬇