Diseño de Cluster Kubernetes
Podemos instalar Kubernetes de varias maneras. ¿Cuál de ellas es la ideal para lo que quieres hacer?
Vamos a plantear algunas preguntas sobre la mesa.
Propósito del cluster
¿Cuál es el propósito de este cluster? ¿WHY?
- ¿Aprendizaje?
- Si estás comenzando y es la primera vez, puedes usar minikube que simula un cluster de solo 1 nodo master, es suficiente y podemos desplegar los pods dentro del propio master.
- Una excelente opción es kind que crea nodos como contenedores en tu máquina local. Evita crear VMs y podemos simular más nodos masters y workers.
- ¿Desarrollo?
- En un ambiente de desarrollo 1 master y varios workers es un escenario.
- Un cluster baremetal puede ser una excelente elección para reducir costos.
- Un setup con kubeadm o kubespray sería una forma fácil de hacerlo.
- ¿Producción?
- Varios masters, como mínimo 3.
- Puede ser provisionado con kubespray, kops, kubeadm o usando soluciones gestionadas por la nube que incluso considero la mejor opción cuando es posible.
https://kubernetes.io/docs/setup/best-practices/cluster-large/
Kubernetes soporta hasta 5000 nodos 150000 pods en el cluster 300000 contenedores totales 100 pods por nodo.
Dimensionamiento del Cluster
Existe un punto óptimo entre CPU y memoria para evitar cuellos de botella. Claro que cada tipo de aplicación puede variar en los recursos. Una aplicación con uso intensivo de CPU y poca memoria o lo contrario se salen del estándar y necesita ser analizado.
Si tienes mucha CPU y poca memoria, el sistema puede quedar ocioso esperando que los datos sean recuperados de la memoria. De la misma forma, si tienes mucha memoria y poca CPU, el sistema puede no conseguir procesar los datos lo suficientemente rápido.
Para propósitos generales, si aún no sabes qué será montado, piensa en al menos 1CPU por cada 4GB RAM.
Otro punto importante es cuántos nodos worker pretendes tener. ¿Es mejor muchos nodos con menos recursos o menos nodos con más recursos?
Cada vez que tenemos un daemonset que ejecuta un pod en cada nodo obligatoriamente, si tienes muchos nodos, también perderás mucho recurso. Cada vez que un nodo arranca, si es muy pequeño ya perdió parte de su RAM para ejecutar el sistema operativo. Necesitamos encontrar un punto ideal en que la aplicación funcione en alta disponibilidad.
Creo que como mínimo 2 nodos worker es ideal para comenzar con alta disponibilidad. Algunos recursos en Kubernetes serían ideales con al menos 3 nodos workers, que sería el mejor escenario.
Para entender qué opción de dimensionamiento seleccionar, considera los pros y contras.
Precios de instancia: Generalmente, puedes asumir que el costo de la instancia por CPU/RAM es lineal entre las principales plataformas de nube.
Al determinar la capacidad de tu cluster, hay muchas maneras de abordar el dimensionamiento de los nodos. Por ejemplo, si calculaste un tamaño de cluster de 16 CPU y 64 GB de RAM, podrías dividir el tamaño del nodo en estas opciones:
2 nodos: 8 CPU / 32 GB de RAM 4 nodos: 4 CPU / 16 GB de RAM 8 nodos: 2 CPU / 8 GB de RAM 16 nodos: 1 CPU / 4 GB de RAM
Menos nodos más grandes
Pros
Si tienes aplicaciones que usan mucha CPU o RAM, tener nodos más grandes puede garantizar que tu aplicación tenga recursos suficientes.
Contras La alta disponibilidad es difícil de conseguir con un conjunto mínimo de nodos. Si tu aplicación tiene 50 pods en dos nodos (25 pods por nodo) y un nodo se cae, perderás el 50% de tu servicio.
Dimensionamiento: al escalar automáticamente el cluster, el tamaño del incremento se vuelve mayor, lo que puede resultar en el aprovisionamiento de más hardware del necesario.
Más nodos más pequeños
Pros
- La alta disponibilidad es más fácil de mantener. Si tienes 50 instancias con dos pods por nodo (25 nodos) y un nodo se cae, reducirás tu capacidad de servicio en solo 4%.
Contras
- Más sobrecarga del sistema para gestionar todos los nodos.
- Posible subutilización, ya que los nodos pueden ser demasiado pequeños para agregar servicios adicionales.
- Un simple daemonset como node exporter de Prometheus tendría en este caso 50 pods.
Equilibrio
Este escenario sería bastante interesante:
- 4 nodos con 16GB si las aplicaciones son más grandes
- 8 nodos con 8GB para aplicaciones más pequeñas
¿Dónde será creado? ¿WHERE?
¿Será un cluster en la nube? Si es en la nube, facilita todo para que puedas concentrarte en las aplicaciones y deja que la nube cuide del control plane. AWS tenemos el EKS que puede ser lanzado con Kops o módulos en Terraform. GCP tenemos el GKE Azure tenemos el AKS.
¿Será on-premises? kubespray y kubeadm son excelentes herramientas para ayudar a desplegar el cluster
Consejos:
- Siempre que sea posible utiliza SSD en el almacenamiento para tener un mayor rendimiento.
- Para múltiples pods accediendo al mismo storage, da preferencia al Network storage
- Define labels en los tipos de storage para facilitar el despliegue usando el almacenamiento correcto
- Crea node selectors para colocar los pods en los nodos con mejor desempeño para este pod
- La buena práctica recomienda reservar los masters para no desplegar nada, solo los componentes de Kubernetes. Garantiza que un taint esté aplicado en estos masters.
- Define recursos dedicados para el kubelet en cada nodo worker.
¿Qué tendremos en el cluster? ¿WHAT? ¿Cuántas aplicaciones estarán en el cluster? ¿Qué tipo de aplicaciones será usada en el cluster? Los recursos pueden variar si son aplicaciones web, aplicaciones efímeras, big data, etc ¿Tipo de recursos usados por estas aplicaciones? Uso intensivo de CPU o de memoria. ¿Serán aplicaciones con uso intensivo de red?
Un detalle que debe ser evaluado es en clusters muy grandes tener un cluster ETCD dedicado separado de los masters. Solo lleva esto en consideración en clusters extremadamente grandes. Mientras puedas mantener el etcd junto a los masters, manténlo.
Infraestructura de Kubernetes
Podemos desplegar Kubernetes en nuestra máquina local, en máquinas físicas dedicadas, en la nube, en máquinas virtualizadas, etc.
Local y Desarrollo
En Windows no es posible ejecutar directamente los componentes de Kubernetes pues no hay binarios disponibles. Es necesario virtualizar una máquina Linux para este propósito, sea usando Hyper-V, VMware, VirtualBox, etc. En Linux podríamos simplemente levantar todos los componentes directamente como servicio si queremos.
Otro escenario muy utilizado es utilizar estos componentes como contenedores. De la misma forma, Windows no ejecuta Docker nativamente, por debajo crea una VM y ejecuta en Linux.
Pero de una forma u otra necesitarás estar en Linux, sea virtualizado o no. Los contenedores son del mundo Linux.
Minikube crea una máquina virtual ya con un cluster single node. Puede ser usado con varios virtualizadores como VirtualBox, VMware, Hyper-V, etc.
Me gustan bastante las herramientas kind y K3D que utilizan Docker in Docker. Los contenedores actúan "como un sistema operativo con Docker instalado" que levanta más contenedores dentro de él. Contenedor dentro de contenedor. Creando una idea de NODE. Es necesario tener Docker instalado o algún container runtime.
El kubeadm espera que la máquina ya esté aprovisionada. Un buen escenario es tener máquinas virtuales listas para formar un cluster con la herramienta kubeadm, pues este binario espera que las VMs estén aprovisionadas. Puede crear single o múltiples nodos. Vagrant es una excelente opción para automatizar el proceso localmente.
Producción
Existen dos tipos de soluciones
Soluciones Turnkey
Estas son herramientas o scripts que funcionan para crear el cluster. Puedes proporcionar las VMs necesarias y estas herramientas ayudan a configurar el cluster. Eres responsable de mantener las VMs, aplicar parches, actualizaciones, etc.
- Tú aprovisionas las VMs
- Tú configuras las VMs
- Usas las herramientas para desplegar el cluster
- Tú mantienes las VMs
Kubespray y kops serían excelentes ejemplos.
OpenShift sería un ejemplo Cloud Foundry Container Runtime VMware Cloud PKS Vagrant
Soluciones Hosted o Soluciones Gestionadas
Son como Kubernetes as a Service. Generalmente soluciones listas de alguna nube.
- El proveedor aprovisiona las VMs
- El proveedor instala Kubernetes y mantiene las VMs
OpenShift Online AKS GKE EKS
Alta Disponibilidad
¿Qué sucede con el resto del cluster cuando perdemos el master si solo tenemos uno?

