kubectl es la herramienta de línea de comandos oficial para hablar con la API de un clúster de Kubernetes: con ella consultas recursos, aplicas manifiestos, lees logs y depuras pods. En este tutorial instalarás kubectl en Ubuntu 24.04, lo conectarás a un clúster y recorrerás los comandos que se usan a diario con un ejemplo real: un Deployment de Nginx que crearás, expondrás, escalarás, actualizarás y depurarás.
Requisitos previos
- Una máquina con Ubuntu 24.04 LTS desde la que administrar el clúster (tu equipo o un VPS de CubePath) y un usuario con privilegios
sudo. - Acceso a un clúster de Kubernetes y su archivo kubeconfig. Sirve un clúster gestionado, uno creado con kubeadm o un clúster de pruebas con k3s.
- Permisos en el clúster para crear recursos en un namespace (los ejemplos usan uno propio llamado
demo).
La sintaxis general de kubectl es siempre la misma:
kubectl <verbo> <tipo> [nombre] [opciones]
Por ejemplo, kubectl get pods -n demo o kubectl describe deployment web. Si dudas de un comando, kubectl <verbo> --help muestra todas sus opciones con ejemplos.
Paso 1: Instalar kubectl
Instala kubectl desde el repositorio oficial de Kubernetes (pkgs.k8s.io). Cada versión menor tiene su propio repositorio; elige la misma versión menor que tu clúster o una adyacente, porque kubectl solo está soportado con una diferencia de una versión menor respecto al servidor. Los ejemplos usan v1.34: cámbiala por la de tu clúster.
Instala las dependencias y descarga la clave del repositorio:
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gnupg
sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.34/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
sudo chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg
Añade el repositorio e instala el paquete:
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.34/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
sudo apt install -y kubectl
Comprueba la versión instalada:
kubectl version --client
Client Version: v1.34.1
Kustomize Version: v5.7.1
Notapara cambiar de versión menor más adelante, edita la URL en
/etc/apt/sources.list.d/kubernetes.listy en el comando de la clave, y vuelve a ejecutarsudo apt update && sudo apt install kubectl.
Paso 2: Configurar el acceso al clúster con kubeconfig
kubectl lee la configuración de conexión (servidor de la API, certificados y credenciales) de ~/.kube/config. Copia ahí el kubeconfig que te haya dado tu proveedor o el de tu clúster, y restringe sus permisos porque contiene credenciales:
mkdir -p ~/.kube
cp /ruta/a/tu-kubeconfig.yaml ~/.kube/config
chmod 600 ~/.kube/config
Verifica que llegas a la API y que los nodos están listos:
kubectl cluster-info
kubectl get nodes
NAME STATUS ROLES AGE VERSION
node-1 Ready control-plane 12d v1.34.1
node-2 Ready <none> 12d v1.34.1
Trabajar con varios clústeres y contextos
Un contexto combina un clúster, un usuario y un namespace por defecto. Estos comandos cubren casi todo lo que necesitarás:
kubectl config get-contexts
kubectl config current-context
kubectl config use-context nombre-del-contexto
Si tienes varios kubeconfig, puedes indicar el archivo en cada comando con --kubeconfig=/ruta/archivo o combinarlos con la variable KUBECONFIG:
export KUBECONFIG=~/.kube/config:~/.kube/config-staging
kubectl config get-contexts
Para fusionarlos en un solo archivo de forma permanente, genera uno nuevo con --flatten, revísalo y sustituye el original:
kubectl config view --flatten > ~/.kube/config-merged
chmod 600 ~/.kube/config-merged
Paso 3: Crear un namespace de trabajo
Los namespaces separan recursos dentro de un mismo clúster. Crea uno para los ejemplos y fíjalo como namespace por defecto del contexto actual, así no tendrás que escribir -n demo en cada comando:
kubectl create namespace demo
kubectl config set-context --current --namespace=demo
Comprueba que el cambio se ha aplicado:
kubectl config view --minify -o jsonpath='{..namespace}'
demo
Paso 4: Crear recursos con apply y dry-run
Hay dos formas de crear recursos: imperativa (kubectl create deployment ...) y declarativa (kubectl apply -f archivo.yaml). La declarativa es la que conviene usar en el día a día porque el YAML queda versionado y puedes volver a aplicarlo tras cada cambio.
Un truco útil es generar el YAML inicial con un comando imperativo en modo --dry-run=client, que no crea nada en el clúster:
kubectl create deployment web --image=nginx:1.27 --replicas=2 --dry-run=client -o yaml > web.yaml
Revisa el archivo generado y aplícalo:
kubectl apply -f web.yaml
deployment.apps/web created
Expón el Deployment con un Service de tipo ClusterIP en el puerto 80:
kubectl expose deployment web --port=80 --target-port=80
Antes de aplicar cambios futuros sobre web.yaml, kubectl diff muestra qué va a cambiar en el clúster respecto a lo que hay desplegado:
kubectl diff -f web.yaml
Si no hay diferencias, el comando no imprime nada.
Paso 5: Consultar recursos con get, describe y explain
kubectl get lista recursos. Algunas variantes que usarás continuamente:
kubectl get pods
kubectl get pods -o wide
kubectl get deploy,svc,pods
kubectl get pods -A
kubectl get pods -l app=web
kubectl get pods --watch
NAME READY STATUS RESTARTS AGE
web-7c5b8d6f4d-9xkzq 1/1 Running 0 40s
web-7c5b8d6f4d-tq2lm 1/1 Running 0 40s
-o wide añade la IP del pod y el nodo, -A consulta todos los namespaces, -l filtra por etiqueta y --watch se queda mostrando cambios hasta que pulses Ctrl+C. También puedes filtrar por campos del objeto:
kubectl get pods -A --field-selector=status.phase!=Running
kubectl describe muestra el detalle de un recurso e incluye, al final, los eventos recientes. Es el primer sitio donde mirar cuando algo no arranca:
kubectl describe deployment web
kubectl describe pod web-7c5b8d6f4d-9xkzq
kubectl explain documenta cualquier campo de la API sin salir de la terminal, útil al escribir manifiestos:
kubectl explain deployment.spec.strategy
Para ver los tipos de recursos disponibles en el clúster y sus nombres cortos (po, svc, deploy, cm...):
kubectl api-resources
Paso 6: Depurar pods con logs, exec y port-forward
Lee los logs de un pod, o de todos los pods de un Deployment, con kubectl logs:
kubectl logs deployment/web
kubectl logs -f web-7c5b8d6f4d-9xkzq --tail=50
kubectl logs web-7c5b8d6f4d-9xkzq --previous
-f sigue el log en tiempo real, --tail limita las líneas y --previous muestra el log del contenedor anterior, imprescindible cuando un pod está en CrashLoopBackOff. Si el pod tiene varios contenedores, añade -c nombre-contenedor.
Para abrir una shell dentro de un contenedor:
kubectl exec -it deployment/web -- sh
Dentro, comprueba por ejemplo la configuración de Nginx con nginx -t y sal con exit.
Para probar un Service desde tu máquina sin exponerlo a Internet, redirige un puerto local:
kubectl port-forward service/web 8080:80
En otra terminal:
curl -sI http://127.0.0.1:8080
HTTP/1.1 200 OK
Server: nginx/1.27.5
Para probar la conectividad desde dentro del clúster, lanza un pod temporal con curl que se borra al terminar:
kubectl run tmp-curl --rm -it --restart=Never --image=curlimages/curl -- curl -s http://web
Los eventos del namespace suelen explicar fallos de programación, de descarga de imagen o de montaje de volúmenes:
kubectl get events --sort-by=.metadata.creationTimestamp
kubectl top muestra el consumo de CPU y memoria, pero requiere que el clúster tenga instalado metrics-server:
kubectl top nodes
kubectl top pods
Paso 7: Escalar, actualizar y revertir Deployments
Cambia el número de réplicas:
kubectl scale deployment web --replicas=3
Actualiza la imagen del contenedor nginx (el nombre que asignó kubectl create deployment) y sigue el despliegue hasta que termine:
kubectl set image deployment/web nginx=nginx:1.28
kubectl rollout status deployment/web
Waiting for deployment "web" rollout to finish: 1 out of 3 new replicas have been updated...
deployment "web" successfully rolled out
Si la nueva versión falla, consulta el historial y vuelve a la revisión anterior:
kubectl rollout history deployment/web
kubectl rollout undo deployment/web
Para reiniciar todos los pods de un Deployment sin cambiar su definición (por ejemplo, tras actualizar un Secret que se lee al arrancar):
kubectl rollout restart deployment/web
Importante
kubectl set imageykubectl scalecambian el estado del clúster pero no tuweb.yaml. Si gestionas los recursos de forma declarativa, refleja también el cambio en el archivo para que el próximokubectl applyno lo deshaga.
Paso 8: Formatear la salida con JSONPath y columnas personalizadas
Cualquier get acepta -o yaml o -o json para ver el objeto completo. Cuando solo necesitas un campo, por ejemplo en un script, usa JSONPath:
kubectl get pods -l app=web -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.podIP}{"\n"}{end}'
web-6f8d9b7c5-2hxvp 10.42.1.15
web-6f8d9b7c5-8kq4n 10.42.2.21
web-6f8d9b7c5-zr7lm 10.42.1.16
Las columnas personalizadas dan una tabla legible con los campos que elijas:
kubectl get pods -o custom-columns=NOMBRE:.metadata.name,NODO:.spec.nodeName,IMAGEN:.spec.containers[0].image
Y -o name devuelve solo tipo/nombre, cómodo para encadenar con otros comandos:
kubectl get pods -l app=web -o name
Paso 9: Etiquetar y eliminar recursos
Las etiquetas permiten agrupar y filtrar recursos. Añade, modifica o quita una etiqueta así:
kubectl label deployment web entorno=pruebas
kubectl label deployment web entorno=produccion --overwrite
kubectl label deployment web entorno-
Elimina recursos por nombre, por archivo o por etiqueta:
kubectl delete -f web.yaml
kubectl delete service web
Borrar un namespace elimina todo lo que contiene, así que úsalo con cuidado. Para limpiar el ejemplo de esta guía y volver al namespace default:
kubectl config set-context --current --namespace=default
kubectl delete namespace demo
Advertencia
kubectl delete pod nombre --force --grace-period=0elimina el objeto de la API sin esperar a que el contenedor se detenga. Resérvalo para pods atascados enTerminatingen un nodo que ya no existe.
Paso 10: Activar el autocompletado y un alias
El autocompletado de Bash completa verbos, tipos y nombres de recursos con el tabulador. Instala bash-completion y añade kubectl a tu ~/.bashrc, junto con el alias k y su autocompletado:
sudo apt install -y bash-completion
echo 'source <(kubectl completion bash)' >> ~/.bashrc
echo 'alias k=kubectl' >> ~/.bashrc
echo 'complete -o default -F __start_kubectl k' >> ~/.bashrc
source ~/.bashrc
Comprueba que funciona escribiendo k get po y pulsando el tabulador: deberían aparecer los nombres de los pods. Si usas Zsh, el equivalente es source <(kubectl completion zsh) en ~/.zshrc.
Solución de problemas
The connection to the server localhost:8080 was refused: kubectl no encuentra un kubeconfig. Comprueba que existe~/.kube/configo que la variableKUBECONFIGapunta al archivo correcto.error: You must be logged in to the server (Unauthorized): las credenciales del kubeconfig han caducado o no son válidas. Descarga de nuevo el kubeconfig desde tu proveedor o regenera el certificado del usuario.Error from server (Forbidden): tu usuario no tiene permisos RBAC para esa acción. Compruébalo conkubectl auth can-i create deployments -n demo.- Aviso de versiones incompatibles: si
kubectl versionavisa de que el cliente y el servidor difieren en más de una versión menor, cambia el repositorio del paso 1 a la versión de tu clúster. - Pod en
ImagePullBackOffoPending: revisa la secciónEventsdekubectl describe pody los eventos del namespace; suelen indicar una imagen mal escrita, falta de credenciales del registro o falta de recursos en los nodos.
Conclusión
Has instalado kubectl desde el repositorio oficial, lo has conectado a tu clúster y has usado los comandos que cubren la mayor parte del trabajo diario: gestionar contextos y namespaces, aplicar manifiestos, inspeccionar recursos, depurar pods y controlar los despliegues. A partir de aquí puedes publicar tus aplicaciones hacia Internet con un Ingress y un certificado TLS, dar almacenamiento persistente a tus pods con PersistentVolumeClaims o empaquetar tus manifiestos con Helm o Kustomize (kubectl apply -k).
