Saltar a contenido

🚀 Instalación de un nodo de Kubernetes paso a paso

En este artículo vamos a desplegar un nodo de Kubernetes desde cero utilizando herramientas estándar como kubeadm, kubelet y kubectl, junto con el runtime CRI-O. Todo el proceso está basado en una instalación manual, ideal para entender qué ocurre en cada capa del sistema.


🖥️ Preparación inicial del sistema

En mi caso he usado una máquina virtual con Debian 13 en proxmox, por lo que instalo el agente de qemu y habilito el ssh para conectarme remotamente:

apt install qemu-guest-agent
apt install openssh-server
apt install vim
apt update && apt upgrade

Configurar SSH es fundamental para administrar el nodo remotamente. Tras editar /etc/ssh/sshd_config, reiniciamos el servicio:

systemctl restart sshd
systemctl status sshd

También es recomendable establecer una contraseña segura:

passwd

Y comprobar la red:

ip a

⚙️ Configuración del sistema para Kubernetes

Kubernetes requiere ciertos ajustes a nivel de kernel y red.

🔴 Desactivar swap

Kubernetes no funciona correctamente con swap activo:

swapoff -a
cat /etc/fstab

🌐 Habilitar módulos del kernel

Necesitamos cargar módulos clave para networking:

modprobe br_netfilter
modprobe overlay

Verificamos:

lsmod | grep br_netfilter
lsmod | grep overlay

Los persistimos:

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

🔧 Configurar parámetros de red

Configuramos sysctl para permitir el tráfico entre pods:

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

Aplicamos los cambios:

sysctl --system
sysctl net.ipv4.ip_forward

🔌 Instalación de plugins CNI

Los plugins CNI permiten la comunicación entre pods.

apt install wget htop btop curl net-tools
wget https://github.com/containernetworking/plugins/releases/download/v1.8.0/cni-plugins-linux-amd64-v1.8.0.tgz

Verificamos la integridad:

echo "ab3bda535f9d90766cccc90d3dddb5482003dd744d7f22bcf98186bf8eea8be6 cni-plugins-linux-amd64-v1.8.0.tgz" | sha256sum --check

Instalamos:

mkdir -p /opt/cni/bin
tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.8.0.tgz

🐳 Instalación de CRI-O y Kubernetes

Definimos versiones:

KUBERNETES_VERSION=v1.35
CRIO_VERSION=v1.35

Añadimos repositorios:

apt install gpg

curl -fsSL https://pkgs.k8s.io/core:/stable:/$KUBERNETES_VERSION/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/$KUBERNETES_VERSION/deb/ /" | tee /etc/apt/sources.list.d/kubernetes.list

curl -fsSL https://download.opensuse.org/repositories/isv:/cri-o:/stable:/$CRIO_VERSION/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/cri-o-apt-keyring.gpg

echo "deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg] https://download.opensuse.org/repositories/isv:/cri-o:/stable:/$CRIO_VERSION/deb/ /" | tee /etc/apt/sources.list.d/cri-o.list

Instalamos componentes:

apt update
apt-get install -y cri-o kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl

▶️ Arranque de servicios

Activamos los servicios necesarios:

systemctl enable --now kubelet
systemctl start crio.service
systemctl enable crio.service

🧠 Inicialización del cluster

Creamos el cluster con kubeadm:

kubeadm init --pod-network-cidr=10.244.0.0/16

El parámetro --pod-network-cidr es importante para que el plugin de red (en este caso Flannel) funcione correctamente.


🔑 Configuración de kubectl

Para poder interactuar con el cluster:

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

Verificamos:

kubectl get nodes

🌐 Despliegue de red (Flannel)

Instalamos Flannel como solución de red:

kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

🔍 Despliegue de metrics-server

Instalamos metrics-server para poder monitorizar el cluster:

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

En mi caso, quiero correr pods en el nodo control-plane, por lo que hago lo siguiente:

kubectl taint nodes k8s-cluster node-role.kubernetes.io/control-plane:NoSchedule-
Y le añado tambien un parámetro para que no se queje del certificado TLS:

kubectl edit deployment metrics-server -n kube-system
    spec:
      containers:
      - args:
        - --cert-dir=/tmp
        - --secure-port=10250
        - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
        - --kubelet-use-node-status-port
        - --metric-resolution=15s
        - --kubelet-insecure-tls     # <--- AQUI


👀 Verificación del cluster

Comprobamos el estado de todos los recursos:

kubectl get all -A
kubectl get nodes