Documente Academic
Documente Profesional
Documente Cultură
Cochabamba – Bolivia
2019
A mis padres, a mi familia, a mis maestros,
compañeros, por todos los que conocí en
este camino y que culmina con una meta
más. Gracias
ii
TABLA DE CONTENIDOS
RESUMEN………………………………………………………….………………………………….…..7
INTRODUCCIÓN……………………...……………………………………………………………….….8
1 GENERALIDADES…………………………………………………………………………….…9
2 METODOLOGÍA……………………………………………………………………………….....9
4 TECNOLOGÍA DE CONTENEDORES……………………..…………………………………….17
3
4.2.1 Conceptos de contenedor………………………………………………………….22
5 KUBERNETES…………………………………….………………………………………………..24
5.1.1 Cluster………………………………………………………………………………..26
5.1.2 Node………………………………………………………………………………….26
5.1.3 Master…………………………………………………………………………….…..27
5.1.4 Pod…………………………………………………………………………………....27
5.1.5 Label…………………………………………………………………………….……28
5.1.6 Annotation……………………………………………………………………….…...28
5.1.9 Service…………………………………………………………………………….….29
5.1.10 Volume……………………………………………………………………………...30
5.1.11 StatefulSet……………………………………………………………………….…30
5.1.12 Secret…………………………………………………………………………….…30
5.1.13 Name………………………………………………………………………………..31
5.2.1.2 Etcd……………………………………………………………………………...32
5.2.1.4 Scheduler……………………………………………………………………….33
5.2.1.5 DNS……………………………………………………………………………...33
5.2.2.2 Kubelet…………………………………………………………………………..34
7 CONCLUSIONES ………..………………………………………………………………..….…..45
8 BIBLIOGRAFÍA ………..…………………………………………………………….……..……..46
5
TABLA DE CUADROS, GRAFICOS Y FIGURAS
Figura 5 Cómo las aplicaciones usan la CPU en contenedores y maquinas virtuales. ...……...19
6
RESUMEN
Existen muchas aplicaciones grandes que se basan en los microservicios o está dividida en
varios contenedores, estas aplicaciones son difíciles de administrar y escalar; por lo tanto, un
orquestador es indispensable si se quiere tener una aplicación de varios contenedores,
escalable y lista para la producción. Una arquitectura de microservicios es un enfoque para la
generación de una aplicación de servidor como un conjunto de servicios pequeños.
Si bien las tecnologías de contenedores han existido durante mucho tiempo, se han hecho más
conocidas con el auge de la plataforma de contenedores Docker, este fue el primer sistema de
contenedores que hizo que los contenedores se puedan transportar fácilmente a través de
diferentes máquinas. Simplificó el proceso de empaquetar no solo la aplicación, sino también
todas sus librerías y otras dependencias, incluso todo el sistema de archivos del sistema
operativo.
7
INTRODUCCIÓN
El resultado de la siguiente monografía será como un punto de partida para las personas que
estén interesadas en utilizar la plataforma kubernetes para desplegar y ejecutar aplicaciones
basados en microservicios.
8
1 GENERALIDADES
2 METODOLOGÍA
9
3 ENTENDIENDO LA NECESIDAD DE UN SISTEMA COMO KUBERNETES
10
3.1.1 Dividir aplicaciones en microservicios
Estos y otros problemas nos han obligado a comenzar a dividir aplicaciones monolíticas
complejas en componentes desplegables independientes más pequeños llamados
microservicios. Cada microservicio se ejecuta como un proceso independiente (consulte la
figura 1) y se comunica con otros microservicios a través de interfaces simples y bien definidas
(APIs).
Los microservicios se comunican a través de protocolos síncronos como HTTP, sobre la cual
generalmente exponen las APIs RESTful (REpresentational State Transfer), o a través de
protocolos asíncronos como AMQP (Advanced Message Queue Protocol). Estos protocolos son
simples, bien entendidos por la mayoría de los desarrolladores y no están vinculados a ningún
lenguaje de programación específico. Cada microservicio se puede escribir en el lenguaje más
adecuado para implementar ese microservicio específico.
Debido a que cada microservicio es un proceso independiente con una API externa
relativamente estática, es posible desarrollar y desplegar cada microservicio por separado. Un
cambio en uno de ellos no requiere cambios ni redespliegues de ningún otro servicio, siempre
que la API no cambie o cambie solo de una manera compatible con versiones anteriores.
11
3.1.2 Microservicios de escala
Puede haber tres instancias del proceso 1.2 (Process 1.2) en el servidor 1 y servidor 3. El
proceso 2,2 (Process 2.2) posiblemente no escalable solo tiene una instancia única en el
servidor 2.
12
3.1.3 Despliegue de microservicios
Como siempre, los microservicios también tienen inconvenientes. Cuando su sistema consta de
solo una pequeña cantidad de componentes desplegables, administrar esos componentes es
fácil. Es trivial decidir dónde desplegar cada componente, porque no hay tantas opciones.
Cuando aumenta la cantidad de esos componentes, las decisiones relacionadas con el
despliegue se vuelven cada vez más difíciles porque no solo aumenta la cantidad de
combinaciones de despliegue, sino que la cantidad de interdependencias entre los
componentes aumenta en un factor aún mayor.
Los microservicios realizan su trabajo en equipo, por lo que necesitan encontrar y hablar entre
ellos. Al desplegarlos, alguien o algo debe configurarlos todos correctamente para permitir que
puedan trabajar juntos como un solo sistema. Con un número cada vez mayor de
microservicios, esto se vuelve tedioso y propenso a errores, especialmente cuando consideras
lo que deben hacer los equipos de operaciones/administradores de sistema cuando falla un
servidor.
Los microservicios también presentan otros problemas, como dificultar la depuración y el rastreo
de las llamadas de ejecución, ya que abarcan múltiples procesos y máquinas. Afortunadamente,
estos problemas ahora se están abordando con sistemas de rastreo distribuidos como Zipkin.
Estas diferencias van desde el hardware al sistema operativo a las librerías que están
disponibles en cada máquina. Los entornos de producción son administrados por el equipo de
operaciones, mientras que los desarrolladores se encargan a menudo de sus computadoras
portátiles de desarrollo por sí mismos. La diferencia es cuánto saben estos dos grupos de
personas sobre la administración del sistema, y esto comprensiblemente conduce a diferencias
relativamente grandes entre esos dos sistemas, sin mencionar que los administradores del
14
sistema le dan mucho más énfasis en mantener el sistema actualizado con los últimos parches
de seguridad. , mientras que a muchos desarrolladores no les importa mucho eso.
Para reducir la cantidad de problemas que solo aparecen en la producción, sería ideal si las
aplicaciones pudieran ejecutarse en el mismo entorno exacto durante el desarrollo y en la
producción para que tengan exactamente el mismo sistema operativo, librerías, configuración
del sistema, entorno de red y todo. Más. Tampoco desea que este entorno cambie demasiado
con el tiempo, si es que lo hace. Además, si es posible, desea la capacidad de agregar
aplicaciones al mismo servidor sin afectar a ninguna de las aplicaciones existentes en ese
servidor.
En los últimos años, también hemos visto un cambio en todo el proceso de desarrollo de
aplicaciones y en cómo se controlan las aplicaciones en la producción. En el pasado, el trabajo
del equipo de desarrollo era crear la aplicación y entregarla al equipo de operaciones, quien
luego la desplego, la atendió y la mantuvo en funcionamiento. Pero ahora, las organizaciones
se están dando cuenta de que es mejor que el mismo equipo que desarrolla la aplicación
también participe en su despliegue y controle durante toda su vida útil de la aplicación. Esto
significa que el desarrollador, el control de calidad y los equipos de operaciones ahora
necesitan colaborar en todo el proceso. Esta práctica se llama DevOps.
15
aplicación a los usuarios antes y luego usar sus comentarios para impulsar el desarrollo de la
aplicación.
Para lanzar versiones más nuevas de aplicaciones con más frecuencia, debe simplificar el
proceso de despliegue. Lo ideal es que los desarrolladores desplieguen las aplicaciones sin
tener que esperar a la gente de operaciones. Pero el despliegue de una aplicación a menudo
requiere un entendimiento de la infraestructura subyacente y la organización del hardware en el
centro de datos. Los desarrolladores no siempre conocen esos detalles y la mayoría de las
veces, ni siquiera quieren saber sobre ellos.
4 TECNOLOGÍA DE CONTENEDORES
En lugar de utilizar máquinas virtuales para aislar los entornos de cada microservicio (o
procesos de software en general), los desarrolladores están recurriendo a las tecnologías de
contenedor de Linux. Estos les permiten ejecutar múltiples servicios en la misma máquina host,
16
mientras que no solo exponen un entorno diferente a cada uno de ellos, sino que también los
aíslan entre sí, de manera similar a las máquinas virtuales, pero con mucho menos sobrecarga.
Un proceso que se ejecuta en un contenedor se ejecuta dentro del sistema operativo del host,
como todos los demás procesos (a diferencia de las máquinas virtuales, donde los procesos se
ejecutan en sistemas operativos separados). Pero el proceso en el contenedor todavía está
aislado de otros procesos. Para el proceso en sí, parece que es el único que se ejecuta en la
máquina y en su sistema operativo.
En comparación con las máquinas virtuales, los contenedores son mucho más ligeros, lo que le
permite ejecutar un mayor número de componentes de software en el mismo hardware,
principalmente porque cada máquina virtual debe ejecutar su propio conjunto de procesos del
sistema, lo que requiere recursos de cómputo adicionales además de los consumidos por El
propio proceso del componente. Un contenedor, por otro lado, no es más que un proceso
aislado que se ejecuta en el sistema operativo host, y consume solo los recursos que consume
la aplicación y sin la sobrecarga de procesos adicionales.
Cuando ejecuta tres máquinas virtuales en un host, tiene tres sistemas operativos
completamente separados que se ejecutan y comparten el mismo hardware. Debajo de esas
máquinas virtuales se encuentran el sistema operativo del host y un hipervisor, que divide los
recursos físicos de hardware en conjuntos más pequeños de recursos virtuales que pueden ser
utilizados por el sistema operativo dentro de cada máquina virtual. Las aplicaciones que se
ejecutan dentro de esas máquinas virtuales realizan llamadas de sistema al kernel del sistema
operativo huésped en la máquina virtual, y luego el kernel realiza instrucciones x86 en la CPU
física del host a través del hipervisor.
Nota: Existen dos tipos de hipervisores. Los hipervisores tipo 1 no utilizan un sistema
operativo host, mientras que el Tipo 2 lo hace.
17
Figura 4 Uso de máquinas virtuales vs. Contenedores, para aislar aplicaciones
Los contenedores, por otro lado, todos realizan llamadas de sistema en el mismo kernel que se
ejecuta en el sistema operativo host. Este kernel único es el único que realiza instrucciones x86
en la CPU del host. La CPU no necesita realizar ningún tipo de virtualización como lo hace con
las máquinas virtuales (ver figura 5).
El principal beneficio de las máquinas virtuales es el aislamiento total que brinda, ya que cada
máquina virtual ejecuta su propio kernel de Linux, mientras que todos los contenedores llaman
el mismo kernel, lo que claramente representa un riesgo para la seguridad. Si tiene una
cantidad limitada de recursos de hardware, las máquinas virtuales solo pueden ser una opción
cuando tiene una pequeña cantidad de procesos que quieres aislar. Para ejecutar una mayor
cantidad de procesos aislados en la misma máquina, los contenedores son una opción mucho
mejor debido a su baja sobrecarga. Recuerde, cada máquina virtual ejecuta su propio conjunto
de servicios del sistema, mientras que los contenedores no lo hacen, porque todos se ejecutan
en el mismo sistema operativo. Eso también significa que para ejecutar un contenedor, no es
necesario arrancar nada, como es el caso en las máquinas virtuales.
18
Figura 5 Cómo las aplicaciones usan la CPU en contenedores y máquinas virtuales
19
4.1.3 Mecanismos para aislamiento de contenedores
En este punto, probablemente se estará preguntando cómo los contenedores pueden aislar
procesos si se ejecutan en el mismo sistema operativo. Dos mecanismos hacen esto posible. El
primero, Linux Namespaces, se asegura de que cada proceso vea su propia visión personal del
sistema (archivos, procesos, interfaces de red, nombre de host, etc.). El segundo son los
Grupos de control de Linux (cgroups), que limitan la cantidad de recursos que el proceso puede
consumir (CPU, memoria, ancho de banda de la red, etc.).
Por defecto, cada sistema Linux tiene inicialmente un solo espacio de nombres. Todos los
recursos del sistema, como los sistemas de archivos, las IDs de proceso, las IDs de usuario, las
interfaces de red y otros, pertenecen al espacio de nombre único. Pero puedes crear espacios
de nombres adicionales y organizar recursos a través de ellos. Cuando ejecuta un proceso, lo
ejecuta dentro de uno de esos espacios de nombres. El proceso solo verá los recursos que
están dentro del mismo espacio de nombre. Bueno, existen varios tipos de espacios de
nombres, por lo que un proceso no pertenece a un espacio de nombres, sino a un espacio de
nombres de cada tipo.
mount (mnt)
ID de proceso (pid)
Red (net)
Comunicación entre procesos (ipc)
UTS
ID de usuario (usuario)
Cada tipo de espacio de nombre se utiliza para aislar un determinado grupo de recursos. Por
ejemplo, el espacio de nombre UTS determina qué nombre de host y nombre de dominio ve el
proceso que se ejecuta dentro de ese espacio de nombre. Al asignar dos espacios de nombres
UTS diferentes a un par de procesos, tú puedes hacer que vean diferentes nombres de host
locales. En otras palabras, para los dos procesos, parecerá que se están ejecutando en dos
máquinas diferentes (por lo menos en lo que al nombre de host respecta).
20
Del mismo modo, a qué espacio de nombre de red pertenece un proceso determina qué
interfaces de red ve la aplicación que se ejecuta dentro del proceso. Cada interfaz de red
pertenece exactamente a un espacio de nombre, pero se puede mover de un espacio de
nombres a otro. Cada contenedor utiliza sus propios espacios de nombres de red y, por lo tanto,
cada contenedor ve su propio conjunto de interfaces de red.
Esto debería darle una idea básica de cómo se usan los espacios de nombres para aislar
aplicaciones que se ejecutan en contenedores uno del otro.
La otra mitad del aislamiento del contenedor trata de limitar la cantidad de recursos del sistema
que un contenedor puede consumir. Esto se logra con cgroups, una característica del kernel de
Linux que limita el uso de recursos de un proceso (o un grupo de procesos). Un proceso no
puede usar más que la cantidad configurada de CPU, memoria, ancho de banda de la red, etc.
De esta manera, los procesos no pueden acaparar los recursos reservados para otros
procesos, que es similar a cuando cada proceso se ejecuta en una máquina separada.
Si bien las tecnologías de contenedores han existido durante mucho tiempo, se han hecho más
conocidas con el auge de la plataforma de contenedores Docker. Docker fue el primer sistema
de contenedores que hizo que los contenedores sea transportable fácilmente a través de
diferentes máquinas. Simplificó el proceso de empaquetar no solo la aplicación sino también
todas sus librerías y otras dependencias, incluso todo el sistema de archivos del sistema
operativo, en un paquete simple y portátil que se puede usar para suministrar la aplicación a
cualquier otra máquina que ejecute Docker.
Cuando ejecutas una aplicación empaquetada con Docker, este ve el contenido exacto del
sistema de archivos que tú has empaquetado con ella. Ve los mismos archivos si se está
ejecutando en su máquina de desarrollo o en una máquina de producción, incluso si el servidor
de producción está ejecutando un sistema operativo Linux completamente diferente. La
aplicación no verá nada del servidor en el que se está ejecutando, por lo que no importa si el
servidor tiene un conjunto completamente diferente de librerías instaladas en comparación con
su máquina de desarrollo.
21
Por ejemplo, si ha empaquetado su aplicación con los archivos de todo el sistema operativo
Red Hat Enterprise Linux (RHEL), la aplicación creerá que se está ejecutando dentro de RHEL,
tanto cuando la ejecuta en su computadora de desarrollo que ejecuta Fedora como cuando lo
ejecutas en un servidor que ejecuta Debian o alguna otra distribución de Linux. Solo el kernel
puede ser diferente.
Esto es similar a crear una imagen de máquina virtual instalando un sistema operativo en una
máquina virtual, instalando la aplicación en su interior y luego distribuyendo la imagen completa
de la máquina virtual y ejecutándola. Docker logra el mismo efecto, pero en lugar de usar
máquinas virtuales para lograr el aislamiento de la aplicación, utiliza las tecnologías de
contenedor de Linux mencionadas en la sección anterior para proporcionar (casi) el mismo nivel
de aislamiento que las máquinas virtuales. En lugar de usar grandes imágenes de máquinas
virtuales monolíticas, usa imágenes de contenedor, que generalmente son más pequeñas.
Una gran diferencia entre las imágenes de contenedor basadas en Docker y las imágenes de
máquinas virtuales es que las imágenes de contenedor están compuestas por capas, que se
pueden compartir y reutilizar en múltiples imágenes. Esto significa que solo se deben descargar
ciertas capas de una imagen si las otras capas ya se descargaron anteriormente al ejecutar una
imagen de contenedor diferente que también contiene las mismas capas.
Docker es una plataforma para empaquetar, distribuir y ejecutar aplicaciones. Como ya hemos
indicado, le permite empaquetar su aplicación junto con todo su entorno. Estas pueden ser
algunas de las librerías que requiere la aplicación o incluso todos los archivos que normalmente
están disponibles en el sistema de archivos de un sistema operativo instalado. Docker permite
transferir este paquete a un repositorio central desde el cual puede transferirse a cualquier
computadora que ejecute Docker y ejecutarse allí (en su mayor parte, pero no siempre, como
explicaremos pronto).
22
Registros: un registro de Docker es un repositorio que almacena sus imágenes de Docker y
facilita el intercambio de esas imágenes entre diferentes personas y computadoras. Cuando
construyes tu imagen, puedes ejecutarla en la computadora en la que la construiste o
puedes empujar (cargar) la imagen a un registro y luego extraerla (descargarla) en otra
computadora y ejecutarla allí. Ciertos registros son públicos, lo que permite que cualquiera
pueda extraer imágenes de ellos, mientras que otros son privados, solo accesibles a ciertas
personas o máquinas.
Contenedores: un contenedor basado en Docker es un contenedor regular de Linux creado
a partir de una imagen de contenedor basada en Docker. Un contenedor en ejecución es un
proceso que se ejecuta en el host que ejecuta Docker, pero está completamente aislado
tanto del host como de todos los demás procesos que se ejecutan en él. El proceso también
tiene recursos limitados, lo que significa que solo puede acceder y usar la cantidad de
recursos (CPU, RAM, etc.) que se le asignan.
23
La figura 6 muestra los tres conceptos y cómo se relacionan entre sí. El desarrollador primero
construye una imagen y luego la empuja a un registro. La imagen de este modo está disponible
para cualquiera que pueda acceder al registro. Ellos pueden jalar la imagen a cualquier otra
máquina que ejecute Docker y ejecutar la imagen. Docker crea un contenedor aislado basado
en la imagen y ejecuta el ejecutable binario especificado como parte de la imagen.
5 KUBERNETES
Despliegue de contenedores
Almacenamiento persistente
Monitoreo de la salud del contenedor
Gestión de recursos informáticos
Escalamiento automático
Alta disponibilidad por federación de cluster
La vida útil de los contenedores puede ser corta. Pueden ser matados o detenidos en cualquier
momento en que excedan el límite de recursos. Kubernetes incluso admite la prueba de vida
para ayudarlo a definir el estado de su aplicación. Para una mejor administración de recursos,
también podemos definir la capacidad máxima en los nodos Kubernetes y el límite de recursos
para cada grupo de contenedores. El programador de Kubernetes seleccionará entonces un
24
nodo que cumpla con los criterios de recursos para ejecutar los contenedores. Trabajar con
almacenamiento y recursos. Kubernetes proporciona una característica opcional de escalado
automático horizontal de pod. Con esta función, podríamos escalar un pod horizontalmente por
métricas de recursos o personalizadas. Kubernetes está diseñado con alta disponibilidad.
Podemos crear múltiples nodos maestros para evitar un punto único de falla.
A través de los años, Google desarrolló un sistema interno llamado Borg (y luego un nuevo
sistema llamado Omega), que ayudó a los desarrolladores de aplicaciones y a los
administradores de sistemas a administrar esas miles de aplicaciones y servicios. Además de
simplificar el desarrollo y la administración, también les ayudó a lograr una utilización mucho
mayor de su infraestructura, lo cual es importante cuando su organización es tan grande.
Cuando ejecuta cientos de miles de máquinas, incluso pequeñas mejoras en la utilización
significan ahorros en millones de dólares, por lo que los incentivos para desarrollar dicho
sistema son claros.
Después de haber mantenido en secreto a Borg y Omega durante toda una década, en 2014
Google presentó Kubernetes, un sistema de código abierto basado en la experiencia adquirida
a través de Borg, Omega y otros sistemas internos de Google.
25
Figura 7 Diagrama de arquitectura de kubernetes
5.1.1 Clúster
5.1.2 Node
Un nodo es un único host. Puede ser una máquina física o virtual. Su trabajo es ejecutar los
pods. Cada nodo de Kubernetes ejecuta varios componentes de Kubernetes, como un kubelet y
26
un kube proxy. Los nodos son gestionados por un master de Kubernetes. Los nodos son abejas
obreras de Kubernetes y cargan con todo el trabajo pesado. En el pasado fueron llamados
minions. Si lees alguna documentación o artículos antiguos, no te confundas. Los minions son
nodos.
5.1.3 Master
5.1.4 Pod
Un pod es la unidad de trabajo en Kubernetes. Cada pod contiene uno o más contenedores.
Los pods siempre se programan juntos (siempre se ejecutan en la misma máquina). Todos los
contenedores en un pod tienen la misma dirección IP y espacio de puerto; se pueden comunicar
utilizando localhost o comunicación entre procesos estándar. Además, todos los contenedores
en un pod pueden tener acceso al almacenamiento local compartido en el nodo que aloja el
pod. El almacenamiento compartido se montará en cada contenedor. Los pods son una
característica importante de Kubernetes. Es posible ejecutar múltiples aplicaciones dentro de un
solo contenedor de Docker teniendo algo como supervisor como la aplicación Docker principal
que ejecuta múltiples procesos, pero esta práctica a menudo está mal vista, por las siguientes
razones:
Transparencia: hacer que los contenedores dentro del pod sean visibles para la
infraestructura permite que la infraestructura brinde servicios a esos contenedores, como la
administración de procesos y el monitoreo de recursos. Esto facilita una serie de
comodidades para los usuarios.
Desacoplamiento de dependencias de software: los contenedores individuales pueden
ser versionados, reconstruidos y redesplegados independientemente. Kubernetes puede
incluso soportar actualizaciones en vivo de contenedores individuales algún día.
Facilidad de uso: los usuarios no necesitan ejecutar sus propios gestores de procesos,
preocuparse por la propagación de la señal y el código de salida, etc.
27
Eficiencia: porque la infraestructura asume más responsabilidad, los contenedores pueden
ser más ligeros.
Los pods ofrecen una excelente solución para administrar grupos de contenedores
estrechamente relacionados que dependen unos de otros y necesitan cooperar en el mismo
host para lograr su propósito. Es importante recordar que los pods se consideran entidades
efímeras, entidades desechables que se pueden desechar y reemplazar a voluntad. Cualquier
almacenamiento de pod se destruye con su pod. Cada pod recibe una ID única (UID), por lo que
aún puede distinguirlos si es necesario.
5.1.5 Label
Las etiquetas son pares clave-valor que se utilizan para agrupar conjuntos de objetos, muy a
menudo pods. Esto es importante para varios otros conceptos, como el controlador de
replicación, los conjuntos de réplicas y los servicios que operan en grupos dinámicos de objetos
y que necesitan identificar a los miembros del grupo. Hay una relación NxN entre objetos y
etiquetas. Cada objeto puede tener múltiples etiquetas y cada etiqueta puede aplicarse a
diferentes objetos. Hay ciertas restricciones de diseño en las etiquetas. Cada etiqueta en un
objeto debe tener una clave única. La clave de la etiqueta debe adherirse a una sintaxis estricta.
Tiene dos partes: prefijo y nombre. El prefijo es opcional. Si existe, está separado del nombre
por una barra (/) y debe ser un subdominio DNS válido. El prefijo debe tener 253 caracteres
como máximo. El nombre es obligatorio y debe tener 63 caracteres como máximo. Los nombres
deben comenzar y terminar con un carácter alfanumérico (a-z, A-Z, 0-9) y contener solo
caracteres alfanuméricos, puntos, guiones, y barra baja. Los valores siguen las mismas
restricciones que los nombres. Tenga en cuenta que las etiquetas están dedicadas a identificar
objetos y no a adjuntar metadatos arbitrarios a objetos.
5.1.6 Annotation
28
5.1.7 Label selector
Los selectores de etiquetas se utilizan para seleccionar objetos en función de sus etiquetas. Los
selectores basados en la igualdad especifican un nombre de clave y un valor. Hay dos
operadores, = (o ==) y ! =, Por la igualdad o la desigualdad basada en el valor. Por ejemplo:
role = webserver
Esto seleccionará todos los objetos que tienen esa clave y valor de etiqueta. Los selectores de
etiquetas pueden tener múltiples requisitos separados por una coma. Por ejemplo:
5.1.9 Service
Los servicios se utilizan para exponer alguna funcionalidad a los usuarios u otros servicios. Por
lo general abarcan un grupo de pods, que generalmente se identifican mediante una etiqueta.
Puede tener servicios que brindan acceso a recursos externos o pods que controla
directamente en el nivel de IP virtual. Los servicios de Kubernetes nativos están expuestos a
través de endpoints convenientes. Tenga en cuenta que los servicios operan en la capa 3 (TCP
/UDP).
Kubernetes 1.2 agregó el objeto Ingress, que proporciona acceso a los objetos HTTP. Los
servicios se publican o descubren a través de uno de los dos mecanismos: DNS o variables de
29
entorno. Los servicios pueden ser equilibrados de carga por Kubernetes. Sin embargo, los
desarrolladores pueden optar por administrar el equilibrio de carga por sí mismos en el caso de
servicios que utilizan recursos externos o requieren un tratamiento especial.
5.1.10 Volume
El almacenamiento local en el pod es efímero y desaparece con el pod. A veces, eso es todo lo
que necesitas, si el objetivo es simplemente intercambiar datos entre los contenedores del
nodo, pero a veces es importante que los datos sobrevivan al pod, o es necesario compartir los
datos entre los pods. El concepto de volumen apoya esa necesidad. Tenga en cuenta que, si
bien Docker también tiene un concepto de volumen, es bastante limitado (aunque se vuelve
más poderoso). Kubernetes utiliza sus propios volúmenes separados. Kubernetes también
admite tipos de contenedores adicionales como rkt, por lo que no podía confiar en los
volúmenes de Docker ni siquiera en principio.
5.1.11 StatefulSet
Los pods vienen y se van, y si le importan sus datos, puede usar el almacenamiento
persistente. Eso es todo bueno. Pero a veces desea que Kubernetes administre un almacén de
datos distribuidos como Kubernetes o MySQL Galera. Estas tiendas agrupadas mantienen los
datos distribuidos en nodos identificados de forma única. No puedes modelar eso con pods y
servicios regulares.
5.1.12 Secret
Los secretos son pequeños objetos que contienen información confidencial como credenciales y
tokens. Se almacenan como texto plano en etcd, a los que puede acceder el servidor de API de
Kubernetes y se pueden montar como archivos en pods que necesitan acceso a ellos. El mismo
secreto puede ser montado en múltiples pods. Kubernetes crea secretos para sus
componentes, y usted puede crear sus propios secretos. Otro enfoque es utilizar secretos como
variables de entorno.
Tenga en cuenta que los secretos en un pod siempre se almacenan en la memoria (tmpfs en el
caso de secretos montados) para una mejor seguridad.
30
5.1.13 Name
Cada objeto en Kubernetes es identificado por un UID y un nombre. El nombre se utiliza para
referirse al objeto en las llamadas a la API.
Los nombres deben tener un máximo de 253 caracteres y utilizar caracteres alfanuméricos en
minúsculas, guion (-) y punto (.). Si elimina un objeto, puede crear otro objeto con el mismo
nombre que el objeto eliminado, pero los UID deben ser únicos durante toda la vida útil del
clúster. Los UIDs son generados por Kubernetes, por lo que no tiene que preocuparse por eso.
Un namespace es un clúster virtual. Puede tener un solo clúster físico que contenga varios
clústeres virtuales separados por namespaces. Cada cluster virtual está totalmente aislado de
otros clústeres virtuales y ellos solo pueden comunicarse a través de interfaces públicas.
Kubernetes puede programar pods de diferentes namespaces para que se ejecuten en el
mismo nodo. Del mismo modo, los pods de diferentes namespaces pueden usar el mismo
almacenamiento persistente.
31
Figura 8 Componentes del master
El servidor API kube expone la API REST de Kubernetes. Este puede escalar horizontalmente
fácilmente ya que no tiene estado y almacena todos los datos en el clúster de etcd. El servidor
API es la encarnación del plano de control de Kubernetes.
5.2.1.2 Etcd
32
el controlador de endpoints y otros. Todos estos administradores vigilan el estado del clúster vía
el API y su trabajo es dirigir el clúster al estado deseado.
5.2.1.4 Scheduler
Requerimientos de recursos
Requisitos de servicio
Restricciones de política de hardware/software
Especificaciones de afinidad y anti-afinidad.
Localidad de datos
Plazos
5.2.1.5 DNS
A partir de Kubernetes 1.3, un servicio DNS forma parte del clúster estándar de Kubernetes.
Está programado como un pod regular. Cada servicio (excepto los servicios sin cabeza) recibe
un nombre DNS. Los pods también pueden recibir un nombre de DNS. Esto es muy útil para el
descubrimiento automático.
5.2.2.1 Proxy
El proxy kube realiza gestión de la red de bajo nivel en cada nodo. Refleja los servicios de
Kubernetes localmente y puede hacer el reenvío de TCP y UDP. Este encuentra IPs de clúster
vía variables de entorno o DNS.
5.2.2.2 Kubelet
Debido a que Kubernetes expone todos sus nodos de trabajo como una única plataforma de
despliegue, los desarrolladores de aplicaciones pueden comenzar a desplegar aplicaciones por
su cuenta y no necesitan saber nada sobre los servidores que conforman el clúster.
34
En esencia, todos los nodos son ahora un solo grupo de recursos computacionales que están
esperando que las aplicaciones los consuman. A un desarrollador generalmente no le importa
en qué tipo de servidor se está ejecutando la aplicación, siempre que el servidor pueda
proporcionar a la aplicación los recursos adecuados del sistema.
Existen ciertos casos en los que al desarrollador le importa en qué tipo de hardware debe
ejecutarse la aplicación. Si los nodos son heterogéneos, encontrará casos en los que desea
que ciertas aplicaciones se ejecuten en nodos con ciertas capacidades y ejecuten otras
aplicaciones en otras. Por ejemplo, una de tus aplicaciones puede requerir que se ejecute en un
sistema con SSDs en lugar de HDDs, mientras que otras aplicaciones se ejecutan bien en
HDDs. En tales casos, obviamente desea asegurarse de que la aplicación particular siempre
esté programada para un nodo con un SSD.
Sin usar Kubernetes, el administrador del sistema seleccionaría un nodo específico que tiene un
SSD y desplegaría la aplicación allí. Pero al usar Kubernetes, en lugar de seleccionar un nodo
específico donde debe ejecutarse su aplicación, es más apropiado decirle a Kubernetes que
solo elija entre nodos con un SSD.
Al configurar Kubernetes en sus servidores y usarlo para ejecutar sus aplicaciones en lugar de
ejecutarlas manualmente, ha desacoplado su aplicación de la infraestructura. Cuando le dice a
Kubernetes que ejecute su aplicación, le está permitiendo elegir el nodo más apropiado para
ejecutar su aplicación basándose en la descripción de los requisitos de recursos de la aplicación
y los recursos disponibles en cada nodo.
Tener un sistema que permita mover una aplicación a través del clúster en cualquier momento
también es valioso en caso de fallas en el servidor. A medida que aumenta el tamaño del
clúster, lidiará con los componentes de la computadora que fallan cada vez más
frecuentemente.
Kubernetes supervisa los componentes de su aplicación y los nodos en los que se ejecutan y
los reprograma automáticamente a otros nodos en caso de que falle un nodo. Esto libera al
equipo de operaciones de tener que migrar los componentes de la aplicación manualmente y
permite al equipo enfocarse de inmediato en arreglar el nodo y devolverlo al conjunto de
recursos de hardware disponibles en lugar de concentrarse en reubicar la aplicación.
El uso de Kubernetes para administrar tus aplicaciones desplegadas también significa que el
equipo de operaciones no necesita monitorear constantemente la carga de las aplicaciones
individuales para reaccionar ante picos repentinos de carga. Como se mencionó anteriormente,
se le puede decir a Kubernetes que monitoree los recursos utilizados por cada aplicación y que
siga ajustando el número de instancias en ejecución de cada aplicación.
36
5.3.5 Simplificando el desarrollo de aplicaciones
Si vuelves al hecho de que las aplicaciones se ejecutan en el mismo entorno tanto durante el
desarrollo como durante la producción, esto tiene un gran efecto en el momento en que se
descubren los errores. Todos estamos de acuerdo en que cuanto antes descubras un error,
más fácil es solucionarlo y corregirlo requiere menos trabajo. Son los desarrolladores quienes
hacen la reparación, por lo que esto significa menos trabajo para ellos.
Luego está el hecho de que los desarrolladores no necesitan implementar características que
normalmente implementarían. Esto incluye el descubrimiento de servicios y/o los pares en una
aplicación agrupada. Kubernetes hace esto en lugar de la aplicación. Por lo general, la
aplicación solo necesita buscar ciertas variables de entorno o realizar una búsqueda de DNS. Si
eso no es suficiente, la aplicación puede consultar el servidor API de Kubernetes directamente
para obtener eso y/u otra información. Consultar el servidor de la API de Kubernetes de esa
manera puede incluso evitar que los desarrolladores tengan que implementar mecanismos
complicados como la elección del líder.
Como ejemplo final de lo que Kubernetes trae a la mesa, también debe considerar el aumento
en la confianza que los desarrolladores sentirán al saber que cuando se lance una nueva
versión de su aplicación, Kubernetes puede detectar automáticamente si la nueva versión es
mala y detener su despliegue inmediatamente. Este aumento de la confianza por lo general
acelera la entrega continua de aplicaciones, lo que beneficia a toda la organización.
https://github.com/pablokbs/peladonerd/tree/master/kubernetes/13
37
Se crea este script de configuración para mongo con el comando:
38
Luego creamos otro archive “04-mongo-full.yaml” con la siguiente información:
Este archivo va servir para crear 3 nodos mongo que son los StatefulSets, ejecutamos:
39
Verificamos que se crearon los nodos con el siguiente comando:
Este archivo sirve para crear un servicio que permita a los pods mongos comunicarse,
ejecutamos:
40
Se creara otro archivo “05-node-app.yaml”, con la siguiente información:
Este archivo sirve para crear una aplicación que utilizara la base de datos mongo, ejecutamos:
Luego Se creara un servicio para poder acceder de forma externa al deployment “node-mongo”,
creamos un archivo “06-node-app-svc.yaml” con la siguiente información:
41
Ejecutamos el comando:
También se puede verificar los nodos, servicios, deployments con el siguiente comando:
42
Automáticamente el tablero se abrirá en el navegador web.
minikube ip
http://192.168.99.120:30000
Ahora podemos utilizar la aplicación web que utiliza la base de datos mongo:
43
Figura 11 Aplicación web desplegado con Kubernetes
44
7 CONCLUSIONES
Se pudo desplegar una aplicación con minikube de manera local y se vio que minikube
no es adecuado para la producción ni para entornos de carga pesada, tiene algunas
limitaciones por su naturaleza de nodo único, pero es una buena opción para practicar
kubernetes, para utilizar kubernetes en producción se puede utilizar Google Kubernetes
Engine, DigitalOcean, Amazon EKS, etc.
Se pudo desplegar Mongo y se vio que los statefulSets en Kubernetes son adecuados
para desplegar aplicaciones de base de datos.
45
8 BIBLIOGRAFÍA
Saito, H., Lee, H., & Wu, C. (2017). DevOps with Kubernetes. Birmingham: Packt Publishing Ltd.
https://docs.microsoft.com/es-es/dotnet/standard/microservices-architecture/architect-
microservice-container-applications/microservices-architecture
https://enmilocalfunciona.io/instalando-y-probando-kubernetes-windows-10
Pagani, M. (2019). First steps with Docker and Kubernetes – Introduction. Microsoft.
https://techcommunity.microsoft.com/t5/Windows-Dev-AppConsult/First-steps-with-
Docker-and-Kubernetes-Introduction/ba-p/357525
46