Despliegue de un Clúster de Kubernetes mediante Binarios y Docker

Especificaciones del Entorno

Esta guía detalla la implemantación de un clúster de Kubernetes (v1.18.2) utilizando binarios oficiales. Se asume un entorno basado en CentOS 7 con kernel actualizado a la rama 5.x para garantizar compatibilidad con Docker CE.

  • Arquitectura de Red: Iptables para kube-proxy y Calico en modo IPIP.
  • IP de Servicio: 10.10.0.1 asignada al servicio interno de Kubernetes.
  • Versiones clave: Docker 19.03.6, Etcd v3.4.7, CoreDNS 1.6.7.
  • Alta Disponibilidad: Implementada mediante balanceadores de carga (SLB en nube o Nginx/Keepalived local).

Preparación de los Nodos

Antes de instalar los componentes del clúster, es imperativo realizar la limpieza y optimización del sistema operativo en todos los nodos (Master y Worker).

# Desactivar firewalls y swap
systemctl stop firewalld && systemctl disable firewalld
swapoff -a
sed -i '/swap/d' /etc/fstab

# Configurar SELinux en modo permisivo o desactivado
setenforce 0
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

A continuación, se presenta un script de automatización (preparar_nodo.sh) para actualizar el kernel e instalar las dependencias de Docker:

#!/bin/bash
# Script: preparar_nodo.sh

ajustar_hostname() {
    local nuevo_nombre=$1
    if [ -n "$nuevo_nombre" ]; then
        hostnamectl set-hostname "$nuevo_nombre"
        echo "127.0.0.1 $nuevo_nombre" >> /etc/hosts
    fi
}

instalar_base() {
    yum install -y nfs-utils curl yum-utils device-mapper-persistent-data lvm2 wget vim conntrack
    # Actualización de Kernel a 5.x
    rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
    yum install -y https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm
    yum --enablerepo=elrepo-kernel install -y kernel-ml
    grub2-set-default 0
}

configurar_docker() {
    yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    yum install -y docker-ce-19.03.6 docker-ce-cli-19.03.6
    mkdir -p /etc/docker
    cat <<EOF > /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {"max-size": "100m"},
  "storage-driver": "overlay2"
}
EOF
    systemctl enable --now docker
}

# Ejecución
ajustar_hostname $1
instalar_base
configurar_docker

Gestión de la Infraestructura de Clave Pública (PKI)

Kubernetes requiere TLS para la comunicación segura entre sus componentes. Utilizaremos cfssl para generar la Entidad Certificadora (CA) y los certificados necesarios.

# Ejemplo de configuración para el certificado del servidor (server-csr.json)
{
    "CN": "kubernetes",
    "hosts": [
      "127.0.0.1",
      "192.168.0.216",
      "192.168.0.217",
      "192.168.0.218",
      "10.10.0.1",
      "lb.k8s.local",
      "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    }
}

Es vital incluir tanto las IPs de los nodos Master como la IP virtual (VIP) del balanceador en el campo hosts.

Despliegue del Almacenamiento Etcd

Etcd es el cerebro del clúster. Configuraremos un clúster de tres nodos con autenticación TLS.

# Estructura de directorios
mkdir -p /opt/kubernetes/{bin,cfg,ssl}

# Configuración de servicio Etcd (etcd.service)
[Unit]
Description=Etcd Service
After=network.target

[Service]
Type=notify
ExecStart=/opt/kubernetes/bin/etcd \
  --name=etcd-01 \
  --data-dir=/var/lib/etcd/default.etcd \
  --listen-peer-urls=https://192.168.0.216:2380 \
  --listen-client-urls=https://192.168.0.216:2379,https://127.0.0.1:2379 \
  --advertise-client-urls=https://192.168.0.216:2379 \
  --initial-advertise-peer-urls=https://192.168.0.216:2380 \
  --initial-cluster=etcd-01=https://192.168.0.216:2380,etcd-02=https://192.168.0.217:2380,etcd-03=https://192.168.0.218:2380 \
  --initial-cluster-token=etcd-cluster-prod \
  --initial-cluster-state=new \
  --cert-file=/opt/kubernetes/ssl/server.pem \
  --key-file=/opt/kubernetes/ssl/server-key.pem \
  --trusted-ca-file=/opt/kubernetes/ssl/ca.pem \
  --peer-cert-file=/opt/kubernetes/ssl/server.pem \
  --peer-key-file=/opt/kubernetes/ssl/server-key.pem \
  --peer-trusted-ca-file=/opt/kubernetes/ssl/ca.pem
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

Componentes del Master: API Server, Scheduler y Controller Manager

El API Server es el punto de entrada. Se debe configurar para utilizar el token de bootstrap para la auto-inscripción de nodos kubelet.

# Ejemplo de flags críticos para kube-apiserver
--service-cluster-ip-range=10.10.0.0/16 \
--token-auth-file=/opt/kubernetes/cfg/token.csv \
--authorization-mode=RBAC,Node \
--kubelet-https=true \
--enable-bootstrap-token-auth=true \
--service-node-port-range=30000-50000

Para el Controller Manager, es fundamental definir el --cluster-cidr (por ejemplo, 10.20.0.0/16) para la asignación de IPs a los Pods.

Configuración de Nodos Worker (Kubelet y Kube-Proxy)

Los nodos de trabajo requieren la configuración de CNI y el archivo bootstrap.kubeconfig para solicitar certificados automáticamente al API Server.

# kubelet-config.yml
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 0.0.0.0
port: 10250
cgroupDriver: systemd
clusterDNS:
  - 10.10.0.2
clusterDomain: cluster.local
authentication:
  anonymous:
    enabled: false
  webhook:
    enabled: true
  x509:
    clientCAFile: /opt/kubernetes/ssl/ca.pem
rotateCertificates: true

El componente Kube-Proxy se encargará del balanceo de carga interno. En este despliegue, utilizaremos el modo iptables.

Complementos de Red y Monitoreo

Una vez que los nodos estén en estado NotReady, instalamos Calico como plugin de red (CNI). Es necesario ajustar el CIDR de Calico para que coincida con el --cluster-cidr definido previamente.

# Aplicación de Calico con almacenamiento Etcd externo
kubectl apply -f calico-etcd.yaml

# Verificación de nodos
kubectl get nodes

Para la resolución de nombres interna, desplegamos CoreDNS, configurando la IP estática 10.10.0.2 como servidor DNS del clúster.

Alta Disponibilidad con Nginx y Keepalived

Si no se dispone de un balanceador de carga en la nube, se puede configurar un par de nodos Nginx para balancear el tráfico del API Server en el puerto 6443.

# Configuración de flujo en nginx.conf
stream {
    upstream k8s-api {
        server 192.168.0.216:6443;
        server 192.168.0.217:6443;
        server 192.168.0.218:6443;
    }
    server {
        listen 6443;
        proxy_pass k8s-api;
    }
}

Keepalived gestionará una IP Virtual (VIP) que saltará entre los balanceadores en caso de fallo, asegurando que los Workers siempre tengan un punto de contacto activo.

Etiquetas: Kubernetes etcd Docker calico CoreDNS

Publicado el 10-10 22:06