Entornos rápidos de desarrollo para Kubernetes con k3s y k3d

Cloud, Seguridad, Tecnología de sistemas

Trevenque Group » Blog » Soluciones Empresariales » Entornos rápidos de desarrollo para Kubernetes con k3s y k3d

Introducción

En anteriores posts repasamos cómo montar Kubernetes y Rancher usando la herramienta rke. Aunque este método, con cambios menores, sigue siendo válido para adaptarlo a las nuevas versiones de las aplicaciones; la realidad es que este procedimiento es engorroso para laboratorios de desarrollo o pruebas rápidas de versiones. En estos casos es necesaria la creación y aprovisionamiento de máquinas virtuales, así como un entorno de red específico y herramientas externas como Loadbalancers que complican algo más el proceso.

Laboratorios rápidos de Kubernetes gracias a k3s y k3d

Para solucionar estos problemas se han ido desarrollando múltiples herramientas de utilidad, que repasamos brevemente a continuación:

  • Vagrant: Es una herramienta del fabricante Hashicorp que permite, con ayuda de un hipervisor tipo VirtualBox/VMware Workstation, desplegar rápidamente máquinas virtuales o Boxes (como se denominan en el argot de Vagrant) y utilizarlas para un desarrollo o laboratorio de forma mucho más ágil. La configuración de Vagrant se realiza mediante Vagrantfiles, que definen de forma declarativa qué sistema operativo, configuración de red y qué provisionamiento tendrá nuestra infraestructura.
  • Multipass VM: Es una herramienta de consola del fabricante Canonical (Ubuntu), que utiliza como backend de virtualización KVM en Linux, pero que bajo Windows/MacOS puede usar Virtualbox. Nativamente corre con Hyper-V bajo Windows e Hyperkit en MacOS. Multipass es la mejor forma de crear máquinas virtuales basadas en Ubuntu dentro de un host Ubuntu. La cli es bastante fácil de manejar y nos permite desplegar instancias rápidamente y probar nuestras aplicaciones de forma ágil.

Dejando de lado herramientas más genéricas para entornos de desarrollo y centrándonos en Kubernetes, han surgido varios proyectos para poder desplegarlo de forma rápida, entre ellos Kind  (Kubernetes in Docker) y k3s (Lightweight Kubernetes by Rancher).

Ambos proyectos nos permiten testear e incluso llevar a producción nuestros desarrollos sobre Kubernetes y contenedores utilizando Docker como base.

Hoy nos centraremos en k3s y en k3d , su wrapper para despliegue rápido.

k3s y k3d

El proyecto k3s es una distribución production ready ligera y certificada de Kubernetes. Está especialmente diseñada para usarse en entornos Edge o con recursos limitados. Esta distribución tiene un consumo de memoria muy reducido y su binario no supera los 100MB. Está especialmente optimizada para entornos ARM64 y ARMv7, aunque puede instalarse también en tu portátil (que es lo que haremos hoy mediante k3d ). Este proyecto, desarrollado inicialmente por Rancher en 2019, ha sido adoptado recientemente por la Cloud Native Computing Foundation.

El proyecto k3d  es un wrapper o manejador que nos permitirá desplegar rápidamente en nuestro portátil clusters de Kubernetes basados en k3s , contando únicamente con Docker instalado.

Os dejamos las webs de k3d y también de k3s para que las tengáis como referencia.

Cómo instalar k3s

La instalación de k3s es bastante fácil. En esta ocasión utilizaremos un portátil con Docker-Desktop instalado y WSL2 bajo Windows, y en la consola correremos el siguiente comando:

# Instalamos k3d
wget -q -O - https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash

# Comprobamos versión instalada de k3d y k3s
❯ k3d version
k3d version v3.4.0
k3s version v1.19.4-k3s1 (default)

Es tan simple como se aprecia, aunque hay distintos métodos de instalación que puedes consultar aquí.

Creando nuestra primera demo con k3s y k3d

Ha llegado el momento de instalar nuestro primer cluster Kubernetes basado en k3s y usando k3d :

# Creando el cluster mediante k3d
❯ k3d cluster create MiPrimerCluster
INFO Created network 'k3d-MiPrimerCluster'
INFO Created volume 'k3d-MiPrimerCluster-images'
INFO Creating node 'k3d-MiPrimerCluster-server-0'
INFO Pulling image 'docker.io/rancher/k3s:v1.19.4-k3s1'
INFO Creating LoadBalancer 'k3d-MiPrimerCluster-serverlb'
INFO Pulling image 'docker.io/rancher/k3d-proxy:v3.4.0'
INFO (Optional) Trying to get IP of the docker host and inject it into the cluster as 'host.k3d.internal' for easy access
INFO Successfully added host record to /etc/hosts in 2/2 nodes and to the CoreDNS ConfigMap
INFO Cluster 'MiPrimerCluster' created successfully!
INFO You can now use it like this:
kubectl cluster-info

