Card image cap

Instalación de Kubernetes y Docker en Debian

by Josep Llauradó Selvas


Posted on 2020-11-18


En esta sencilla guia veremos como se puede realizar la instalación de un cluster kubernetes y docker, usando como sistema operativo Debian.

 

Qué es Kubernetes o Docker?

Si estas leyendo estas líneas mejor no sigas, este artículo no es para tí… :-) pero te emplazo a un artículo para gente no-muy-técnica en un futuro próximo (añadiré el link aquí, así como lo publicaré en LinkedIn/Twitter, of course!)

Consideraciones iniciales

Estamos partiendo de un escenario en el que tenemos la voluntad de crear cluster Kubernetes para poder lanzar cargas al mismo a partir de imágenes Docker. En mi caso no soy un experto en estas tecnologías, con lo que cualquier mejora que reciba en comentarios será bienvenida. Esta entrada es la guía que yo he estado usando y elaborando para conseguir que un cluster funcione correctamente, con lo que seguro que es mejorable en múltiples aspectos.

Como configuración inicial partimos de una maquina limpia con Debian básica (sin interfaz gráfica, please!). En mi caso he preparado una configuración mínima recomendada de 3 nodos iguales. Cada uno de ellos tiene SSH, con sus respectivas claves, y he verificado que MACs, UUIDs de maquinas, etc. sean diferentes (si estas usando virtualización y has clonado de forma estándar las maquinas será así).

A partir de ahí he configurado el /etc/hosts para facilitar la visibilidad entre ellas fácilmente y he creado usuarios básicos + sudo para escalar a root sin complicaciones.

1. Instalación

Despues de entrar en una de las 3 máquinas, empezaremos por instalar paquetería básica, ya comentada, asi como habitar el bridge en el FW para que las maquinas tengan visibilidad desde fuera:

# apt-get install curl ssh sudo
# apt-get install xfsprogs
# apt-get install net-tools
# cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
#sudo sysctl --system

A continuación añadimos los repositorios de kubernetes oficiales para Debian e instalamos kubernetes:

# sudo apt-get update 
# sudo apt-get install -y apt-transport-https
# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
# echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
# sudo apt-get update --allow-insecure-repositories
# sudo apt-get install -y kubectl --allow-unauthenticated
# sudo apt-get install kubelet kubeadm docker-engine

Por lo que ví, es muuuuuy importante mantener alineadas las versiones de kubernetes, así que congelamos el upgrade de versiones por si acaso:

# apt-mark hold kubelet kubeadm kubectl

Y finalmente añadimos los repositorios de docker, verificamos que no tenemos docker instalado (versiones antiguas de los repos de Debian) e instalamos las nuevas:

# apt-get install \
   apt-transport-https \
   ca-certificates \
   curl \
   gnupg-agent \
   software-properties-common
# curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
# add-apt-repository \
  "deb [arch=amd64] https://download.docker.com/linux/debian \
  $(lsb_release -cs) \
  stable"
# apt-get remove docker docker-engine docker.io containerd runc
# apt-get install docker-ce docker-ce-cli containerd.io
 

2. Configuración

2.1 Almacenamiento de pods

Creamos puntos de montaje nuevos con XFS, dado que es el FS recomendado. En nuestro caso creamos un volumen LVM específico; esta configuración se tendrá que hacer en los 3 nodos:

# fdisk /dev/sdb
<-> Configuramos una partición primaria tipo 8e quedando:
Disk 		     Start     Final   Sectors Size Id Type
/dev/sdb1             2048 104857599 104855552  50G 8e Linux LVM

# vgcreate dockerdata /dev/sdb1
  Physical volume "/dev/sdb1" successfully created.
  Volume group "dockerdata" successfully created

# lvcreate dockerdata -l 99%VG -n data1
 Logical volume "data1" created.

# lvdisplay
 --- Logical volume ---
 LV Path                /dev/dockerdata/data1
 LV Name                data1
 VG Name                dockerdata
 LV UUID                ZRIzYl-CbQB-Ph3q-W1CJ-KUJq-dSZA-3rSSCu
 LV Write Access        read/write
 LV Creation host, time io50, 2020-11-12 15:46:47 +0100
 LV Status              available
 # open                 0
 LV Size                <49,50 GiB
 Current LE             12671
 Segments               1
 Allocation             inherit
 Read ahead sectors     auto
 - currently set to     256
 Block device           254:5

