DEVOXX Reino Unido. Kubernetes en producción: implementación azul / verde, autoescalado y automatización de implementación. Parte 1

Kubernetes es una gran herramienta para ejecutar contenedores Docker en un entorno de producción en clúster. Sin embargo, hay tareas que Kubernetes no puede resolver. Con implementaciones frecuentes en un entorno de producción, necesitamos una implementación Azul / Verde totalmente automatizada para evitar el tiempo de inactividad en este proceso, que también requiere solicitudes HTTP externas y descarga SSL. Esto requiere integración con un equilibrador de carga como ha-proxy. Otra tarea es el escalado semiautomático del clúster Kubernetes en sí mismo cuando se trabaja en la nube, por ejemplo, la reducción parcial de la escala del clúster por la noche.

Aunque Kubernetes no tiene estas características listas para usar, proporciona una API que se puede utilizar para resolver estos problemas. Las herramientas de escalado y despliegue automatizado azul / verde de Kubernetes se desarrollaron como parte del proyecto de código abierto Cloud RTI.

Esta transcripción del video describe cómo configurar Kubernetes junto con otros componentes de código abierto para obtener un entorno listo para la producción que acepte el código del git commit change commit sin tiempo de inactividad en la producción.



Hoy hablaremos sobre Kubernetes, en particular, sobre su automatización. Echaremos un vistazo a los conceptos básicos de este sistema y luego veremos cómo integrar Kubernetes en los proyectos en la etapa de desarrollo. Mi nombre es Paul, soy de los Países Bajos, trabajo para una compañía llamada Luminis Technologies y soy el autor de los libros "Diseño de aplicaciones en la nube con OSGi" y "Modulación de Java 9". De lo que hablaré es muy diferente del tema de estos libros.
En el último año, pasé la mayor parte de mi tiempo trabajando en una plataforma de infraestructura basada en Kubernetes y creando herramientas para ello, principalmente en Golang. Además, sigo trabajando en el libro de Java 9. Mi pasatiempo es el levantamiento de pesas. Así que vamos al grano.

¿Por qué cuidar a Kubernetes? En primer lugar, porque le permite ejecutar Docker en clústeres. Si no usa Docker, entonces no está en el tema. Si trabaja con Docker, sabe que está diseñado principalmente para ejecutar contenedores en su propia máquina. Mejora el trabajo con muchas redes, sin embargo, todo esto está limitado a una máquina, por lo que no hay forma de ejecutar contenedores en un clúster.



Los creadores de Docker están expandiendo constantemente sus capacidades, pero si realmente necesita ejecutar contenedores en producción, necesitará algo como Kubernetes, porque Docker con su línea de comando no ayudará.

Hablemos de los conceptos básicos de Kubernetes. Antes de analizar el uso de la API para la automatización, debemos comprender el concepto de cómo funciona esta plataforma. Un clúster típico incluye los siguientes elementos. El nodo maestro gestiona y controla el funcionamiento de todo el clúster y decide dónde se planificarán los contenedores y cómo se lanzarán. Lanza el servidor API, que es el elemento más importante del trabajo de la plataforma, luego consideraremos este problema en detalle.



Hay un montón de nodos de trabajo de Nodo que contienen pods Pods con contenedores Docker y almacenamiento distribuido, etc. Nodes es el lugar donde se ejecutarán sus contenedores. Kubernetes no funciona con contenedores Docker directamente, pero utiliza una abstracción llamada Pod para esto. Los nodos de trabajo lanzan un montón de contenedores, y el nodo maestro se asegura de que funcionen. Además, hay un almacenamiento distribuido de tipo clave-valor, etc., que almacena toda la información sobre el clúster. Etcd es tolerante a fallas, por lo que al menos consta de 3 nodos independientes. Esto garantiza que el asistente funcione sin perder el estado.

Después de iniciar Kubernetes con todos los componentes anteriores, se implementan los contenedores de programación. La implementación significa que los contenedores comienzan a funcionar en un clúster. Para hacer esto, antes que nada, necesita un objeto llamado Replication Controller, lanzado en el servidor maestro, que le permite crear y monitorear el estado de varias instancias de hogares.



