Guía de Despliegue de un Clúster Kubernetes con kubeadm

Este documento detalla los pasos necesarios para configurar un clúster de Kubernetes utilizando la herramienta kubeadm. Cubre desde la preparación del sistema operativo hasta la inicialización del clúster y la instalación de una red de Pods, incluyendo soluciones a problemas comunes.

  1. Preparación del Sistema Operativo

Desactivar Firewall

Es fundamental deshabilitar el firewall para evitar conflictos con la comunicación interna del clúster.

sudo systemctl stop firewalld
sudo systemctl disable firewalld

Deshabilitar SELinux

SELinux puede interferir con el funcionamiento de los contenedoers. Se recomienda deshabilitarlo o configurarlo en modo permisivo.

sudo setenforce 0
sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

Desactivar la Memoria Swap

Kubernetes no permite el uso de swap en los nodos. Desactívela temporalmente y de forma permanente.

sudo swapoff -a    # Desactivar temporalmente
free -h            # Verificar estado de la swap
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab # Desactivar permanentemente en fstab

Sincronización Horaria

Una sincronización horaria precisa es crucial para el buen funcionamiento de un clúster distribuido.

sudo systemctl restart chronyd
sudo systemctl enable chronyd

Habilitar bridge-nf-call-iptables

Kubernetes requiere que el tráfico que pasa a través de puentes de red sea procesado por las reglas de iptables para el correcto funcionamiento de los servicios.

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
sudo modprobe br_netfilter
lsmod | grep br_netfilter # Verificar que el módulo esté cargado

Configuración de IPVS (IP Virtual Server)

IPVS ofrece un rendimineto superior a iptables para el balanceo de carga de los servicios de Kubernetes. Para habilitarlo, deben cargarse los módulos kernel necesarios.

# Instalar herramientas requeridas
sudo yum install -y ipset ipvsadm

# Crear un script para cargar módulos IPVS al inicio
cat <<EOF | sudo tee /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF

# Asignar permisos de ejecución al script y ejecutarlo
sudo chmod +x /etc/sysconfig/modules/ipvs.modules
sudo sh /etc/sysconfig/modules/ipvs.modules

# Verificar que los módulos se hayan cargado correctamente
lsmod | grep -e ip_vs -e nf_conntrack_ipv4

Configuración de Nombres de Host en /etc/hosts

Para asegurar una resolución de nombres consistente entre los nodos del clúster, configure el archivo /etc/hosts en cada máquina.

127.0.0.1   localhost
192.168.18.98	k8s-master
192.168.18.99	k8s-node01
192.168.18.100	k8s-node02

  1. Instalación de Entorno Básico

Instalación de Docker

Kubernetes utiliza un motor de contenedores compatible con la Container Runtime Interface (CRI), como Docker.

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo  https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum install -y --setopt=obsoletes=0 docker-ce-19.03.9-3.el7
sudo systemctl start docker

Configuración de Docker

Configure el mirror de descarga de imágenes, la ubicación de los datos de Docker y el controlador de cgroups.

sudo mkdir -p /data/docker /etc/docker
cat << EOF | sudo tee /etc/docker/daemon.json
{
  "registry-mirrors": ["https://gpkhi0nk.mirror.aliyuncs.com"],
  "data-root": "/data/docker",
  "exec-opts": ["native.cgroupdriver=systemd"],
    "log-driver": "json-file",
  "log-opts": {
   "max-size": "100m",
   "max-file": "4"
    }
}
EOF

sudo systemctl daemon-reload
sudo systemctl enable docker
sudo systemctl restart docker

  1. Configuración e Instalación de Kubernetes

Añadir Repositorio YUM de Kubernetes

Configure el repositorio YUM para obtener los paquetes de Kubernetes.

cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyuncs.com/kubernetes/yum/doc/yum-key.gpg
       http://mirrors.aliyuncs.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

Instalar kubelet, kubeadm, kubectl