# rm -fr /var/lib/docker
# mkdir /var/lib/docker

# mkfs.xfs /dev/mapper/dockerdata-data1
meta-data=/dev/mapper/dockerdata-data1 isize=512    agcount=4, agsize=3243776 blks
        =                       sectsz=512   attr=2, projid32bit=1
        =                       crc=1        finobt=1, sparse=1, rmapbt=0
        =                       reflink=0
data     =                       bsize=4096   blocks=12975104, imaxpct=25
        =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=6335, version=2
        =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

# mount /dev/mapper/dockerdata-data1 /var/lib/docker
# vi /etc/docker/daemon.json
{
       "exec-opts": ["native.cgroupdriver=systemd"],
       "log-driver": "json-file",
       "log-opts": {
               "max-size": "100m"
       },
       "storage-driver": "overlay2"
}

# kubeadm reset

2.2 Red

Para configurar la red usaremos calico. Primero pero verificaremos que tenemos el ip_forward habilitado (editando o usando el comando) y reiniciaremos:

# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf

Para ello, en el nodo principal, ejecutaremos las siguientes instrucciones:

# curl https://docs.projectcalico.org/manifests/calico.yaml -O
# kubectl apply -f calico.yaml

2.3 Almacenamiento persistente

Los pods en principio son imagenes de lectura/escritura sin persistencia. Esto implica que si se muere un pod se recrea a partir de una imagen base y se levanta, pero claro, si la imagen es de una BBDD perderemos los datos!

Para evitar esta situación existe el almacenamiento persistente. Para ello nosotros usaremos NFS:

En el servidor master:

# apt-get install nfs-kernel-server
....
# mkdir /var/local/exports/volume1
# vi /etc/exports
/var/local/nfs/sapwm2data io51(rw,sync,no_subtree_check) io52(rw,sync,no_subtree_check)

Y en los nodos secundarios:

# apt-get install nfs4-acl-tools nfs-common
...
# showmount -e io50
Export list for io50:
/var/local/exports/volume1 io52,io51

 

3. Inicio de servicios

Para arrancar el cluster Kubernetes empezaremos con el primer nodo de los 3, que será el master, y despues pasaremos al resto:

# kubeadm init
....
Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

 mkdir -p $HOME/.kube
 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
 sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
 https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.18.25:6443 --token 3zx8jw.6uebcoq2ku9nbttk \
   --discovery-token-ca-cert-hash sha256:a184c9849f4297141bbe11f254017946355a171875ad5ce0f8e143399a33e9c4

Ahora debemos unir los nodos restantes al cluster Kubernetes. Para ello ejecutaremos el comando que nos propone en las últimas lineas de la ejecución de kubeadm init en el resto de nodos:

# Copia de docker/daemon.json a todos los otros nodos

# kubeadm join 192.168.18.25:6443 --token 3zx8jw.6uebcoq2ku9nbttk \
   --discovery-token-ca-cert-hash sha256:a184c9849f4297141bbe11f254017946355a171875ad5ce0f8e143399a33e9c4

Finalmente, copiaremos el fichero de config a nuestro usuario local (no tiene que ser root) para poder controlar el master de kubernetes:

As user:
# cp /etc/kubernetes/admin.conf .
# export KUBECONFIG=/root/admin.conf

4. Comandos de control

Visualización del status:

# kubectl get nodes
NAME   STATUS     ROLES    AGE   VERSION
io50   NotReady   master   47m   v1.19.4
io51   NotReady   <none>   43m   v1.19.4
io52   NotReady   <none>   43m   v1.19.4

Ver deployments:

root@io50:/var/local/src/sapwm2# kubectl get deployments
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
db     0/1     1            0           26m
web    0/1     1            0           26m

Start a pod:

root@io50:/var/local/src/sapwm2# kubectl run sapwm2-db --image=db
pod/db created
root@io50:/var/local/src/sapwm2# kubectl run sapwm2-web --image=web
pod/web created

View pods:

root@io50:/var/local/src/sapwm2# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
sapwm2-db              0/1     Pending   0          41s
sapwm2-web             0/1     Pending   0          49s

 

homepage
Leave a Comment:


BeyondBlueSky - 2019

Website developed using Symfony 5, Bootstrap 4 and Open Iconic