Introducción
Gestionar decenas de clústeres Kubernetes con control planes dedicados por cluster rápidamente se vuelve insostenible: cada nuevo clúster requiere al menos tres nodos solo para el control plane (API Server, etcd, controladores), multiplicando costos de infraestructura, complejidad operativa y puntos de falla. La solución es adoptar Hosted Control Planes (HCP): un único clúster de gestión centraliza todos los control planes de los clústeres de trabajo, eliminando la redundancia de recursos y simplificando upgrades y monitoreo.
En esta guía, implementarás una plataforma Kubernetes escalable sobre OpenStack usando:
- k0s: distribución minimalista de Kubernetes para el clúster de gestión.
- k0rdent: operador de Kubernetes que gestiona el ciclo de vida de clústeres de forma declarativa.
- OpenStack: proveedor de IaaS para aprovisionar nodos de trabajo.
El resultado es un sistema reproducible, auditables y versionado, donde cada nuevo clúster se define como código y se aprovisiona automáticamente sin intervención manual.
Qué es y para qué sirve
Hosted Control Planes (HCP)
Los HCP centralizan la infraestructura crítica de los clústeres (API Server, etcd, controladores) en un único clúster de gestión. Esto reduce:
- Costos: Menos VMs necesarias (solo nodos de trabajo por clúster).
- Complejidad: Un solo punto de control para upgrades, backups y políticas.
- Consistencia: Todos los clústeres siguen el mismo patrón de configuración.
k0s + k0rdent
- k0s: Distribución de Kubernetes diseñada para entornos edge, IoT y clústeres pequeños/medianos. Es liviana (binario único de ~50MB) y no requiere contenedores para arrancar (usa procesos nativos).
- k0rdent: Operador de Kubernetes que automatiza el ciclo de vida de clústeres. Permite definir clústeres como recursos CRD (
ClusterDeployment), donde k0rdent se encarga de:
– Instalar k0s en los nodos de trabajo.
– Configurar el clúster final y exponer su kubeconfig.
Prerequisitos
Versiones de software
| Componente | Versión mínima | Notas |
|---|---|---|
| Kubernetes | 1.28+ | Para el clúster de gestión. |
| k0s | v1.29.0+ | Distribución ligera. |
| k0rdent | v0.6.0+ | Operador de gestión de clústeres. |
| Helm | v3.12.0+ | Para instalar k0rdent. |
| OpenStack CLI | 6.0+ | Con acceso a la API. |
| kubectl | v1.28.0+ | Cliente de Kubernetes. |
- Acceso a OpenStack:
clouds.yaml (ver sección de configuración).– Rol en OpenStack con permisos para crear VMs, redes y volúmenes.
– Archivo openrc.sh para autenticación por CLI (opcional, pero recomendado para pruebas).
- Permisos en Kubernetes:
– Permisos para crear ClusterDeployment, Secrets y Services en el namespace kcm-system.
- Herramientas locales:
– jq y yq (para manipular archivos YAML/JSON desde la terminal).
Guía paso a paso
1. Configurar el entorno base
Instalar herramientas locales
# Linux (Debian/Ubuntu)
sudo apt-get update && sudo apt-get install -y \
kubectl=1.28.0-00 \
helm=3.12.0-1 \
jq yq
# macOS (Homebrew)
brew install [email protected] helm@3 jq yqConfigurar acceso a OpenStack
- Obtén tu archivo
clouds.yamldesde el dashboard de OpenStack o mediante:
openstack config download --os-cloud <nombre_cloud> --output clouds.yaml
El archivo debe tener un formato como este:
clouds:
mi-openstack:
auth:
auth_url: https://keystone.example.com:5000/v3
username: "tu-usuario"
password: "tu-contraseña"
project_name: "tu-proyecto"
user_domain_name: "Default"
project_domain_name: "Default"
region_name: "RegionOne"
interface: "public"
identity_api_version: 3
- Verifica el acceso:
openstack --os-cloud mi-openstack server list
Instalar k0s en modo local (para el clúster de gestión)
k0s es ideal para el clúster de gestión porque:
- No requiere contenedores para arrancar (usa procesos nativos).
- Es liviano (~50MB) y fácil de actualizar.
- Descarga y ejecuta k0s en modo single node (para pruebas):
curl -sSLf https://get.k0s.sh | sudo sh
sudo k0s install controller --single
sudo k0s start
- Espera 30-60 segundos y exporta el kubeconfig:
sudo k0s kubeconfig admin > ~/.kube/config-k0s-management
export KUBECONFIG=~/.kube/config-k0s-management
- Verifica el clúster:
kubectl get nodes
Resultado esperado: NAME STATUS ROLES AGE VERSION
node1 Ready <none> 1m v1.29.0+k0s
2. Instalar k0rdent en el clúster de gestión
k0rdent es un operador de Kubernetes que gestiona el ciclo de vida de clústeres. Se instala via Helm.
- Agrega el repositorio de Helm de k0rdent:
helm repo add k0rdent https://charts.k0rdent.io
helm repo update
- Instala el operador en el namespace
kcm-system:
kubectl create namespace kcm-system
helm install k0rdent k0rdent/k0rdent \
--namespace kcm-system \
--version 0.6.0 \
--set controllerManager.manager.image.tag=v0.6.0
- Verifica que los pods estén en estado
Running:
kubectl get pods -n kcm-system -w
Resultado esperado: NAME READY STATUS RESTARTS AGE
k0rdent-controller-manager-1 2/2 Running 0 1m
3. Configurar credenciales de OpenStack para k0rdent
k0rdent necesita credenciales para aprovisionar VMs en tu entorno OpenStack.
- Crea un
Secretcon las credenciales en formatoclouds.yaml:
# k0rdent-openstack-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: openstack-credentials
namespace: kcm-system
type: Opaque
stringData:
clouds.yaml: |
clouds:
mi-openstack:
auth:
auth_url: "https://keystone.example.com:5000/v3"
username: "tu-usuario"
password: "tu-contraseña"
project_name: "tu-proyecto"
user_domain_name: "Default"
project_domain_name: "Default"
region_name: "RegionOne"
interface: "public"
identity_api_version: 3
- Aplica el manifiesto:
kubectl apply -f k0rdent-openstack-secret.yaml
- Configura el
CloudProviderpara que k0rdent use las credenciales:
# k0rdent-cloudprovider.yaml
apiVersion: k0rdent.mirantis.com/v1beta1
kind: CloudProvider
metadata:
name: openstack-provider
namespace: kcm-system
spec:
provider: openstack
secretRef:
name: openstack-credentials
namespace: kcm-system
- Aplica la configuración:
kubectl apply -f k0rdent-cloudprovider.yaml
4. Definir y aprovisionar un clúster de trabajo
Definir el clúster como código
k0rdent usa recursos ClusterDeployment para definir clústeres de forma declarativa.
- Crea un manifiesto para un clúster de trabajo con:
– 2 nodos de trabajo.
– Usando k0s como distribución.
# cluster-worker.yaml
apiVersion: k0rdent.mirantis.com/v1beta1
kind: ClusterDeployment
metadata:
name: worker-cluster-1
namespace: kcm-system
spec:
clusterName: worker-cluster-1
kubernetesVersion: "v1.29.0+k0s"
controlPlane:
replicas: 1
machineSpec:
image: "ubuntu-22.04"
flavor: "m1.medium"
workers:
machineSpec:
image: "ubuntu-22.04"
flavor: "m1.large"
replicas: 2
provider: openstack-provider
- Aplica el manifiesto:
kubectl apply -f cluster-worker.yaml
Verificar el aprovisionamiento
- Observa la creación de recursos en Kubernetes:
kubectl get clusterdeployments -n kcm-system -w
Resultado esperado: NAME CLUSTER NAME STATUS AGE
worker-cluster-1 worker-cluster-1 Creating 1m
- Monitorea la creación de VMs en OpenStack:
openstack server list --name worker-cluster-1
Resultado esperado: +--------------------------------------+---------------------+--------+----------------+--------------+
| ID | Name | Status | Networks | Image |
+--------------------------------------+---------------------+--------+----------------+--------------+
| 550e8400-e29b-41d4-a716-446655440000 | worker-cluster-1-cp | ACTIVE | net=10.0.0.0 | ubuntu-22.04 |
+--------------------------------------+---------------------+--------+----------------+--------------+
- Una vez que el clúster esté listo, k0rdent crea un
Secretcon el kubeconfig:
kubectl get secrets -n kcm-system
Resultado esperado: NAME TYPE DATA AGE
worker-cluster-1-kubeconfig Opaque 1 2m
- Descarga el kubeconfig y verifica el clúster:
kubectl get secret worker-cluster-1-kubeconfig -n kcm-system -o jsonpath='{.data.value}' | base64 -d > ~/.kube/config-worker-cluster-1
export KUBECONFIG=~/.kube/config-worker-cluster-1
kubectl get nodes
Resultado esperado: NAME STATUS ROLES AGE VERSION
worker-cluster-1-worker1 Ready <none> 1m v1.29.0+k0s
worker-cluster-1-worker2 Ready <none> 1m v1.29.0+k0s
5. Probar escalabilidad declarativa
Modifica el manifiesto cluster-worker.yaml para escalar los nodos de trabajo a 3:
# cluster-worker.yaml (modificado)
spec:
workers:
replicas: 3 # Cambiado de 2 a 3Aplica el cambio:
kubectl apply -f cluster-worker.yamlVerifica en OpenStack:
openstack server list --name worker-cluster-1Resultado esperado: Aparece una nueva VM worker-cluster-1-worker3.Consideraciones y buenas prácticas
Limitaciones conocidas
- k0s en HCP: k0s no soporta oficialmente HCP en producción. Esta guía usa k0s para el clúster de gestión, pero para clústeres de trabajo críticos, considera usar k3s (con soporte para HCP en Mirantis) o RKE2 (de Rancher).
- OpenStack: k0rdent depende de que OpenStack tenga imágenes y flavors compatibles. Valida que:
cloud-init instalado.– El flavor tenga al menos 2GB de RAM (k0s requiere recursos mínimos).
- Redes: Asegúrate de que los nodos de trabajo puedan comunicarse con el clúster de gestión (puertos necesarios: 6443 para el API Server, 2379-2380 para etcd).
Alternativas
| Componente | Alternativa | Cuándo usarla |
|---|---|---|
| k0s | k3s | Si necesitas soporte nativo para HCP. |
| k0rdent | Cluster API | Para entornos multi-cloud (AWS, GCP). |
| OpenStack | AWS/GCP | Si buscas evitar OpenStack. |
- Versionado: Guarda los manifiestos
ClusterDeploymenten un repositorio Git con tags semánticos (ej:v1.0.0). - Backups: El clúster de gestión debe tener backups automáticos de etcd (usa
k0s etcd saveo herramientas comovelero). - Políticas: Usa
PodSecurityPolicyoGatekeeperpara enforzar políticas en los clústeres de trabajo. - Monitoreo: Integra Prometheus + Grafana para monitorear:
– Estado de los nodos de trabajo (CPU, memoria, discos).
Conclusión
Con esta arquitectura:
- Reduces costos: Elimina la necesidad de 3 VMs por clúster.
- Simplificas operaciones: Un solo clúster gestiona todos los control planes.
- Escalas declarativamente: Añadir o modificar clústeres es una operación de código, no manual.
El stack k0s + k0rdent + OpenStack es ideal para equipos de plataforma que buscan:
- Un clúster de gestión liviano (k0s).
- Gestión declarativa de clústeres (k0rdent).
- Integración con infraestructura existente (OpenStack).
Para profundizar:
FIN