Instale las herramientas principales de Kubernetes. Es crucial que las versiones de estos paquetes sean consistentes.

# Para ver versiones disponibles:
# sudo yum list kubelet kubeadm kubectl --showduplicates | sort -r

# Instalar una versión específica (ejemplo: 1.20.12)
sudo yum install -y kubelet-1.20.12-0 kubectl-1.20.12-0 kubeadm-1.20.12-0
sudo systemctl enable --now kubelet

Descargar Imágenes de Contenedores de Kubernetes

kubeadm requiere varias imágenes de contenedores para inicializar el clúster. Es recomendable descargarlas previamente, utilizando un mirror si es necesario.

# Listar imágenes requeridas por la versión de kubeadm:
# sudo kubeadm config images list --kubernetes-version v1.20.12

# Descargar y etiquetar imágenes desde un mirror alternativo
IMAGES=(
	kube-apiserver:v1.20.12
	kube-controller-manager:v1.20.12
	kube-scheduler:v1.20.12
	kube-proxy:v1.20.12
	pause:3.2
	etcd:3.4.13-0
	coredns:1.7.0
)

for img in "${IMAGES[@]}"; do
    MIRROR_REGISTRY="registry.cn-hangzhou.aliyuncs.com/google_containers"
    K8S_REGISTRY="k8s.gcr.io"
	sudo docker pull "$MIRROR_REGISTRY/$img"
	sudo docker tag "$MIRROR_REGISTRY/$img" "$K8S_REGISTRY/$img"
	sudo docker rmi "$MIRROR_REGISTRY/$img"
done

Inicialización del Nodo Maestro con kubeadm

Puede inicializar el clúster con parámetros directos o utilizando un archivo de configuración. Aquí se muestra un ejemplo de archivo de configuración que puede personalizar.

# Generar un archivo de configuración de ejemplo (opcional)
# kubeadm config print init-defaults > kubeadm-config.yaml

# Modificar kubeadm-config.yaml según sea necesario
# Asegúrese de que 'advertiseAddress' sea la IP del nodo maestro.
# Revise 'podSubnet' y 'serviceSubnet' para que coincidan con su plan de red.

# Ejemplo de contenido para kubeadm-config.yaml:
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.18.98 # IP del nodo maestro
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/cri-dockerd.sock # Asegúrate que esto coincide con tu CRI
  imagePullPolicy: IfNotPresent
  name: k8s-master # Nombre del nodo
  taints: null
---
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.20.12 # Versión de Kubernetes
networking:
  dnsDomain: cluster.local
  podSubnet: 172.244.0.0/16 # Rango de IPs para los Pods
  serviceSubnet: 172.100.0.0/16 # Rango de IPs para los Servicios
scheduler: {}
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd # Importante: debe coincidir con el driver de cgroups de Docker

Para la inicialización, puede usar el comando directamente (si no quiere usar un archivo YAML):

sudo kubeadm init \
--apiserver-advertise-address=$(hostname -I | awk '{print $1}') \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.20.12 \
--service-cidr=172.100.0.0/16 \
--pod-network-cidr=172.244.0.0/16 \
--upload-certs \
--control-plane-endpoint "k8s-master:6443" # Reemplazar con el nombre de host o IP del master si es un setup HA

Verificación y Configuración de kubectl

Tras una inicialización exitosa, siga las instrucciones proporcionadas por kubeadm para configurar kubectl.

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

Permitir la Ejecución de Pods en el Nodo Maestro (Opcional)

Por defecto, el nodo maestro tiene un "taint" que impide la ejecución de Pods. Si desea que el maestro también ejecute cargas de trabajo, puede eliminar este taint:

kubectl taint nodes --all node-role.kubernetes.io/master-
# O para versiones más recientes, donde el taint podría ser diferente:
# kubectl taint nodes --all node-role.kubernetes.io/control-plane-

Instalación de un Plugin de Red de Pods

Un clúster de Kubernetes necesita un CNI (Container Network Interface) para la comunicación entre Pods. Elija uno de los siguientes:

