Kubernetes - domando la nube

Kubernetes - domando la nube

Cuando desee utilizar Linux para proporcionar servicios a una empresa, estos servicios deberán ser seguros, resistentes y escalables. Bonitas palabras, ¿pero qué queremos decir con ellas?

Segura" significa que los usuarios pueden acceder a los datos que necesitan, ya sean de sólo lectura o de escritura. Al mismo tiempo, no se exponen datos a ninguna parte que no esté autorizada a verlos. La seguridad es engañosa: puedes pensar que lo tienes todo protegido sólo para descubrir más tarde que hay agujeros. Diseñar con seguridad desde el principio de un proyecto es mucho más fácil que tratar de adaptarlo más tarde.

Resistente" significa que sus servicios toleran las fallas dentro de la infraestructura. Un fallo puede ser una controladora de disco del servidor que ya no puede acceder a ningún disco, haciendo que los datos no estén disponibles. O el fallo puede ser un conmutador de red que ya no permite la comunicación entre dos o más sistemas. En este contexto, un "punto único de fallo" o SPOF es un fallo que afecta negativamente a la disponibilidad del servicio. Una infraestructura resiliente es aquella que no tiene SPOF.

Escalable" describe la capacidad de los sistemas para manejar con elegancia los picos de demanda. También dicta con qué facilidad se pueden hacer cambios en los sistemas. Por ejemplo, añadir un nuevo usuario, aumentar la capacidad de almacenamiento o trasladar una infraestructura de Amazon Web Services a Google Cloud, o incluso trasladarla internamente.

Tan pronto como su infraestructura se expande más allá de un servidor, hay muchas opciones para aumentar la seguridad, la resistencia y la escalabilidad. Examinaremos cómo se han resuelto tradicionalmente estos problemas y qué nueva tecnología está disponible que cambie la faz de la informática de las grandes aplicaciones.

Para entender lo que es posible hoy en día, es útil observar cómo se han implementado tradicionalmente los proyectos tecnológicos. En los viejos tiempos, es decir, hace más de 10 años, las empresas compraban o alquilaban hardware para ejecutar todos los componentes de sus aplicaciones. Incluso las aplicaciones relativamente simples, como un sitio web de WordPress, tienen múltiples componentes. En el caso de WordPress, se necesita una base de datos MySQL junto con un servidor web, como Apache, y una forma de manejar el código PHP. Así que, construían un servidor, configuraban Apache, PHP y MySQL, instalaban WordPress y se iban.

En general, eso funcionó. Funcionó lo suficientemente bien que todavía hay un gran número de servidores configurados exactamente de esa manera hoy en día. Pero no fue perfecto, y dos de los mayores problemas fueron la resistencia y la escalabilidad.

La falta de resiliencia significaba que cualquier problema significativo en el servidor resultaría en una pérdida de servicio. Claramente una falla catastrófica significaría que no habría sitio web, pero tampoco había espacio para llevar a cabo el mantenimiento programado sin afectar al sitio web. Incluso la instalación y activación de una actualización de seguridad rutinaria para Apache requeriría unos segundos de interrupción para el sitio web.

El problema de la resiliencia se resolvió en gran medida mediante la creación de "agrupaciones de alta disponibilidad". El principio era tener dos servidores corriendo el sitio web, configurados de tal manera que el fallo de cualquiera de ellos no resultara en la caída del sitio web. El servicio que se estaba prestando era resistente incluso si los servidores individuales no lo eran.

Parte del poder de Kubernetes es la abstracción que ofrece. Desde la perspectiva de un desarrollador, desarrollan la aplicación para que se ejecute en un contenedor Docker. A Docker no le importa si se ejecuta en Windows, Linux o algún otro sistema operativo. Ese mismo contenedor Docker puede tomarse del MacBook del desarrollador y ejecutarse bajo Kubernetes sin ninguna modificación.

La instalación de Kubernetes puede ser una sola máquina. Por supuesto, muchos de los beneficios de los Kubernetes no estarán disponibles: no habrá auto-escalado; hay un solo punto obvio de falla, y así sucesivamente. Sin embargo, como prueba de concepto en un entorno de prueba, funciona.

