Home Artículos técnicos Implementación de Edgio Delivery CDN como proveedor de entradas en su clúster de Kubernetes
Applications

Implementación de Edgio Delivery CDN como proveedor de entradas en su clúster de Kubernetes

About The Author

Outline

Prólogo

El siguiente es un ejemplo de integración de Kubernetes con el servicio CDN de Edgio Delivery para profesionales experimentados de Kubernetes. Asume un nivel de conocimiento en Kubernetes y conocimiento de protocolos estándar de Internet como TCP, DNS y HTTP/HTTPS. El objetivo final es demostrar una manera de hacer que el servicio CDN de Edgio Delivery aparezca como entrada estándar. El usuario de Kubernetes puede mantener la configuración de entrada en sistemas familiares como Portainer o Terraform.

Kubernetes

Kubernetes.io define Kubernetes como “un sistema de código abierto para automatizar el despliegue, escalado y gestión de aplicaciones en contenedores”. Hay varias maneras de traer un clúster. La forma más rápida y sencilla es aprovechar uno de los muchos proveedores de nube que permiten implementaciones de “un solo clic”.

Los clusters de Kubernetes contienen muchas partes. En la demo, nos centraremos en un subconjunto del total.

Piezas de Kubernetes

  • Nodo: Máquina o VM que aloja las cargas de trabajo y los servicios.
  • Carga de trabajo: Aplicación simple o compleja
  • Pod: Contenedores en los que se está ejecutando el software de la aplicación. Uno o más pods componen una carga de trabajo.
  • Servicio: Un mecanismo que expone una carga de trabajo a otras cargas de trabajo o entradas
  • Ingreso: Un mecanismo para exponer los servicios al mundo exterior

Edgio

Edgio hace que la vida conectada sea más rápida, segura y sencilla de administrar al impulsar una velocidad, seguridad y simplicidad inigualables en el perímetro con nuestras soluciones de entrega, aplicaciones y streaming perfectamente integradas. Nuestra tecnología a escala mundial y nuestros servicios expertos impulsan las principales marcas del mundo con la capacidad de ofrecer la educación, entretenimiento, eventos y aplicaciones más rápidas, dinámicas y sin fricciones a cada usuario. Dedicado a proporcionar una atención al cliente sin igual y extender valor en cada paso del camino, Edgio es un socio de elección, impulsando el tráfico de Internet en todo el mundo para apoyar los programas, películas, deportes, juegos y música más populares, y sitios web de carga instantánea.

Arquitectura

Edgio Delivery CDN

Para esta demostración, utilizamos el SDK de Edgio python en GitHub – llnw/llnw-sdk-python: Limelight Networks Python SDK. La configuración básica se mantendrá simple.

Al configurar la CDN, se necesitan los siguientes datos (distintos de la autenticación).

  • Shortname: Un identificador único dentro de Edgio Delivery CDN que contiene reglas de CDN.
  • Published hostname: El nombre de host que se enfrenta a Internet desde la CDN, en el caso de esta demo, el nombre de host cstradtman.s.llnwi.net fue previamente configurado.
  • Ruta de URL publicada: La ruta asignada a la regla específica en cuestión.
  • Nombre de host de origen: El nombre de host del origen. En este caso, un registro round-robin apunta al clúster de Kubernetes.
  • Ruta de URL de origen: La ruta de destino asociada con el nombre de host. En este caso, estará en blanco ya que lo describimos más adelante en este documento. En esta demo, las cargas de trabajo se diferenciarán por número de puerto y no por ruta.

DNS

La demo utiliza la API de Vultr DNS. Configurar la CDN usando direcciones IP como orígenes no es una buena práctica. La demo utiliza una API para crear o modificar un registro round-robin que apunta a los nodos del clúster.

Grupo temático

La demo está en Vultr en un clúster de tres nodos.

Espacios de nombres

La demo existirá bajo el espacio de nombres predeterminado ya que es lo único que se ejecuta en este clúster

Nodos

  • Clúster VKE – 3 nodos con cada uno
    • 4G RAM
    • Disco 80G
    • 2 vCPU
    • 1 red G

Cargas de trabajo

La carga de trabajo es un simple programa de Python que devuelve información básica sobre la conexión HTTP. Implementamos esta demo en línea, que no es un método de implementación típico. Sin embargo, permite que la demo sea totalmente autónoma en lugar de tener dependencias externas para construir los contenedores y almacenarlos. El código fuente está en el Apéndice 1. El código de Python real está en cursiva, y el código YAML que describe el despliegue no lo está. La carga de trabajo utiliza el puerto TCP 8000.

Servicios

Hay varios tipos de servicios disponibles. Estamos utilizando el tipo de servicio “NodePort”. Expone el servicio en las direcciones IP externas del clúster en un número de puerto alto seleccionado aleatoriamente. Kubernetes se encarga de la conexión a un nodo donde se ejecuta la carga de trabajo.

