--- title: "Cómo gestionar varios clústeres de Kubernetes con kubectl" description: "Combina varios kubeconfig en uno, cambia de clúster y namespace con kubectx y kubens, crea accesos limitados y ejecuta comandos en todos tus clústeres." category: "Kubernetes Avanzado" language: es source: https://cubepath.com/es/docs/kubernetes-avanzado/gestion-de-multiples-clusteres-de-kubernetes updated: 2026-09-25 --- # Cómo gestionar varios clústeres de Kubernetes con kubectl Es habitual trabajar con varios clústeres de Kubernetes a la vez: uno de desarrollo y otro de producción, o uno por región. `kubectl` lo resuelve con los contextos del fichero kubeconfig, pero sin orden es fácil lanzar un comando en el clúster equivocado. En este tutorial combinarás los kubeconfig de dos clústeres en uno, cambiarás de clúster y namespace de forma segura con `kubectx` y `kubens`, crearás un kubeconfig de acceso limitado para otra persona o herramienta, y ejecutarás comandos en todos los clústeres a la vez. ## Requisitos previos Para seguir esta guía necesitas: - Acceso de administrador a dos o más clústeres de Kubernetes, por ejemplo desplegados sobre VPS de CubePath en ubicaciones distintas, y el fichero kubeconfig de cada uno. - Una estación de trabajo con Ubuntu 24.04 (o cualquier Linux o macOS) con `kubectl` instalado. En los ejemplos, los clústeres se llaman `dev` y `prod`, y sus kubeconfig originales están en `~/Descargas/dev.yaml` y `~/Descargas/prod.yaml`. Sustitúyelos por tus rutas. ## Cómo está organizado un kubeconfig Un kubeconfig tiene tres listas y un valor activo: | Sección | Contenido | |---|---| | `clusters` | Dirección de la API y certificado de la CA de cada clúster. | | `users` | Credenciales: certificado de cliente, token o plugin de autenticación. | | `contexts` | Combinaciones de un clúster, un usuario y, opcionalmente, un namespace. | | `current-context` | El contexto que usa `kubectl` cuando no indicas otro. | `kubectl` busca la configuración en la variable `KUBECONFIG` (una lista de ficheros separados por `:`) o, si no existe, en `~/.kube/config`. ## Paso 1: Dar nombres únicos a cada kubeconfig Los kubeconfig generados por kubeadm usan siempre los mismos nombres: el clúster se llama `kubernetes`, el usuario `kubernetes-admin` y el contexto `kubernetes-admin@kubernetes`. Si combinas dos ficheros con esos nombres, las entradas del segundo se ignoran en silencio y acabarías con dos contextos apuntando al mismo clúster. Comprueba los nombres de cada fichero: ```bash kubectl --kubeconfig ~/Descargas/dev.yaml config get-contexts ``` ```output CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin ``` Copia cada fichero a `~/.kube/` y edítalo para dar nombres únicos a las tres entradas: ```bash mkdir -p ~/.kube cp ~/Descargas/dev.yaml ~/.kube/dev.yaml cp ~/Descargas/prod.yaml ~/.kube/prod.yaml chmod 600 ~/.kube/dev.yaml ~/.kube/prod.yaml nano ~/.kube/dev.yaml ``` Cambia los nombres en las secciones `clusters`, `users` y `contexts`, y en `current-context`, de modo que queden así (los certificados y la dirección del servidor no se tocan): ```yaml apiVersion: v1 kind: Config clusters: - name: dev cluster: server: https://203.0.113.10:6443 certificate-authority-data: LS0tLS1CRUdJTi... users: - name: dev-admin user: client-certificate-data: LS0tLS1CRUdJTi... client-key-data: LS0tLS1CRUdJTi... contexts: - name: dev context: cluster: dev user: dev-admin current-context: dev ``` Haz lo mismo en `~/.kube/prod.yaml` con los nombres `prod`, `prod-admin` y `prod`. ## Paso 2: Combinar los kubeconfig en uno Haz una copia del fichero actual si ya tienes uno, y genera el fichero combinado. La opción `--flatten` incrusta los certificados para que el resultado no dependa de otros ficheros: ```bash [ -f ~/.kube/config ] && cp ~/.kube/config ~/.kube/config.bak KUBECONFIG=~/.kube/dev.yaml:~/.kube/prod.yaml kubectl config view --flatten > ~/.kube/config.new mv ~/.kube/config.new ~/.kube/config chmod 600 ~/.kube/config ``` Lista los contextos disponibles: ```bash kubectl config get-contexts ``` ```output CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev dev dev-admin prod prod prod-admin ``` Comprueba que cada contexto llega a su clúster con la opción `--context`, que sirve para lanzar un comando en otro clúster sin cambiar el contexto activo: ```bash kubectl --context dev get nodes kubectl --context prod get nodes ``` Cada comando debe devolver los nodos de un clúster distinto. > Consejo: como alternativa a combinar ficheros, puedes dejar cada kubeconfig por separado y añadir `export KUBECONFIG=~/.kube/dev.yaml:~/.kube/prod.yaml` a tu `~/.bashrc`. Así añadir o quitar un clúster es solo tocar un fichero. ## Paso 3: Cambiar de contexto y namespace Con `kubectl` puro, se cambia de clúster y de namespace así: ```bash kubectl config use-context prod kubectl config set-context --current --namespace=kube-system kubectl config current-context ``` ```output Switched to context "prod". Context "prod" modified. prod ``` Los comandos son largos para algo que se hace decenas de veces al día. Las herramientas `kubectx` y `kubens` los simplifican y están en los repositorios de Ubuntu: ```bash sudo apt update sudo apt install kubectx ``` Ahora puedes listar y cambiar contextos y namespaces con órdenes cortas: ```bash kubectx # lista los contextos y marca el activo kubectx dev # cambia al contexto dev kubectx - # vuelve al contexto anterior kubens default # cambia el namespace del contexto actual kubens - # vuelve al namespace anterior ``` Comprueba el resultado: ```bash kubectx -c kubens -c ``` ```output dev default ``` Si instalas también `fzf` (`sudo apt install fzf`), `kubectx` y `kubens` sin argumentos abren un selector interactivo. ## Paso 4: Evitar comandos en el clúster equivocado El error más caro en un entorno multiclúster es aplicar en producción algo pensado para desarrollo. Dos medidas sencillas lo reducen mucho. La primera es ver siempre el contexto activo en el prompt. Añade estas líneas al final de `~/.bashrc`: ```bash nano ~/.bashrc ``` ```bash kube_ctx() { local ctx ctx=$(kubectl config current-context 2>/dev/null) || return printf '[%s] ' "$ctx" } PS1='$(kube_ctx)'"$PS1" ``` Recarga la configuración y comprueba que el prompt muestra el contexto: ```bash source ~/.bashrc ``` ```output [dev] usuario@estacion:~$ ``` La segunda es usar `--context` de forma explícita en scripts y en cualquier operación destructiva sobre producción, en lugar de depender del contexto activo: ```bash kubectl --context prod -n web rollout restart deployment/frontend ``` ## Paso 5: Crear un kubeconfig de acceso limitado No compartas el kubeconfig de administrador con compañeros, pipelines de CI o herramientas de monitoreo. Crea una ServiceAccount con los permisos justos y un kubeconfig propio para ella. En este ejemplo, una cuenta de solo lectura en el clúster `prod`: ```bash kubectl --context prod create serviceaccount readonly -n kube-system kubectl --context prod create clusterrolebinding readonly-view \ --clusterrole=view --serviceaccount=kube-system:readonly ``` El ClusterRole `view` incluido en Kubernetes permite leer la mayoría de objetos pero no los `Secret`. Genera un token con caducidad para la cuenta, en este caso de 30 días: ```bash TOKEN=$(kubectl --context prod create token readonly -n kube-system --duration=720h) ``` > Nota: el servidor de API puede limitar la duración máxima de los tokens. Si necesitas un token sin caducidad para una herramienta, crea un `Secret` de tipo `kubernetes.io/service-account-token` asociado a la cuenta, y tenlo en cuenta al revocar accesos. Extrae la dirección y la CA del clúster `prod` y construye el nuevo kubeconfig: ```bash SERVER=$(kubectl config view --raw -o jsonpath='{.clusters[?(@.name=="prod")].cluster.server}') kubectl config view --raw -o jsonpath='{.clusters[?(@.name=="prod")].cluster.certificate-authority-data}' | base64 -d > prod-ca.crt kubectl config set-cluster prod --kubeconfig=prod-readonly.yaml \ --server="$SERVER" --certificate-authority=prod-ca.crt --embed-certs=true kubectl config set-credentials readonly --kubeconfig=prod-readonly.yaml --token="$TOKEN" kubectl config set-context prod-readonly --kubeconfig=prod-readonly.yaml \ --cluster=prod --user=readonly kubectl config use-context prod-readonly --kubeconfig=prod-readonly.yaml rm prod-ca.crt ``` Comprueba que el acceso funciona para lectura y que se deniega la escritura: ```bash kubectl --kubeconfig=prod-readonly.yaml get pods -A | head -3 kubectl --kubeconfig=prod-readonly.yaml auth can-i create deployments ``` ```output NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-76f75df574-8xk2p 1/1 Running 0 12d kube-system coredns-76f75df574-qz7lw 1/1 Running 0 12d no ``` Entrega `prod-readonly.yaml` por un canal seguro. Para revocar el acceso, borra la ServiceAccount: `kubectl --context prod delete serviceaccount readonly -n kube-system`. ## Paso 6: Ejecutar un comando en todos los clústeres Para revisiones rápidas, un bucle sobre los contextos evita repetir el mismo comando a mano. Por ejemplo, para ver la versión y el estado de los nodos de cada clúster: ```bash for ctx in $(kubectl config get-contexts -o name); do echo "=== $ctx" kubectl --context "$ctx" get nodes -o wide done ``` ```output === dev NAME STATUS ROLES AGE VERSION INTERNAL-IP ... dev-cp-1 Ready control-plane 40d v1.33.4 10.0.0.10 ... === prod NAME STATUS ROLES AGE VERSION INTERNAL-IP ... prod-cp-1 Ready control-plane 90d v1.33.4 10.1.0.10 ... ``` El mismo patrón sirve para buscar pods que no están en `Running` en todos los clústeres: ```bash for ctx in $(kubectl config get-contexts -o name); do echo "=== $ctx" kubectl --context "$ctx" get pods -A --field-selector=status.phase!=Running,status.phase!=Succeeded done ``` Úsalo para consultas. Para desplegar aplicaciones en varios clústeres, es mejor una herramienta declarativa (ver la conclusión) que un bucle de `kubectl apply`. ## Herramientas para flotas más grandes Cuando el número de clústeres crece, conviene pasar de kubeconfig y bucles a herramientas dedicadas: | Herramienta | Para qué sirve | |---|---| | Argo CD (ApplicationSet) o Flux | Desplegar las mismas aplicaciones desde Git en varios clústeres, con estado declarativo. | | Rancher | Interfaz web y gestión centralizada de usuarios, permisos y actualizaciones de muchos clústeres. | | Cluster API | Crear, actualizar y borrar clústeres de forma declarativa con recursos de Kubernetes. | KubeFed (Kubernetes Cluster Federation), que aparece en muchas guías antiguas, fue archivado por el proyecto Kubernetes en 2023 y no debe usarse en instalaciones nuevas. ## Solución de problemas - **Después de combinar, dos contextos muestran los mismos nodos.** Los ficheros originales tenían entradas de clúster o usuario con el mismo nombre. Restaura `~/.kube/config.bak` y repite el paso 1 con nombres únicos. - **`error: You must be logged in to the server (Unauthorized)`.** El certificado de cliente o el token ha caducado. En kubeadm, los certificados del administrador duran un año; renuévalos en el plano de control con `sudo kubeadm certs renew admin.conf` y copia de nuevo `/etc/kubernetes/admin.conf`. - **Helm avisa de que el kubeconfig es legible por el grupo u otros usuarios.** Ejecuta `chmod 600 ~/.kube/config`. ## Conclusión Ahora tienes un único kubeconfig con nombres claros para cada clúster, cambias de contexto y namespace con `kubectx` y `kubens`, ves siempre en el prompt dónde estás trabajando y sabes crear accesos limitados y revocables. Como siguientes pasos, puedes adoptar Argo CD con ApplicationSets para desplegar desde Git en todos tus clústeres, centralizar la autenticación con OIDC en lugar de certificados de cliente, y monitorizar todos los clústeres desde un mismo Grafana.