Una vez que esté listo para la producción, puede ejecutarse internamente o en un proveedor de cloud computing como AWS o Google Cloud. Los proveedores de la nube tienen algunos servicios incorporados que ayudan a ejecutar Kubernetes, pero ninguno de ellos es un requisito difícil. Si quieres moverte entre Google, Amazon y tu propia infraestructura, configura Kubernetes y muévete. Ninguna de sus aplicaciones tiene que cambiar de ninguna manera.

¿Y dónde está Linux? Kubernetes funciona en Linux, pero el sistema operativo es invisible para las aplicaciones. Este es un paso significativo en la madurez y usabilidad de las infraestructuras de TI.

El problema de la escalabilidad es un poco más complicado. Digamos que su sitio de WordPress recibe 1.000 visitantes al mes. Un día, su negocio es mencionado en Radio 4 o en la televisión de desayuno. De repente, recibes más de un mes de visitas en 20 minutos. Todos hemos escuchado historias de sitios web que se'colapsan', y es por eso que típicamente: una falta de escalabilidad.

Los dos servidores que ayudaron con la resiliencia podían manejar una carga de trabajo mayor que la de un solo servidor, pero eso sigue siendo limitado. Usted pagaría por dos servidores el 100 por ciento del tiempo y la mayoría de las veces ambos funcionaban perfectamente. Es probable que uno solo pueda dirigir su sitio. Entonces John Humphrys menciona su negocio en Today y necesitaría 10 servidores para manejar la carga, pero sólo por unas pocas horas.

La mejor solución al problema de la resiliencia y la escalabilidad era el cloud computing. Configure una o dos instancias de servidor (los pequeños servidores que ejecutan sus aplicaciones) en Amazon Web Services (AWS) o Google Cloud, y si una de las instancias falla por alguna razón, se reiniciará automáticamente. Configure la auto-escalado correctamente y cuando el Sr. Humphrys hace que la carga de trabajo en las instancias de su servidor web aumente rápidamente, se inician automáticamente instancias adicionales del servidor para compartir la carga de trabajo. Más tarde, a medida que el interés disminuye, esas instancias adicionales se detienen, y usted sólo paga por lo que utiliza. Perfecto... ¿o no?

Aunque la solución en la nube es mucho más flexible que el servidor independiente tradicional, todavía hay problemas. Actualizar todas las instancias de nube en ejecución no es sencillo. El desarrollo para la nube también tiene sus retos: el portátil que sus desarrolladores están usando puede ser similar a la instancia de nube, pero no es lo mismo. Si se compromete con AWS, la migración a Google Cloud es una tarea compleja. Y supongamos que, por la razón que sea, simplemente no quiere entregar su ordenador a Amazon, Google o Microsoft.

Los contenedores han surgido como un medio para envolver aplicaciones con todas sus dependencias en un solo paquete que puede ejecutarse en cualquier lugar. Los contenedores, como Docker, pueden ejecutarse en los portátiles de sus desarrolladores del mismo modo que en las instancias de nube, pero la gestión de una flota de contenedores se convierte en un reto cada vez mayor a medida que aumenta el número de contenedores.

La respuesta es orquestación de contenedores. Se trata de un cambio de enfoque significativo. Antes, nos asegurábamos de que tuviéramos suficientes servidores, ya fueran físicos o virtuales, para asegurarnos de que pudiéramos atender la carga de trabajo. El uso de la autoescala de los proveedores de nube nos ayudó, pero todavía estábamos tratando con casos. Tuvimos que configurar los balanceadores de carga, cortafuegos, almacenamiento de datos y más manualmente. Con la orquestación de contenedores, todo eso (y mucho más) está solucionado. Nosotros especificamos los resultados que necesitamos y nuestras herramientas de orquestación de contenedores cumplen con nuestros requisitos. Especificamos lo que queremos que se haga, en lugar de cómo queremos que se haga.

La integración continua y el despliegue continuo pueden funcionar bien con Kubernetes. He aquí una visión general de Jenkins que se utiliza para construir e implementar una aplicación Java

Kubernetes (ku-ber-net-eez) es la principal herramienta de orquestación de contenedores en la actualidad, y procede de Google. Si alguien sabe cómo ejecutar infraestructuras de TI a gran escala, Google lo sabe. El origen de Kubernetes es Borg, un proyecto interno de Google que todavía se utiliza para ejecutar la mayoría de las aplicaciones de Google, incluyendo su motor de búsqueda, Gmail, Google Maps y más. Borg era un secreto hasta que Google publicó un artículo sobre él en 2015, pero el periódico dejó muy claro que Borg era la principal inspiración detrás de Kubernetes.