Mientras los workers estén funcionando y los contenedores estén ejecutándose, y las aplicaciones estén respondiendo, todo continuará normal hasta que algo comience a fallar.
Si algún contenedor falla no subirá más pues no tenemos los controllers para monitorizarlos y garantizar y avisar al worker que necesita cargar un nuevo pod.
El acceso al cluster a través de las APIs o kubectl no será posible.
Por eso debes considerar más nodos master.
En todos los nodos master deben ejecutarse los mismos componentes de Kubernetes a fin de evitar un único punto de falla.
De la misma forma, los nodos worker con las aplicaciones. Si un nodo worker que ejecuta la aplicación se detiene, todos los pods no estarán disponibles en aquel nodo y comenzará a mover los pods a otro nodo, pero existirá un tiempo de indisponibilidad hasta que todo sea reconocido. Por eso es bueno tener más workers y definir criterios para que las réplicas del mismo pod eviten al máximo estar en el mismo nodo.
Vamos a enfocarnos en el master, sabiendo que necesitamos tener los mismos componentes dentro de ellos.
El kube-apiserver funciona en modo active-active. Esto quiere decir que si apuntamos el kubeconfig para cualquiera de los nodos master tendremos la respuesta. Lo ideal es tener un load balancer frente al cluster que enviará las peticiones de modo balanceado para definir qué kube-apiserver debe responder.
Los otros componentes (kube-controller-manager, kube-scheduler, etcd) del master trabajan en modo active-passive. Esto quiere decir que el líder es quien define las cosas y los otros quedan en modo pasivo verificando si el líder está ejecutándose. En caso de que se detenga, los pasivos entrarán en acción para ser el nuevo líder.
¿Cómo funciona esto?
Cada vez que los componentes active-passive se inician, intentan obtener el endpoint para el componente en cuestión para convertirse en líder.
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
component: kube-controller-manager
tier: control-plane
name: kube-controller-manager
namespace: kube-system
spec:
containers:
- command:
- kube-controller-manager
- --allocate-node-cidrs=true
- --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf
- --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf
- --bind-address=127.0.0.1
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --cluster-cidr=10.244.0.0/16
- --cluster-name=kind-cluster
- --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
- --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
- --controllers=*,bootstrapsigner,tokencleaner
- --enable-hostpath-provisioner=true
- --kubeconfig=/etc/kubernetes/controller-manager.conf
- --leader-elect=true # Habilitación de la elección de líder
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
- --root-ca-file=/etc/kubernetes/pki/ca.crt
- --service-account-private-key-file=/etc/kubernetes/pki/sa.key
- --service-cluster-ip-range=10.96.0.0/16
- --use-service-account-credentials=true
image: registry.k8s.io/kube-controller-manager:v1.29.1
Otros parámetros son default y no especificados aquí
- --leader-elect-lease-duration 15s : que define el tiempo de duración que será el líder
- --leader-elect-renew-deadline 10s : que avisa que intentará renovar para ser el líder cada 10 segundos. O sea, antes de que el lease acabe ya actualiza para 10 segundos después para más 15s
- --leader-elect-retry-period 2s : Es el tiempo que quien no sea el líder verificará si puede ser el nuevo líder.
En el caso del ETCD tenemos la opción de removerlos de los masters y crear un cluster de ETCD (no es otro cluster Kubernetes) llamado external ETCD.
Desplegar el ETCD en los masters y gestionarlo es más fácil con certeza, además de ahorrar recursos. Esta topología con el ETCD dentro de los masters se llama Topología Stacked.
Cuando un nodo master deja de responder la redundancia está comprometida, pero ¿por qué?