# Vamos a ver qué información de cluster tenemos
❯ kubectl cluster-info
Kubernetes master is running at https://0.0.0.0:41671
CoreDNS is running at https://0.0.0.0:41671/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at https://0.0.0.0:41671/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

# Listamos los pods dentro del cluster
❯ kubectl get pods --all-namespaces
NAMESPACE     NAME                                     READY   STATUS      RESTARTS   AGE
kube-system   coredns-66c464876b-9x82l                 1/1     Running     0          48s
kube-system   metrics-server-7b4f8b595-g2l5b           1/1     Running     0          48s
kube-system   local-path-provisioner-7ff9579c6-mqd7r   1/1     Running     0          48s
kube-system   helm-install-traefik-44fpj               0/1     Completed   0          48s
kube-system   svclb-traefik-z6n4v                      2/2     Running     0          19s
kube-system   traefik-5dd496474-c5cjb                  0/1     Running     0          19s

# Listamos los nodos del cluster
❯ kubectl get nodes
NAME                           STATUS   ROLES    AGE   VERSION
k3d-miprimercluster-server-0   Ready    master   89s   v1.19.4+k3s1

# Y por último revisamos qué contenedores está corriendo nuestro sistema
❯ docker ps
CONTAINER ID   IMAGE                      COMMAND                  CREATED         STATUS         PORTS                             NAMES
8664aee7d160   rancher/k3d-proxy:v3.4.0   "/bin/sh -c nginx-pr…"   2 minutes ago   Up 2 minutes   80/tcp, 0.0.0.0:41671->6443/tcp   k3d-MiPrimerCluster-serverlb
eeda6795a095   rancher/k3s:v1.19.4-k3s1   "/bin/k3s server --t…"   2 minutes ago   Up 2 minutes                                     k3d-MiPrimerCluster-server-0

Como podéis ver, k3d ha instalado un cluster basado en la versión 1.19.4 de Kubernetes con k3s  como distribución con un único nodo master ; y para ello ha levantado únicamente dos contenedores, el binario de k3s y un balanceador de acceso a la API. Sí, k3s es una distribución que nos permite tener alta disponibilidad.

Aunque este cluster, tal y como está desplegado, no tiene nodos worker. Vamos a desplegarlo de nuevo:

# Creamos un nuevo cluster llamado 'MySegundoCluster' con dos workers nodes
❯ k3d cluster create MySegundoCluster --agents 2
INFO Created network 'k3d-MySegundoCluster'
INFO Created volume 'k3d-MySegundoCluster-images'
INFO Creating node 'k3d-MySegundoCluster-server-0'
INFO Creating node 'k3d-MySegundoCluster-agent-0'
INFO Creating node 'k3d-MySegundoCluster-agent-1'
INFO Creating LoadBalancer 'k3d-MySegundoCluster-serverlb'
INFO (Optional) Trying to get IP of the docker host and inject it into the cluster as 'host.k3d.internal' for easy access
INFO Successfully added host record to /etc/hosts in 4/4 nodes and to the CoreDNS ConfigMap
INFO Cluster 'MySegundoCluster' created successfully!
INFO You can now use it like this:
kubectl cluster-info

# Listado de nodos vía k3d
❯ k3d node list
NAME                            ROLE           CLUSTER            STATUS
k3d-MySegundoCluster-agent-0    agent          MySegundoCluster   running
k3d-MySegundoCluster-agent-1    agent          MySegundoCluster   running
k3d-MySegundoCluster-server-0   server         MySegundoCluster   running
k3d-MySegundoCluster-serverlb   loadbalancer   MySegundoCluster   running

# Listamos los nodos de nuestro recién creado cluster. 
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
❯ kubectl get nodes
NAME                            STATUS   ROLES    AGE   VERSION
k3d-mysegundocluster-server-0   Ready    master   14s   v1.19.4+k3s1
k3d-mysegundocluster-agent-1    Ready    <none>   8s    v1.19.4+k3s1
k3d-mysegundocluster-agent-0    Ready    <none>   8s    v1.19.4+k3s1

# Listamos pods en todos los namespaces
❯ kubectl get pods --all-namespaces
NAMESPACE     NAME                                     READY   STATUS      RESTARTS   AGE
kube-system   local-path-provisioner-7ff9579c6-clrqf   1/1     Running     0          3m13s
kube-system   coredns-66c464876b-wn4g4                 1/1     Running     0          3m13s
kube-system   metrics-server-7b4f8b595-hdxt4           1/1     Running     0          3m13s
kube-system   helm-install-traefik-mgtjx               0/1     Completed   0          3m13s
kube-system   svclb-traefik-jkl6q                      2/2     Running     0          2m50s
kube-system   svclb-traefik-rb22p                      2/2     Running     0          2m50s
kube-system   svclb-traefik-9kbkb                      2/2     Running     0          2m50s
kube-system   traefik-5dd496474-8lnzz                  1/1     Running     0          2m50s

