¿Qué es Kubernetes? Una guía para la contenedorización y el despliegue

Publicado: 2022-03-11

Hace poco, usamos la aplicación web monolítica: enormes bases de código que crecieron en nuevas funciones y características hasta que se convirtieron en gigantes enormes, lentos y difíciles de administrar. Ahora, un número cada vez mayor de desarrolladores, arquitectos y expertos en DevOps están llegando a la opinión de que es mejor usar microservicios que un monolito gigante. Por lo general, usar una arquitectura basada en microservicios significa dividir su monolito en al menos dos aplicaciones: la aplicación de front-end y una aplicación de back-end (la API). Tras la decisión de utilizar microservicios, surge una pregunta: ¿En qué entorno es mejor ejecutar microservicios? ¿Qué debo elegir para que mi servicio sea estable y fácil de administrar e implementar? La respuesta corta es: ¡Usa Docker!

En este artículo, le presentaré los contenedores, le explicaré Kubernetes y le enseñaré cómo contener e implementar una aplicación en un clúster de Kubernetes mediante CircleCI.

¿Estibador? ¿Qué es Docker?

Docker es una herramienta diseñada para facilitar DevOps (y su vida). Con Docker, un desarrollador puede crear, implementar y ejecutar aplicaciones en contenedores . Los contenedores permiten a un desarrollador empaquetar una aplicación con todas las partes que necesita, como bibliotecas y otras dependencias, y enviarlo todo como un solo paquete.

Comparación de aplicaciones implementadas en un host frente a una aplicación empaquetada en un contenedor

Comparación de aplicaciones implementadas en un host frente a una aplicación empaquetada en un contenedor

Mediante el uso de contenedores, los desarrolladores pueden (re)implementar fácilmente una imagen en cualquier sistema operativo. Simplemente instale Docker, ejecute un comando y su aplicación estará lista y funcionando. Ah, y no se preocupe por cualquier inconsistencia con la nueva versión de las bibliotecas en el sistema operativo anfitrión. Además, puede lanzar más contenedores en el mismo host, ¿será la misma aplicación u otra? No importa.

Parece que Docker es una herramienta increíble. Pero, ¿cómo y dónde debo lanzar contenedores?

Hay muchas opciones sobre cómo y dónde ejecutar contenedores: AWS Elastic Container Service (AWS Fargate o una instancia reservada con escalado automático horizontal y vertical); una instancia en la nube con una imagen de Docker predefinida en Azure o Google Cloud (con plantillas, grupos de instancias y escalado automático); en su propio servidor con Docker; o, por supuesto, ¡Kubernetes! Kubernetes fue creado especialmente para virtualización y contenedores por ingenieros de Google en 2014.

¿Kubernetes? ¿Qué es eso?

Kubernetes es un sistema de código abierto que le permite ejecutar contenedores, administrarlos, automatizar implementaciones, escalar implementaciones, crear y configurar ingresos, implementar aplicaciones con estado o sin estado, y muchas otras cosas. Básicamente, puede lanzar una o más instancias e instalar Kubernetes para operarlas como un clúster de Kubernetes. Luego, obtenga el extremo de la API del clúster de Kubernetes, configure kubectl (una herramienta para administrar clústeres de Kubernetes) y Kubernetes estará listo para funcionar.

Entonces, ¿por qué debería usarlo?

Con Kubernetes, puede utilizar los recursos computacionales al máximo. Con Kubernetes, serás el capitán de tu barco (infraestructura) con Kubernetes llenando tus velas. Con Kubernetes, su servicio será HA. Y lo más importante, con Kubernetes, ahorrará una buena cantidad de dinero.

¡Parece prometedor! ¡Especialmente si ahorrará dinero! ¡Hablemos más de eso!

Kubernetes está ganando popularidad día tras día. Profundicemos e investiguemos qué hay debajo del capó.

Bajo el capó: ¿Qué es Kubernetes?

¿Qué es Kubernetes? Los componentes que conforman Kubernetes bajo el capó

Los componentes que forman Kubernetes

Kubernetes es el nombre de todo el sistema, pero al igual que su automóvil, hay muchas piezas pequeñas que funcionan juntas en perfecta armonía para que Kubernetes funcione. Aprendamos cuáles son.