Para configurar el controlador de replicación para crear, por ejemplo, 5 réplicas de contenedores en cinco nodos de trabajo diferentes, debe tener tantos nodos. Además del hecho de que el controlador inicia la operación de estos contenedores, monitorea su estado. Si por falta de memoria falla uno de los contenedores, el controlador registrará una disminución en el número de 5 a 4 e iniciará un nuevo contenedor en uno de los nodos disponibles. Esto significa que cuando Kubernetes se está ejecutando, no inicia los contenedores en ningún nodo específico, sino que establece el estado requerido: configure la plataforma para implementar 5 contenedores y transfiera el control al controlador de replicación, que se encarga de mantener este estado. Por lo tanto, el controlador de replicación es un concepto muy importante.

Como dije, Kubernetes no funciona con contenedores directamente. Lo hace a través de Pod, una abstracción en la parte superior de los contenedores. Es importante que Kubernetes funcione no solo con contenedores Docker, sino también, por ejemplo, con sus contenedores alternativos: rkt. Esto no es soporte oficial, porque si miras la documentación técnica de Kubernetes, solo habla de los contenedores Docker. Sin embargo, a medida que se desarrolla la plataforma, se le agrega compatibilidad con contenedores de otros formatos.



Cada parte inferior puede contener muchos contenedores con el mismo ciclo de vida. Esto significa que no podremos ejecutar contenedores para varios propósitos en el mismo pod, porque todos ellos pueden existir solo en el mismo período de tiempo. Comienzan simultáneamente y simultáneamente detienen su trabajo. Entonces, si trabaja con microservicios, no puede ponerlos a todos en el mismo sub. Los contenedores dentro del hogar se "ven" entre sí en el host local.

Si, por ejemplo, está implementando un servicio web, el pod para esta aplicación contendrá el contenedor nginx, y nginx no se modifica, sino que se saca directamente de la caja. Para que este nginx funcione, necesitaremos agregar nuestros propios archivos HTML y colocarlos en un contenedor separado para los archivos web. Ambos contenedores se colocan en un subcomún común y comienzan a funcionar juntos, como si existieran en la misma máquina física, por lo que ven archivos del mismo sistema de archivos ubicados en el mismo host local. Los servicios que proporcionan la interacción de los componentes del clúster operan utilizando variables de entorno env vars.

Lo siguiente que proporciona debajo es la creación de redes. Si ejecuta varios contenedores en la misma máquina física, que también se pueden ubicar en la nube, y todos estos contenedores usan puertos, por ejemplo, usamos 3 aplicaciones Java que funcionan con el mismo puerto 8080, entonces esto está lleno de conflictos. Para evitarlo, necesitará la asignación de puertos, lo que complicará en gran medida el proceso de implementación de aplicaciones.



Por lo tanto, sería genial si cada contenedor lanzado tuviera su propia dirección IP virtual con acceso a todos los puertos disponibles, sin pensar en su posible conflicto. Esto es exactamente lo que ofrece Kubernetes.

Cada vez que crea un pod, crea su propia dirección IP virtual. Los puertos no se comparten entre el resto de los pods, por lo que no hay conflicto. Lo único que funciona en esta dirección IP es lo que hace este contenedor. Todo se simplifica.
Sin embargo, esto plantea un nuevo problema: si su dirección IP virtual cambia cada vez que reinicia los contenedores, lo que sucede a menudo, ¿cómo puede usar estos contenedores? Supongamos que tenemos 2 módulos diferentes que se comunican entre sí, pero sus direcciones IP cambian todo el tiempo. Kubernetes utiliza un concepto llamado servicios para resolver este problema. Estos servicios configuran proxies en la parte superior de sus hogares y continúan usando direcciones IP virtuales de cierto rango, pero estas son direcciones fijas que no cambian todo el tiempo.

Por lo tanto, cuando los pods quieren comunicarse entre sí, lo hacen no directamente, sino a través de los servicios, utilizando estas direcciones IP fijas.