Borg es un sistema que gestiona los recursos computacionales de los centros de datos de Google y mantiene las aplicaciones de Google, tanto de producción como de otro tipo, funcionando a pesar de los fallos de hardware, el agotamiento de los recursos u otros problemas que pudieran haber causado una interrupción. Para ello, supervisa cuidadosamente los miles de nodos que componen una "célula" borg y los contenedores que circulan sobre ellos, y pone en marcha o detiene los contenedores según sea necesario en respuesta a problemas o fluctuaciones de la carga.

El propio Kubernetes nació de la iniciativa GIFEE ("Infraestructura de Google para todos los demás") de Google, y fue diseñado para ser una versión más amigable de Borg que podría ser útil fuera de Google. Fue donado a la Fundación Linux en 2015 a través de la formación de la Cloud Native Computing Foundation (CNCF).

Kubernetes proporciona un sistema mediante el cual usted "declara" sus aplicaciones y servicios contenedorizados, y se asegura de que sus aplicaciones se ejecuten de acuerdo con esas declaraciones. Si sus programas requieren recursos externos, como almacenamiento o balanceadores de carga, Kubernetes puede aprovisionarlos automáticamente. Puede escalar sus aplicaciones hacia arriba o hacia abajo para mantenerse al día con los cambios en la carga, e incluso puede escalar todo su clúster cuando sea necesario. Los componentes de su programa ni siquiera necesitan saber dónde se están ejecutando: Kubernetes proporciona servicios de nomenclatura interna a las aplicaciones para que puedan conectarse a "wp_mysql" y conectarse automáticamente al recurso correcto.'

El resultado final es una plataforma que se puede utilizar para ejecutar sus aplicaciones en cualquier infraestructura, desde una sola máquina, pasando por un rack de sistemas en las instalaciones, hasta flotas de máquinas virtuales basadas en la nube que se ejecutan en cualquier proveedor de cloud importante, todo ello utilizando los mismos contenedores y la misma configuración. Kubernetes es agnóstico a los proveedores: llévelo donde usted quiera.

Kubernetes es una herramienta poderosa, y es necesariamente compleja. Antes de entrar en una visión general, necesitamos introducir algunos términos utilizados en Kubernetes. Los contenedores ejecutan aplicaciones individuales, como se discutió anteriormente, y están agrupados en vainas. Un pod es un grupo de contenedores estrechamente vinculados que se despliegan juntos en el mismo host y comparten algunos recursos. Los contenedores dentro de un pod trabajan en equipo: realizarán funciones relacionadas, como un contenedor de aplicación y un contenedor de registro con configuraciones específicas para la aplicación.

Una visión general de Kubernetes que muestra al maestro ejecutando los componentes clave y los dos nodos. Tenga en cuenta que, en la práctica, los componentes principales pueden dividirse en varios sistemas

Los cuatro componentes clave de Kubernetes son el Servidor API, el Programador, el Administrador de Controladores y una base de datos de configuración distribuida llamada etcd. El Servidor API está en el corazón de Kubernetes, y actúa como el punto final primario para todas las solicitudes de gestión. Estos pueden ser generados por una variedad de fuentes, incluyendo otros componentes de Kubernetes, como el programador, los administradores a través de tableros basados en la línea de comandos o en la web, y las propias aplicaciones en contenedores. Valida las solicitudes y actualiza los datos almacenados en etcd.

El Programador determina en qué nodos se ejecutarán los distintos módulos, teniendo en cuenta las restricciones como los requisitos de recursos, cualquier restricción de hardware o software, la carga de trabajo, los plazos y mucho más.

El Administrador de controladores supervisa el estado del clúster e intentará iniciar o detener los pods según sea necesario, a través del servidor de la API, para que el clúster alcance el estado deseado. También gestiona algunas conexiones internas y características de seguridad.

Cada nodo ejecuta un proceso Kubelet, que se comunica con el servidor de la API y gestiona contenedores, generalmente mediante Docker, y Kube-Proxy, que se encarga de la proxy de red y del equilibrio de carga dentro del clúster.