Master Node: un panel de control para todo el clúster de Kubernetes. Los componentes del maestro se pueden ejecutar en cualquier nodo del clúster. Los componentes clave son:

  • Servidor API: El punto de entrada para todos los comandos REST, el único componente del Master Node al que puede acceder el usuario.
  • Almacén de datos: almacenamiento de clave-valor fuerte, coherente y de alta disponibilidad utilizado por el clúster de Kubernetes.
  • Programador: observa los pods recién creados y los asigna a los nodos. La implementación de pods y servicios en los nodos ocurre debido al programador.
  • Administrador de controladores: ejecuta todos los controladores que manejan tareas de rutina en el clúster.
  • Nodos de trabajo: agente de nodo principal, también llamado nodo de minion. Las vainas se ejecutan aquí. Los nodos trabajadores contienen todos los servicios necesarios para administrar la red entre los contenedores, comunicarse con el nodo maestro y asignar recursos a los contenedores programados.
  • Docker: se ejecuta en cada nodo trabajador y descarga imágenes y contenedores de inicio.
  • Kubelet: supervisa el estado de un pod y garantiza que los contenedores estén en funcionamiento. También se comunica con el almacén de datos, obteniendo información sobre los servicios y escribiendo detalles sobre los recién creados.
  • Kube-proxy: un proxy de red y un equilibrador de carga para un servicio en un solo nodo trabajador. Es responsable del enrutamiento del tráfico.
  • Kubectl: una herramienta CLI para que los usuarios se comuniquen con el servidor API de Kubernetes.

¿Qué son los pods y los servicios?

Los pods son la unidad más pequeña del clúster de Kubernetes, es como un ladrillo en la pared de un edificio enorme. Un pod es un conjunto de contenedores que deben ejecutarse juntos y pueden compartir recursos (espacios de nombres de Linux, cgroups, direcciones IP). Las vainas no están destinadas a vivir mucho tiempo.

Los servicios son una abstracción en la parte superior de una serie de pods, que normalmente requieren un proxy en la parte superior para que otros servicios se comuniquen con él a través de una dirección IP virtual.

Ejemplo de implementación simple

Cómo interactúan las diferentes partes interesadas con una aplicación con tecnología de Kubernetes

Cómo interactúan las diferentes partes interesadas con una aplicación con tecnología de Kubernetes

Usaré una aplicación sencilla de Ruby on Rails y GKE como plataforma para ejecutar Kubernetes. De hecho, puedes usar Kubernetes en AWS o Azure o incluso crear un clúster en tu propio hardware o ejecutar Kubernetes localmente usando minikube , todas las opciones que encontrarás en esta página.

Los archivos de origen de esta aplicación se pueden encontrar en este repositorio de GitHub.

Para crear una nueva aplicación de Rails, ejecute:

 rails new blog

Para configurar la conexión MySQL para producción en el config/database.yml file :

 production: adapter: mysql2 encoding: utf8 pool: 5 port: 3306 database: <%= ENV['DATABASE_NAME'] %> host: 127.0.0.1 username: <%= ENV['DATABASE_USERNAME'] %> password: <%= ENV['DATABASE_PASSWORD'] %>

Para crear un modelo de artículo, controlador, vistas y migración, ejecute:

 rails g scaffold Article title:string description:text

Para agregar gemas al Gemfile:

 gem 'mysql2', '< 0.6.0', '>= 0.4.4' gem 'health_check'

Para crear la imagen de Docker, tome mi Dockerfile y ejecute:

 docker build -t REPO_NAME/IMAGE_NAME:TAG . && docker push REPO_NAME/IMAGE_NAME:TAG

Es hora de crear un clúster de Kubernetes. Abre la página de GKE y crea un clúster de Kubernetes. Cuando se crea el clúster, haga clic en el botón "Conectar" y copie el comando; asegúrese de tener la herramienta CLI de gCloud (cómo hacerlo) y kubectl instalados y configurados. Ejecute el comando copiado en su PC y verifique la conexión al clúster de Kubernetes; ejecute kubectl cluster-info .