Estos servicios organizan el tráfico de todas las réplicas intercambiadas entre los componentes del clúster. Por lo tanto, los servicios son muy importantes para garantizar la comunicación entre los componentes.
El concepto de Servicios facilita enormemente el proceso de implementación de múltiples componentes cuando varios componentes son parte de una aplicación más grande, como la arquitectura de microservicios, aunque personalmente no me gusta tratar con microservicios.



Cada componente que tiene se puede implementar como un sub independiente con su propio ciclo de vida. Son independientes entre sí y tienen espacios de nombres separados, sus propias direcciones IP y rangos de números de puerto, se pueden actualizar y escalar de forma independiente. El uso de servicios facilita enormemente la comunicación entre componentes. La siguiente diapositiva muestra un ejemplo de aplicación de varios componentes.



La primera en Frontend es una interfaz de usuario que utiliza varios servicios de back-end o réplicas de servicios de back-end. Verá un paquete de varios pods para los cuales los servicios se utilizan como proxy. No debe preocuparse por el rendimiento de cada pod, porque si uno de ellos falla, Kubernetes reiniciará automáticamente el nuevo. El servicio de back-end utiliza otros servicios ubicados en diferentes pods, y todos utilizan el concepto de servicios para la interacción. Todo esto funciona muy bien, por lo que si usa esta arquitectura, Kubernetes puede implementarla fácilmente. Si la arquitectura se basa en un principio diferente, puede tener problemas.

El siguiente concepto importante a introducir es el espacio de nombres de espacios de nombres.



Estos son espacios aislados dentro de Kubernetes que contienen hogares, controladores de replicación y servicios. Aislamiento significa, por ejemplo, que cuando el entorno de desarrollo está en un espacio de nombres y la producción está en otro, se utilizan servicios con el mismo nombre para evitar conflictos entre diferentes espacios de nombres. De esta manera, puede colocar fácilmente diferentes entornos en el mismo clúster Kubernetes físico.

La implementación de la aplicación es un paso necesario antes de lanzar la aplicación en producción. La documentación de Kubernetes establece que debe usar la herramienta de línea de comandos kubectl para completar la implementación. Esta herramienta se mejora constantemente y es perfecta para implementar cualquier cosa.



Verá los archivos de configuración de yaml que necesita crear para la API utilizando el comando kubectl. La siguiente diapositiva muestra cómo se ve un archivo yaml típico.



En este archivo configuramos el controlador de replicación. La primera parte importante es la línea con el número de réplicas que queremos replicar: 3. Este número es igual al número de nodos que se utilizarán. En este caso, el número 3 significa que queremos ejecutar pods en 3 máquinas diferentes en nuestro clúster. El controlador de replicación supervisa el estado del sistema y, si es necesario, reinicia automáticamente los pods para garantizar el funcionamiento continuo de un número determinado de réplicas.

En la parte inferior del código hay líneas que representan la especificación del hogar. Describe los puertos, los nodos de almacenamiento, el nombre y la imagen del servidor web y otra información necesaria para nuestro contenedor Docker.

Finalmente, hay un montón de metadatos aquí, como etiquetas. Las etiquetas son pares clave-valor y se agregan a objetos como pods. Se utilizan para agrupar y seleccionar subconjuntos de objetos. Son muy importantes para organizar las interacciones API, vinculando controladores, pods y servicios.

El pod no sabe qué controlador de replicación lo creó, y el controlador de replicación no conoce la lista de pods que crea. Pero tanto los pods como el controlador tienen etiquetas, cuya coincidencia indica que un sub específico pertenece a un controlador específico. Esta es una conexión bastante débil, pero flexible, que garantiza el funcionamiento estable de la API y las cosas automatizadas.

Ahora verá una breve demostración que muestra el trabajo de kubectl, y luego profundizaremos en el trabajo del equilibrador de carga y el uso de la API. Entonces, entro en el comando kubectl get pods, pero el sistema no muestra hogares porque todavía no hemos ejecutado nada. Luego, ingreso el comando ls para ver una lista de los archivos disponibles.



Ahora ingreso el nombre del primer archivo de la lista y se muestra el archivo de configuración yaml, similar al que acabamos de ver. Usemos este archivo para crear un hogar escribiendo kubectl create –f nginx-controller.yaml. Como resultado, habremos creado bajo. Al repetir el comando kubectl get pods, puede ver que este funciona.