Entrada

Kubernetes Ingreso es un objeto de software que describe el comportamiento de una colección de recursos que hacen que un servicio de Kubernetes esté disponible fuera del clúster.

Un controlador Ingress combina software y/o hardware que crea instancias del objeto de software Ingress.

Una CDN es un proxy inverso distribuido rico en características, además de la función de proxy inverso, las CDN suelen tener algoritmos de caché flexibles, diversidad geográfica, características de seguridad (ACL (GEO, método, regex), firewalls de aplicaciones web, marcas de agua y otras características más avanzadas que no se encuentran en proxies inversos simples.

Las API para la monitorización de objetos de Kubernetes están bien definidas, y una serie de proxies inversos HTTP y balanceadores de carga se han ampliado para funcionar como controladores Ingress. Por ejemplo, NGINX y HAProxy son proxies de la vieja escuela que se han extendido para funcionar como controladores de ingreso y otros como Traefik e Itsio se desarrollaron en paralelo a Kubernetes. Una CDN es una progresión natural de proxies inversos simples. En el caso de esta demo, crearemos un controlador de entrada personalizado que controla Edgio Delivery CDN. Los datos normalmente requeridos para describir una Ingress es

  • Public Hostname: El nombre de host en el que estará disponible el servicio Kubernetes
  • Ruta pública: La ruta asociada al nombre de host público en la que estarán disponibles los servicios de Kubernetes
  • Nombre del servicio de backend: Nombre del servicio definido por una estrofa de servicios de Kubernetes
  • Puerto de backend: Un nombre que coincide con la descripción del puerto en la descripción del servicio

Edgio Delivery Mappings de activos CDN:

Kubernetes

Edgio Delivery CDN

Nombre de host público

Nombre de host publicado

Vía pública

Ruta URL publicada

Nombre del servicio de backend

Único dentro del clúster de Kubernetes

No conocido/disponible para el mundo exterior

Nombre de host fuente

Nombre de dominio totalmente cualificado

En realidad no uno a uno

La lógica detrás de esto es:

  • Escuche el evento de ingreso de espacio de nombres desde el clúster
  • Si el tipo de evento es “Añadido”.
    • Obtenga la dirección IP de los nodos en el clúster
    • Crear registro DNS en vultr
    • Cree reglas de CDN en Edgio CDN que apunten hacia los registros DNS creados y el puerto asignado por el servicio NodePort.
  • Si el tipo de evento es “Modificado”.
    • Encuentre reglas de CDN en Edgio CDN que coincidan con la entrada existente
    • Modifique las reglas en Edgio CDN para reflejar nuevos datos en el evento
  • Si el tipo de evento es “Deleted”.
    • Encuentra reglas de CDN en Edgio CDN que coincidan con la entrada eliminada
    • Eliminar registros DNS en Vultr asociados con esta entrada
    • Elimine las reglas de CDN en Edgio que coinciden con la entrada eliminada

Configuración

Objetos

Los objetos de Kubernetes se describen en archivos YAML. En Kubernetes, cada configuración es un objeto. Puede colocar todas las configuraciones de implementación en un solo archivo. Es una práctica común dividirlos en función de qué parte del despliegue describen.

Despliegue

En el Apéndice 1, hay un archivo YAML grande que es una combinación de código Python y YAML. Todo después de “spec.template.spec.containers.command” es el código de Python que se convierte en un contenedor durante el despliegue. Desde el punto de vista del objeto Kubernetes las líneas que nos son importantes para la demo son:

  • Kind: Deployment – Describe el objeto como un Deployment
  • Metadata.name: Nombre es usado por el objeto service para crear el vínculo entre los dos.
  • Spec.selector.matchlabels.app: indica a qué pods se aplicará el despliegue.
  • Spec.template.spec.containers.image: Apunta a la imagen oficial de python 3 del hub docker
  • Spec.template.spec.containers.ports.name: Una etiqueta para el puerto a ser referenciado en el servicio de otros objetos en este caso
  • Spec.template.spec.containers.ports.containerport: Enumera el puerto TCP expuesto desde el contenedor en ejecución

Servicio

  • Kind: Deployment – Describe el objeto como un Deployment
  • Metadata.name: El nombre es usado por el objeto de ingreso para crear el enlace entre los dos.
  • Spec.selector.app: apunta al nombre del despliegue: Pywai-inline-service como se nombra en el objeto de despliegue.
  • Spec.selector.type: NodePort Esto define este servicio como el tipo NodePort como se describió anteriormente
  • Spec.ports.name: La etiqueta para el puerto a ser referenciado por otros objetos (entrada en este caso)
  • Spec.ports.protocol: define el protocolo IP en uso – TCP
  • Spec.ports.port: Define el puerto expuesto por este servicio
  • Spec.ports.targetPort: Apunta al puerto expuesto por la implementación – pywai-inline-deployment en este caso

Entrada

En el Apéndice 3, verá el archivo YAML que describe el objeto Kubernetes para el controlador Edgio Ingreso. Los objetos que deben interesarse son:

  • Kind: Ingreso – Esto le dice a Kubernetes que es un objeto Ingress
  • Medatdata.name – Todo en Kubernetes debe tener un nombre
  • Metadata.labels.cdn – Esta etiqueta se utiliza para indicar al controlador de entrada que este objeto es para el controlador de entrada de edgio
  • Spec.rules.host – nombre de host público para exponer el servicio.
  • Spec.rules.http.paths.path – Ruta asociada al servicio.
  • Spec.rules.http.paths.backend.service.name – etiqueta del servicio a exponer
  • Spec.rules.http.paths.backend.service.port.name – Etiqueta de puerto del servicio a exponer

Configuración de mapas

Secretos

Kubernetes tiene un concepto incorporado de secretos para el almacenamiento de datos sensibles. Esta demostración aprovecha esto para los nombres de usuario y las claves compartidas tanto para Edgio SDK como para la API de Vultr DNS

Ejemplos de código

El código para esta demostración está incluido en los repos git

Futuras adiciones y mejoras al diseño actual

En una publicación futura, mostraremos cómo aprovechar otras soluciones de Edgio, por ejemplo, aplicaciones. Podríamos usar el clúster de Kubernetes como una forma de aprovechar y sincronizar configuraciones entre múltiples ofertas de CDN de Edgio para diferentes flujos de trabajo.

Apéndice 1 – pywai-inline-deployment.yaml

ApiVersion: Apps/v1

Tipo: Despliegue

metadatos:

nombre: pywai-inline-deployment

especificaciones:

selector:

MatchLabels:

aplicación: pywai-inline-deployment

réplicas: 1

plantilla:

metadatos:

etiquetas:

aplicación: pywai-inline-deployment

especificaciones:

contenedores:

– nombre: python

imagen: python:3

orden:

– /bin/sh

– “-c”

– |

CAT > /test.py <<EOF

#!/usr/bin/env python3

“””

Servidor HTTP muy simple en python para las solicitudes de registro

Uso::

./server.py [<puerto>]

“””

Desde http.server importa BaseHTTPRequestHandler, HTTPServer

registro de importación

importar pprint

Clase S(BaseHTTPRequestHandler):

def _set_response(self):

self.send_response(200)

self.send_header(‘Content-type’, «text/html»)

self.end_headers()

def do_GET(self):

logging.info(“GET Request,\nPath: %S\nHeaders:\n%s\n”, str(self.path), str(pprint.pformat(self.headers))

self._set_response()

headerinfo=pprint.pformat(self.headers.items())

clientinfo=pprint.pformat(self.client_address)

lineinfo=pprint.pformat(self.requestline)

versioninfo=pprint.pformat(self.request_version)

self.wfile.write(“<pre> {} </pre>”.format(headerinfo).encode(‘utf-8’))

self.wfile.write(“<pre> {} </pre>”.format(clientinfo).encode(‘utf-8’))

self.wfile.write(“<pre> {} </pre>”.format(lineinfo).encode(‘utf-8’))

self.wfile.write(“<pre> {} </pre>”.format(versioninfo).encode(‘utf-8’))

def run(server_class=HTTPServer, handler_class=S, port=8080):

Logging.basicConfig(level=logging.INFO)

server_address = (”, puerto)

httpd = server_class(server_address, handler_class)

logging.info(‘Starting httpd…\n’)

pruebe:

httpd.serve_forever()

Excepto KeyboardInterrupt:

pase

httpd.server_close()

logging.info(‘Stopping httpd…\n’)

si __name__ == ‘__main___’:

desde sys import argv

si len(argv) == 2:

run(port=int(argv[1]))

de lo contrario:

run()

EOF

exec python /test.py 8000

puertos:

– nombre: http

ContainerPort: 8000

Apéndice 2 – pywai-inline-service.yaml

ApiVersion: v1

Tipo: Servicio

metadatos:

nombre: pywai-inline-service

especificaciones:

selector:

aplicación: pywai-inline-deployment

Tipo: NodePort

puertos:

– nombre: http

protocolo: TCP

puerto: 80

Puerto de destino: 8000

Apéndice 3 – pywai-edgio-ingress.yaml

ApiVersion: Networking.k8s.io/v1

Clase: Ingreso

metadatos:

nombre: externo-pywai-inline-ingress

anotaciones:

kubernetes.io/ingress.class: edgio

etiquetas:

cdn: edgio

especificaciones:

normas:

– Host: <Introduzca el nombre corto único> .s.llnwi.net

http:

rutas:

– ruta: /fred

PathType: Exacto

backend:

servicio:

nombre: external-pywai-inline-service

puerto:

nombre: pywai-port