El sistema de base de datos distribuido etcd deriva su nombre de la carpeta /etc de los sistemas Linux, que se utiliza para almacenar la información de configuración del sistema, más el sufijo 'd', que a menudo se utiliza para denotar un proceso daemon. Los objetivos de etcd son almacenar los datos de valor clave de una manera distribuida, consistente y tolerante a fallos.

El servidor de la API mantiene todos sus datos de estado en etcd y puede ejecutar muchas instancias simultáneamente. El programador y el administrador del controlador sólo pueden tener una instancia activa, pero utiliza un sistema de arrendamiento para determinar qué instancia en ejecución es la principal. Todo esto significa que Kubernetes puede funcionar como un sistema de alta disponibilidad sin puntos de fallo.

Entonces, ¿cómo utilizamos esos componentes en la práctica? Lo que sigue es un ejemplo de cómo configurar un sitio web de WordPress usando Kubernetes. Si quisieras hacer esto de verdad, entonces probablemente usarías una receta predefinida llamada gráfico de timón. Están disponibles para varias aplicaciones comunes, pero aquí veremos algunos de los pasos necesarios para poner en marcha un sitio de WordPress en Kubernetes.

La primera tarea es definir una contraseña para MySQL:

kubectl hablará con el servidor de la API, que validará el comando y luego almacenará la contraseña en etcd. Nuestros servicios están definidos en archivos YAML, y ahora necesitamos un almacenamiento persistente para la base de datos MySQL.

La especificación debería ser en su mayoría autoexplicativa. Los campos de nombre y etiquetas se utilizan para referirse a este almacenamiento de otras partes de Kubernetes, en este caso nuestro contenedor WordPress.

Una vez definido el almacenamiento, podemos definir una instancia de MySQL, apuntando al almacenamiento predefinido. A continuación, se define la propia base de datos. Le damos a esa base de datos un nombre y una etiqueta para facilitar su consulta dentro de Kubernetes.

Ahora necesitamos otro contenedor para ejecutar WordPress. Parte de la especificación de despliegue de contenedores es:

El tipo de estrategia "Recrear" significa que si cambia alguno de los códigos que componen la aplicación, las instancias en ejecución serán eliminadas y recreadas. Otras opciones incluyen la posibilidad de hacer ciclos de nuevas instancias y eliminar las existentes, una por una, lo que permite que el servicio continúe funcionando durante la implementación de una actualización. Finalmente, declaramos un servicio para el propio WordPress, que comprende el código PHP y Apache. Parte del archivo de YAML que declara que esto es:

Observe la última línea, que define el tipo de servicio como LoadBalancer. Eso instruye a Kubernetes para que el servicio esté disponible fuera de Kubernetes. Sin esa línea, esto no sería más que un servicio interno de "sólo Kubernetes". Y eso es todo. Kubernetes usará ahora esos archivos YAML como una declaración de lo que se requiere, y configurará los pods, conexiones, almacenamiento, etc. según sea necesario para poner el cluster en el estado "deseado".

Usa la vista del tablero de mandos para obtener un resumen de Kubernetes en acción.

Esta ha sido necesariamente sólo una visión general de alto nivel de los kubernetes, y se han omitido muchos detalles y características del sistema. Hemos pasado por alto el autoescalado (tanto de los pods como de los nodos que componen un cluster), los trabajos de cron (inicio de contenedores según una programación), Ingress (balanceo de carga HTTP, reescritura y descarga de SSL), RBAC (controles de acceso basados en roles), políticas de red (firewalling), y mucho más. Kubernetes es extremadamente flexible y poderoso: para cualquier nueva infraestructura de TI, debe ser un competidor serio.

Si no está familiarizado con Docker, empiece por aquí: https://docs.docker.com/get-started.

Hay un tutorial interactivo sobre cómo implementar y escalar una aplicación aquí: https://kubernetes.io/docs/tutorials/kubernetes-basics

Y vea https://kubernetes.io/docs/setup/scratch para saber cómo construir un clúster.

Puedes jugar con un clúster gratuito de Kubernetes en https://tryk8s.com

Por último, puede leer un largo artículo técnico con una excelente visión general del uso de Borg por parte de Google y de cómo eso influyó en el diseño de Kubernetes aquí: https://storage.googleapis.com/pub-tools-public-publication-data/pdf/43438.pdf

Más información sobre Tiger Computing.