Pero este es solo uno debajo. Intentemos escalar nuestro controlador creando varias réplicas. Para hacer esto, ingreso el comando kubectl scale rc nginx - replicas = 5, donde rc es el controlador de replicación, y 5 es el número requerido de instancias o réplicas de este controlador. Verá el progreso de la creación de contenedores, y si vuelve a ingresar el comando kubectl get pods después de un par de segundos, puede ver que la mayoría de los contenedores creados ya han comenzado a funcionar.



Por lo tanto, aumentamos el número de hogares o réplicas que trabajan en nuestro clúster a 5 copias. Además, por ejemplo, puede echar un vistazo a la dirección IP creada para la primera réplica ingresando el comando kubectl describe pod nginx-772ia. Esta es la dirección IP virtual que se adjunta a este contenedor en particular.



Su trabajo será proporcionado por los servicios mencionados anteriormente. Veamos qué sucede si destruye una de las réplicas de trabajo, porque en cualquier caso, debemos garantizar el trabajo de un número determinado de copias. Entro en el comando kubectl delete pod nginx-772ia y el sistema informa que con ese identificador se ha eliminado. Usando el comando kubectl get pods, vemos que 5 instancias de controlador están funcionando nuevamente, y en lugar de la réplica remota nginx-772ia, ha aparecido una nueva con el identificador nginx-sunfn.



Esto sucedió porque Kubernetes notó la falla de una de las réplicas. En realidad, esto no fue un mal funcionamiento accidental, sino una acción deliberada, hasta donde personalmente lo eliminé. Pero dado que el número de réplicas especificadas por la configuración del clúster permaneció sin cambios, el controlador de replicación notó la desaparición de una de las instancias e inmediatamente restauró el estado requerido del clúster creando e iniciando un nuevo contenedor con una nueva ID. Por supuesto, este es un ejemplo estúpido cuando elimino una réplica y espero que el controlador la restaure, pero situaciones similares ocurren en la vida real debido a una falla del contenedor, por ejemplo, debido a la falta de memoria. En este caso, el controlador también se reiniciará en.

Si tenemos varios escenarios de producción en los que la aplicación Java no está configurada correctamente, por ejemplo, no hay suficiente memoria instalada, esto puede provocar un bloqueo tanto unas pocas horas como una semana después de que se inicie el programa. En tales casos, Kubernetes se encarga de que el flujo de trabajo no se interrumpa.

Permítame recordarle una vez más que todo lo anterior no es aplicable en la etapa de producción, cuando no debe usar la línea de comando kubectl y otras cosas ingresadas desde el teclado para garantizar el funcionamiento del producto. Entonces, antes de comenzar a implementar la automatización, necesitamos resolver otro gran problema. Supongamos que tengo un contenedor nginx ejecutándose en este momento, pero no tengo acceso a él desde el "mundo exterior". Sin embargo, si se trata de una aplicación web, puedo acceder a ella a través de Internet. Para garantizar la estabilidad de este proceso, se utiliza un equilibrador de carga, que se encuentra en frente del clúster.
Necesitamos poder administrar los servicios de Kubernetes desde el mundo exterior, y esta característica no se admite automáticamente desde el primer momento. Por ejemplo, para garantizar el equilibrio de HTTP, debe usar la descarga SSL o la carga SSL. Este es el proceso de eliminar el cifrado basado en SSL del tráfico entrante que recibe el servidor web para liberar al servidor del descifrado de datos. Para equilibrar el tráfico, también puede usar la compresión Gzip de páginas web.

Las versiones recientes de Kubernetes, como 1.02, tienen una nueva característica llamada Ingress. Sirve para configurar el equilibrador de carga. Este es un nuevo concepto en la API donde puede escribir un complemento que configurará cualquier balanceador de carga externo que use.



Desafortunadamente, hoy este concepto no está finalizado y se ofrece en la versión alfa. Puede demostrar cómo funcionará en el futuro, pero no coincidirá con la forma en que funciona hoy. Utilizo el equilibrador proporcionado por Google Cloud Engine, sin embargo, si no trabaja con este servicio, tendrá que hacer algo usted mismo, al menos en este momento. En el futuro, probablemente en un mes, será mucho más fácil: puede usar la función de ingreso para equilibrar el tráfico.