Flannel

mkdir -p /data/k8s/yaml/kube-system
cd /data/k8s/yaml/kube-system
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl create -f kube-flannel.yml

Calico

# Descargar el manifiesto de Calico
curl https://docs.projectcalico.org/manifests/calico.yaml -O

# Modificar el manifiesto (si es necesario):
# 1. Asegúrese de que el CIDR de la red de Pods (CALICO_IPV4POOL_CIDR) coincida con --pod-network-cidr
#    utilizado en kubeadm init.
# 2. Configure la interfaz de red para la autodetección de IP (IP_AUTODETECTION_METHOD),
#    por ejemplo, para 'eth0'.
#    Busque la sección 'CLUSTER_TYPE' y añada:
#    - name: IP_AUTODETECTION_METHOD
#      value: "interface=eth0"

# Aplicar el manifiesto
kubectl apply -f calico.yaml

Weave Net

kubectl apply -f https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')

Verificar el Estado del Clúster

Una vez instalado el plugin de red, todos los nodos deberían aparecer como "Ready".

kubectl get nodes
kubectl get pods -A

Autocompletado de Comandos kubectl

Mejore la experiencia de usuario con el autocompletado para kubectl.

sudo yum install -y bash-completion
echo "source /usr/share/bash-completion/bash_completion" | sudo tee -a /etc/profile
echo "source <(kubectl completion bash)" | sudo tee -a /etc/profile
source /etc/profile # Aplicar cambios en la sesión actual

Espacios de Nombres por Defecto en Kubernetes

Kubernetes crea algunos namespaces automáticamente para organizar los recursos del sistema.

kubectl get namespace

  • default: Para recursos no asignados explícitamente a un namespace.
  • kube-node-lease: Utilizado para la detección de latidos (heartbeat) de los nodos.
  • kube-public: Accesible por todos los usuarios, incluyendo los no autentciados.
  • kube-system: Contiene los recursos creados por el sistema de Kubernetes.
  1. Solución de Problemas y Operaciones Comunes

Gestionar el Token de Unión al Clúster

Si olvida el token o este expira, puede listarlos o generar uno nuevo.

# Listar tokens existentes
sudo kubeadm token list

# Generar un nuevo token y el comando de unión
sudo kubeadm token create --print-join-command

Obtener el Hash SHA256 del Certificado CA

Necesario para unir nodos de forma segura si el token es antiguo o no se tiene acceso al comando original.

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

Unión de Nodos al Clúster

Utilice el comando kubeadm join proporcionado al inicializar el maestro o generado posteriormente.

sudo kubeadm join 192.168.18.98:6443 --token zxgoub.q7pcbx3s2dfrwywd \
    --discovery-token-ca-cert-hash sha256:639f9093b1250954edff0f11544860ed4b491c04678e70b343a0d378f8330117

Solución de Problemas Comunes

  • Bloqueo en "Running pre-flight checks": Comúnmente causado por problemas de sincronización horaria o tokens expirados. Verifique el estado de chronyd y genere un nuevo token si es necesario.
  • Puerto 10250 en uso: Si un nodo no se une correctamente debido a que un puerto está en uso, o si necesita restablecer un nodo por completo:
# Ejecutar en el nodo que se desea restablecer
sudo kubeadm reset --force
sudo systemctl stop kubelet
sudo systemctl stop docker
sudo rm -rf /var/lib/cni/
sudo rm -rf /var/lib/kubelet/*
sudo rm -rf /etc/cni/
sudo ifconfig cni0 down
sudo ifconfig flannel.1 down
sudo ifconfig docker0 down
sudo ip link delete cni0
sudo ip link delete flannel.1
sudo systemctl restart kubelet
sudo systemctl restart docker

Después de ejecutar el reinicio, intente nuevamente el comando kubeadm join.

Etiquetas: Kubernetes kubeadm Docker kubectl centos

Publicado el 6-13 16:04