La aplicación está lista para implementarse en el clúster k8s. Vamos a crear una base de datos MySQL. Abra la página SQL en la consola de gCloud y cree una instancia de base de datos MySQL para la aplicación. Cuando la instancia esté lista, cree el usuario y la base de datos y copie el nombre de conexión de la instancia .

Además, debemos crear una clave de cuenta de servicio en la página API y servicios para acceder a una base de datos MySQL desde un contenedor sidecar. Puede encontrar más información sobre ese proceso aquí. Cambie el nombre del archivo descargado a service-account.json . Volveremos más tarde a ese archivo.

Estamos listos para implementar nuestra aplicación en Kubernetes, pero primero debemos crear secretos para nuestra aplicación: un objeto secreto en Kubernetes creado para almacenar datos confidenciales. Cargue el archivo service-account.json previamente descargado:

 kubectl create secret generic mysql-instance-credentials \ --from-file=credentials.json=service-account.json

Crear secretos para la aplicación:

 kubectl create secret generic simple-app-secrets \ --from-literal=username=$MYSQL_PASSWORD \ --from-literal=password=$MYSQL_PASSWORD \ --from-literal=database-name=$MYSQL_DB_NAME \ --from-literal=secretkey=$SECRET_RAILS_KEY

No olvide reemplazar valores o establecer variables de entorno con sus valores.

Antes de crear una implementación, echemos un vistazo al archivo de implementación. Concatené tres archivos en uno; la primera parte es un servicio que expondrá el puerto 80 y reenviará todas las conexiones que lleguen al puerto 80 al 3000. El servicio tiene un selector con el que el servicio sabe a qué pods debe reenviar conexiones.

La siguiente parte del archivo es la implementación, que describe la estrategia de implementación: contenedores que se lanzarán dentro del pod, variables de entorno, recursos, sondas, montajes para cada contenedor y otra información.

La última parte es el escalador automático horizontal de pods. HPA tiene una configuración bastante simple. Tenga en cuenta que si no configura recursos para el contenedor en la sección de implementación, HPA no funcionará.

Puedes configurar Vertical Autoscaler para tu clúster de Kubernetes en la página de edición de GKE. También tiene una configuración bastante simple.

¡Es hora de enviarlo al clúster de GKE! En primer lugar, debemos ejecutar migraciones a través de un trabajo. Ejecutar:

kubectl apply -f rake-tasks-job.yaml : este trabajo será útil para el proceso de CI/CD.

kubectl apply -f deployment.yaml : para crear servicios, implementaciones y HPA.

Y luego verifique su pod ejecutando el comando: kubectl get pods -w

 NAME READY STATUS RESTARTS AGE sample-799bf9fd9c-86cqf 2/2 Running 0 1m sample-799bf9fd9c-887vv 2/2 Running 0 1m sample-799bf9fd9c-pkscp 2/2 Running 0 1m

Ahora vamos a crear un ingreso para la aplicación:

  1. Cree una IP estática: gcloud compute addresses create sample-ip --global
  2. Cree el ingreso (archivo): kubectl apply -f ingress.yaml
  3. Verifique que se haya creado el ingreso y tome la IP: kubectl get ingress -w
  4. Cree el dominio/subdominio para su aplicación.

CI/CD

Vamos a crear una canalización de CI/CD usando CircleCI. En realidad, es fácil crear una canalización de CI/CD con CircleCI, pero tenga en cuenta que un proceso de implementación rápido y sucio totalmente automatizado sin pruebas como esta funcionará para proyectos pequeños, pero no lo haga para nada serio porque , si algún código nuevo tiene problemas en producción, perderá dinero. Es por eso que debe pensar en diseñar un proceso de implementación sólido, iniciar tareas de control antes de la implementación completa, verificar errores en los registros después de que se haya iniciado el control, etc.