Hoy, este problema se resuelve creando un equilibrador de tráfico personalizado. En primer lugar, puede usar el proxy ha ubicado frente al clúster de Kubernetes. Se ejecuta fuera del clúster en una máquina externa o un conjunto de máquinas. A continuación, es necesario proporcionar una configuración dinámica automática del proxy ha, para no configurarlo manualmente al crear cada nuevo hogar. Se debe realizar un trabajo similar para nginx, Apache y otros servidores, y el ha-proxy actúa como una herramienta fácil de integrar.

La siguiente diapositiva muestra cómo el nodo del equilibrador de carga maneja el tráfico HTTPS entrante, y el proxy ha se encuentra en una máquina externa o grupo de máquinas ubicadas fuera del grupo Kubernetes. La carga SSL también se encuentra aquí. El proxy detecta las direcciones solicitadas y luego pasa el tráfico a los servicios de Kubernetes, sin estar interesado en las direcciones IP de los hogares que pueden cambiar con el tiempo. A continuación, los servicios pasan el tráfico a pods en ejecución con direcciones IP dinámicas.



Si usa AWS, puede usar el concepto de equilibrador de carga ELB. Elastic Load Balancing redirige el tráfico a instancias saludables de Amazon para garantizar la estabilidad de la aplicación. Este mecanismo es especialmente bueno si necesita escalabilidad del equilibrador de carga.



En este caso, el tráfico se envía primero al servicio de AWS, donde se descarga SSL, luego de lo cual ingresa al nodo del equilibrador de carga de proxy ha.

Puede hacer lo mismo si sus clústeres están completamente dentro de una red VPN virtual privada. En este caso, el uso de AWS ELB garantiza por completo la seguridad del sistema. No necesita implementar SSL entre varios componentes fuera del clúster. Lo único que se conectará con el mundo exterior es nuestro proxy proxy.



Conceptualmente, parece bastante simple, pero ¿cómo funciona en realidad? ¿Cómo configuro un proxy ha para que conozca los servicios de Kubernetes? Si observa ha-proxy de la misma manera que consideramos nginx, notará que todavía utiliza archivos de configuración estáticos. Entonces, si desea agregarle un nuevo back-end, que en este caso son nuestros servicios de Kubernetes, debemos cambiar el archivo de configuración, volver a cargar ha-proxy y solo después de eso todo funcionará como debería. Por supuesto, no queremos hacer esto manualmente. Por lo tanto, puede usar una pequeña herramienta de código abierto llamada Confd, que administra los archivos de configuración de la aplicación local utilizando datos de etcd. Si se producen cambios en el almacén de metadatos, etc., Confd genera automáticamente una plantilla de configuración,que reconfigura el proxy ha de acuerdo con las nuevas condiciones de trabajo.

Puede parecer que este enfoque requiere esfuerzos adicionales, sin embargo, es una herramienta muy simple que funciona con plantillas, por lo que su uso es una tarea bastante trivial.

26:00 min. La

continuación será muy pronto ...


Un poco de publicidad :)


Gracias por estar con nosotros. ¿Te gustan nuestros artículos? ¿Quieres ver más materiales interesantes? Apóyenos haciendo un pedido o recomendando a sus amigos, VPS en la nube para desarrolladores desde $ 4.99 , un análogo único de servidores de nivel básico que inventamos para usted: toda la verdad sobre VPS (KVM) E5-2697 v3 (6 núcleos) 10GB DDR4 480GB SSD 1Gbps desde $ 19 o cómo dividir el servidor? (las opciones están disponibles con RAID1 y RAID10, hasta 24 núcleos y hasta 40GB DDR4).

Dell R730xd 2 veces más barato en el centro de datos Equinix Tier IV en Amsterdam? Solo tenemos 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV desde $ 199 en los Países Bajos.Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - ¡desde $ 99! Lea sobre Cómo construir un edificio de infraestructura. clase c con servidores Dell R730xd E5-2650 v4 que cuestan 9,000 euros por un centavo?

All Articles