Existen diferentes escenarios donde puedes necesitar de un escalado rápido de tu clúster de manera puntual que hace que el despliegue de nuevos nodos pueda no resultar todo lo ágil que demandas. Es por ello que Microsoft anunció hace un tiempo una implementación llamada Virtual Kubelet, la cual permite «hacerse pasar por nodos» a otras tecnologías, como si de uno más se tratara, pero que pueden ser mucho más rápidos y ágiles a la hora de escalar. En este artículo quiero mostrarte cómo funciona Virtual Kubelet usando Azure Container Instances.
Crear un clúster de prueba
Para este ejemplo voy a crear un clúster de un solo nodo, para que nos sea fácil quedarnos sin recursos rápidamente:
# Variables
RESOURCE_GROUP="Kubelet-Demo"
AKS_NAME="returngis"
LOCATION="northeurope"
# Create an AKs cluster
az group create -n $RESOURCE_GROUP -l $LOCATION
az aks create --resource-group $RESOURCE_GROUP --name $AKS_NAME --node-count 1 --generate-ssh-keys
# Get AKS context
az aks get-credentials -n $AKS_NAME -g $RESOURCE_GROUP
Una vez creado y asignado el contexto a kubectl puedes comprobar que tienes un único nodo:
➜ kubectl get nodes
NAME STATUS ROLES AGE VERSION
aks-nodepool1-14445317-vmss000000 Ready agent 6m57s v1.15.11
Desplegar aplicación de prueba
Para ver la utilidad de esto con un ejemplo práctico, voy a lanzar en mi nuevo clúster el siguiente despliegue:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
resources:
requests:
memory: 1.5G
cpu: 1
tolerations:
- key: virtual-kubelet.io/provider
value: azure
effect: NoSchedule
Como ves, en él he establecido por un lado los recursos que necesitan los pods para poder funcionar, un poco altos :D, y por otro los taints que tolera. Para el caso de Virtual Kubelet es necesario que tolere la clave virtual-kubelet.io/provider, como verás más adelante.
Si una vez desplegado recuperas los pods comprobarás que algunos se han quedado pendientes de desplegar porque no tienes más espacio en tu clúster de un solo nodo:
➜ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-65bbbc895f-dprz4 0/1 Pending 0 12s <none> <none> <none> <none>
nginx-deployment-65bbbc895f-gzxsg 0/1 Pending 0 12s <none> <none> <none> <none>
nginx-deployment-65bbbc895f-rbmph 1/1 Running 0 12s 10.244.0.8 aks-nodepool1-14445317-vmss000000 <none> <none>
Como necesito ubicarlos de manera rápida y puntual aquí es donde entra en juego Virtual Kubelet.
Desplegar Virtual Kubelet con el conector para Azure Container Instances
Antes de instalar el conector necesitas tener instalado Helm 2 en el clúster.
#Install Helm 2
brew install helm@2
brew link --force --overwrite helm@2
kubectl create serviceaccount tiller --namespace kube-system
kubectl create clusterrolebinding tiller-role-binding --clusterrole cluster-admin --serviceaccount=kube-system:tiller
helm init --service-account tiller --upgrade
Una vez desplegado, a través de este comando puedes instalar el conector de manera sencilla:
#Install ACI Connector for Kubelet
az aks install-connector --resource-group $RESOURCE_GROUP --name $AKS_NAME --connector-name aciconnector
En realidad aks install-connector lo que hace por debajo es desplegar un chart de Helm, de ahí que lo tengas que tener instalado.
Este proceso también se puede hacer durante la creación del clúster:

Pero quería que vieras primero la necesidad y luego implantarla 🙂
Si ahora recuperas los nodos verás que tienes dos:
➜ kubectl get nodes
NAME STATUS ROLES AGE VERSION
aks-nodepool1-14445317-vmss000000 Ready agent 10m v1.15.11
virtual-kubelet-aciconnector-linux-northeurope Ready agent 34s v1.13.1-vk-v0.9.0-1-g7b92d1ee-dev
Además, como ya te adelante en el apartado anterior, este nuevo nodo tiene un taint asociado, que mis pods ya toleran:
➜ kubectl describe node virtual-kubelet-aciconnector-linux-northeurope
Name: virtual-kubelet-aciconnector-linux-northeurope
Roles: agent
Labels: alpha.service-controller.kubernetes.io/exclude-balancer=true
beta.kubernetes.io/os=linux
kubernetes.io/hostname=virtual-kubelet-aciconnector-linux-northeurope
kubernetes.io/os=linux
kubernetes.io/role=agent
type=virtual-kubelet
Annotations: node.alpha.kubernetes.io/ttl: 0
CreationTimestamp: Fri, 26 Jun 2020 08:36:24 +0200
Taints: virtual-kubelet.io/provider=azure:NoSchedule
El funcionamiento de Virtual Kubelet es sencillo: todos los pods que se han quedado pendiente de desplegar y que toleran este taint serán gestionados por este nodo virtual que, a su vez, utilizará Azure Container Instances para desplegarlos. Si vuelves a recuperar los pods desplegados, comprobarás que los que estaban pendientes ahora están «ejecutándose» en tu nuevo nodo virtual:
➜ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
aciconnector-linux-northeurope-virtual-kubelet-for-aks-5c6wn2c8 1/1 Running 0 71s 10.244.0.10 aks-nodepool1-14445317-vmss000000 <none> <none>
nginx-deployment-65bbbc895f-dprz4 1/1 Running 0 3m1s 20.191.54.101 virtual-kubelet-aciconnector-linux-northeurope <none> <none>
nginx-deployment-65bbbc895f-gzxsg 1/1 Running 0 3m1s 20.54.32.175 virtual-kubelet-aciconnector-linux-northeurope <none> <none>
nginx-deployment-65bbbc895f-rbmph 1/1 Running 0 3m1s 10.244.0.8 aks-nodepool1-14445317-vmss000000 <none> <none>
De hecho, si accedes al grupo de recursos que AKS crea para desplegar sus recursos, comprobarás que tienes dos del tipo Container Instances que se corresponden con el despliegue nginx-deployment:

Si escalas el deployment hacia arriba o hacia abajo verás que el número de container instances irá acorde a tus necesidades, mucho más rápido que si tuvieras que añadir nuevos nodos que solo necesitas de manera puntual.
¡Saludos!

Bootcamp DevOps
Si tienes ganas de meterte en el área de DevOps, formo parte del
equipo de docentes del Bootcamp DevOps Lemoncode, ¿Te animas a
aprender con nosotros?