# Listamos contenedores desplegados en el sistema
❯ docker ps
CONTAINER ID   IMAGE                      COMMAND                  CREATED         STATUS         PORTS                             NAMES
a2f24f35340f   rancher/k3d-proxy:v3.4.0   "/bin/sh -c nginx-pr…"   3 minutes ago   Up 3 minutes   80/tcp, 0.0.0.0:35253->6443/tcp   k3d-MySegundoCluster-serverlb
dc1c3a3e249a   rancher/k3s:v1.19.4-k3s1   "/bin/k3s agent"         3 minutes ago   Up 3 minutes                                     k3d-MySegundoCluster-agent-1
7ab17db2bd9b   rancher/k3s:v1.19.4-k3s1   "/bin/k3s agent"         3 minutes ago   Up 3 minutes                                     k3d-MySegundoCluster-agent-0
5ef980fb5744   rancher/k3s:v1.19.4-k3s1   "/bin/k3s server --t…"   3 minutes ago   Up 3 minutes                                     k3d-MySegundoCluster-server-0

Como vemos, nuestro segundo cluster tiene 2 nodos worker y un nodo master recién desplegados; para docker hemos levantado 4 contenedores distintos, uno con k3s actuando de master y dos como agente (worker), más el balanceador de la API.

¡Y todo esto en apenas 3 minutos!

Ahora vamos a hacer un pequeño despliegue de un servidor nginx  para comprobar el funcionamiento de nuestro cluster:

# Creamos un deploy de nginx con la imagen oficial
❯ kubectl create deployment nginx --image nginx

# Comprobamos los pods
❯ kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6799fc88d8-qljt4   1/1     Running   0          16s

# Vemos `[ está nuestro deployment
❯ kubectl describe pods nginx
Name:         nginx-6799fc88d8-qljt4
Namespace:    default
Priority:     0
Node:         k3d-mysegundocluster-agent-1/172.19.0.4
Start Time:   Tue, 29 Dec 2020 13:53:01 +0100
Labels:       app=nginx
              pod-template-hash=6799fc88d8
Annotations:  <none>
Status:       Running
IP:           10.42.2.4
IPs:
  IP:           10.42.2.4
Controlled By:  ReplicaSet/nginx-6799fc88d8
Containers:
  nginx:
    Container ID:   containerd://df89dd1a62bca942f7a14921d11ed69ffb2cdb99b8617d20884479ae5d748d21
    Image:          nginx
    Image ID:       docker.io/library/nginx@sha256:4cf620a5c81390ee209398ecc18e5fb9dd0f5155cd82adcbae532fec94006fb9
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Tue, 29 Dec 2020 13:53:14 +0100
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-bwnfd (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-bwnfd:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-bwnfd
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  29s   default-scheduler  Successfully assigned default/nginx-6799fc88d8-qljt4 to k3d-mysegundocluster-agent-1
  Normal  Pulling    29s   kubelet            Pulling image "nginx"
  Normal  Pulled     17s   kubelet            Successfully pulled image "nginx" in 11.7347774s
  Normal  Created    17s   kubelet            Created container nginx
  Normal  Started    17s   kubelet            Started container nginx

# Listamos los deployments, pods y servicios de nuestro cluster en su namespace default
❯ kubectl get all
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-6799fc88d8-qljt4   1/1     Running   0          47s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.43.0.1    <none>        443/TCP   16m

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   1/1     1            1           47s

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-6799fc88d8   1         1         1       47s

# Ahora escalaremos nuestro deployment a dos réplicas
❯ kubectl scale --replicas=2 deployment/nginx
deployment.apps/nginx scaled

# Aquí vemos `[ está creando una nueva réplica de nuestro despliegue
❯ kubectl get pods
NAME                     READY   STATUS              RESTARTS   AGE
nginx-6799fc88d8-qljt4   1/1     Running             0          3m51s
nginx-6799fc88d8-f96tx   0/1     ContainerCreating   0          3s

# Y listo, ya está desplegado
❯ kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6799fc88d8-qljt4   1/1     Running   0          4m10s
nginx-6799fc88d8-f96tx   1/1     Running   0          22s

¡Listo! Ya podemos desplegar aplicaciones, testar funcionalidades o simplemente jugar con nuestro nuevo cluster de Kubernetes basado en k3s y desplegado mediante k3d en nuestro equipo local.

¿Te ha gustado? ¡Compártelo!

Logo Trevenque

trevenque group

Ofrecemos un conjunto de servicios completos para que puedas desarrollar tu negocio, gestionar tus datos de manera inteligente y tomar decisiones rentables.

Deja un comentario

Artículos similares

Sigue de cerca la actualidad de Grupo Trevenque y las últimas tendencias tecnológicas y de Business Intelligence.

Ver todas las noticias