Actualmente, tenemos un proyecto pequeño y simple, así que vamos a crear un proceso de implementación de CI/CD totalmente automatizado, sin pruebas. Primero, debe integrar CircleCI con su repositorio; puede encontrar todas las instrucciones aquí. Luego debemos crear un archivo de configuración con instrucciones para el sistema CircleCI. La configuración parece bastante simple. Los puntos principales son que hay dos ramas en el repositorio de GitHub: master y production .

  1. La rama maestra es para el desarrollo, para el código nuevo. Cuando alguien inserta código nuevo en la rama maestra, CircleCI inicia un flujo de trabajo para la rama maestra: código de compilación y prueba.
  2. La rama de producción es para implementar una nueva versión en el entorno de producción. El flujo de trabajo para la rama de producción es el siguiente: enviar código nuevo (o incluso mejor, abrir PR desde la rama principal a producción) para desencadenar un nuevo proceso de compilación e implementación; durante la compilación, CircleCI crea nuevas imágenes de Docker, las envía al GCR y crea un nuevo despliegue para la implementación; si la implementación falla, CircleCI activa el proceso de reversión.

Antes de ejecutar cualquier compilación, debe configurar un proyecto en CircleCI. Cree una nueva cuenta de servicio en la API y una página de Servicios en GCloud con estos roles: acceso completo a GCR y GKE, abra el archivo JSON descargado y copie el contenido, luego cree una nueva variable de entorno en la configuración del proyecto en CircleCI con el nombre GCLOUD_SERVICE_KEY y pega el contenido del archivo de la cuenta de servicio como un valor. Además, debe crear las siguientes variables de entorno: GOOGLE_PROJECT_ID (puede encontrarlo en la página de inicio de la consola de GCloud), GOOGLE_COMPUTE_ZONE (una zona para su clúster de GKE) y GOOGLE_CLUSTER_NAME (nombre del clúster de GKE).

El último paso (implementar) en CircleCI se verá así:

 kubectl patch deployment sample -p '{"spec":{"template":{"spec":{"containers":[{"name":"sample","image":"gcr.io/test-d6bf8/simple:'"$CIRCLE_SHA1"'"}]}}}}' if ! kubectl rollout status deploy/sample; then echo "DEPLOY FAILED, ROLLING BACK TO PREVIOUS" kubectl rollout undo deploy/sample # Deploy failed -> notify slack else echo "Deploy succeeded, current version: ${CIRCLE_SHA1}" # Deploy succeeded -> notify slack fi deployment.extensions/sample patched Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "sample" rollout to finish: 2 of 3 updated replicas are available... Waiting for deployment "sample" rollout to finish: 2 of 3 updated replicas are available... deployment "sample" successfully rolled out Deploy succeeded, current version: 512eabb11c463c5431a1af4ed0b9ebd23597edd9

Conclusión

¡Parece que el proceso de creación de un nuevo clúster de Kubernetes no es tan difícil! ¡Y el proceso de CI/CD es realmente increíble!

¡Sí! ¡Kubernetes es increíble! Con Kubernetes, su sistema será más estable, fácil de administrar y lo convertirá en el capitán de su sistema. ¡Sin mencionar que Kubernetes gamifica un poco el sistema y le dará +100 puntos por su comercialización!

Ahora que conoce los conceptos básicos, puede ir más allá y convertir esto en una configuración más avanzada. Planeo cubrir más en un artículo futuro, pero mientras tanto, aquí hay un desafío: Cree un clúster de Kubernetes robusto para su aplicación con una base de datos con estado ubicada dentro del clúster (incluido el Pod auxiliar para hacer copias de seguridad), instale Jenkins dentro del mismo clúster de Kubernetes para la canalización de CI/CD y deje que Jenkins use pods como esclavos para las compilaciones. Use certmanager para agregar/obtener un certificado SSL para su ingreso. Crea un sistema de monitoreo y alertas para tu aplicación usando Stackdriver.

Kubernetes es excelente porque se escala fácilmente, no hay dependencia de un proveedor y, dado que paga por las instancias, ahorra dinero. Sin embargo, no todos son expertos en Kubernetes o tienen el tiempo para configurar un nuevo clúster; para una visión alternativa, el compañero Toptaler Amin Shah Gilani defiende el uso de Heroku, GitLab CI y una gran cantidad de automatización que ya ha descubierto. para escribir más código y realizar menos tareas operativas en Cómo crear una canalización de implementación inicial eficaz .

Relacionados:
  • Haga los cálculos: aplicaciones de microservicios de escalado automático con orquestadores
  • K8s/Kubernetes: AWS frente a GCP frente a Azure
  • Una comparación de la malla de servicios de Kubernetes