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.
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!)
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.
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 --systemA 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-enginePor 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
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
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.confPara ello, en el nodo principal, ejecutaremos las siguientes instrucciones:
# curl https://docs.projectcalico.org/manifests/calico.yaml -O
# kubectl apply -f calico.yamlLos 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
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:a184c9849f4297141bbe11f254017946355a171875ad5ce0f8e143399a33e9c4Ahora 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:a184c9849f4297141bbe11f254017946355a171875ad5ce0f8e143399a33e9c4Finalmente, 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.confVisualizació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.4Ver 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 26mStart 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 createdView 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
BeyondBlueSky - 2019
Website developed using Symfony 5, Bootstrap 4 and Open Iconic