Instalación
Un clúster local desechable y un kubectl que apunta al lugar correcto.
Instalación y configuración
Aprender Kubernetes en un clúster de producción es una mala idea por una razón sencilla: vas a romper cosas, y es exactamente lo que hay que hacer. Necesitas un clúster que se pueda destruir con un solo comando y recrear en dos minutos, en el que un error no cueste nada.
Hay dos formas de conseguirlo en un equipo de trabajo, y la elección no es indiferente. minikube simula un clúster completo dentro de una máquina virtual o un contenedor, con extensiones listas para usar: un panel de control, un controlador de entrada y un simulador de balanceador de carga. kind (Kubernetes in Docker) ejecuta cada nodo como un contenedor Docker: es más ligero, arranca más rápido y es la opción habitual en integración continua.
Pero antes del clúster está kubectl. Es un punto que los principiantes suelen invertir: kubectl no es un componente del clúster, sino un cliente HTTP que habla con una API remota. Se instala de forma independiente, funciona con cualquier clúster y lee en un archivo de configuración local con qué clúster debe hablar. La mitad de los «no funciona» de los primeros días vienen de ahí: kubectl consulta un clúster distinto del que uno cree.
Esta lección instala las herramientas y después se detiene en ese archivo de configuración —contextos y namespaces—, porque es lo que te evitará algún día aplicar en producción un manifiesto destinado a tu equipo.
Instalar kubectl
kubectl es un binario único, sin dependencias. Elige el método que corresponda a tu sistema:
# macOS con Homebrew
brew install kubectl
# Linux (Debian/Ubuntu) : repositorio oficial de Kubernetes
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key \
| sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' \
| sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update && sudo apt-get install -y kubectl
# Windows avec winget
winget install -e --id Kubernetes.kubectl
A continuación, comprueba la instalación. El siguiente comando muestra la versión del cliente y después intenta contactar con un servidor:
kubectl version --client
Mientras no haya ningún clúster en marcha, un comando como kubectl get nodes fallará con un mensaje de conexión rechazada. Es normal, y ya es una información útil: el cliente funciona, simplemente no tiene con quién hablar.
Qué versión elegir
Kubernetes tolera una diferencia de una versión menor entre el cliente y el servidor. Un kubectl 1.31 habla correctamente con un clúster 1.30, 1.31 o 1.32. Más allá de eso, algunos recursos pueden volverse invisibles para el cliente sin un mensaje claro. Ante un comportamiento inexplicable, la primera comprobación es esta:
# Compara la versión del cliente y la del servidor
kubectl version
Opción A: minikube
minikube arranca un clúster de un solo nodo en un controlador de virtualización. El controlador docker es el más sencillo si Docker ya está instalado.
# Instalación (macOS)
brew install minikube
# Arranque : la primera ejecución descarga la imagen del nodo, cuenta con unos minutos
minikube start --driver=docker --cpus=2 --memory=4096
# minikube ha escrito la configuración de conexión para kubectl : lo comprobamos
kubectl get nodes
Salida esperada:
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 47s v1.31.0
Un único nodo, que aloja a la vez el plano de control y tus cargas de trabajo. En producción estos roles están separados; aquí la simplificación no tiene consecuencias para aprender.
Los comandos de gestión del ciclo de vida:
minikube status # estado del clúster y de sus componentes
minikube stop # detiene sin destruir : el estado se conserva
minikube start # reinicia donde se había quedado
minikube delete # destruye todo, incluidos los datos
minikube dashboard # abre la interfaz web en el navegador
minikube ofrece extensiones que se pueden activar. Dos de ellas son útiles para el resto del curso:
# El controlador de entrada, necesario para los Ingress de la lección 6
minikube addons enable ingress
# El servidor de métricas, necesario para kubectl top y el autoescalado
minikube addons enable metrics-server
minikube addons list # ver todo lo que está disponible
Opción B: kind
kind convierte cada nodo en un contenedor Docker. Arranque más rápido, menor consumo y, sobre todo, la posibilidad de simular varios nodos, algo útil para observar una reprogramación de Pods.
# Instalación (macOS)
brew install kind
# Clúster de un solo nodo
kind create cluster --name atelier
# Verificación
kubectl cluster-info --context kind-atelier
Para un clúster con varios nodos, kind lee un archivo de configuración. Atención: este archivo usa la API de kind, no la de Kubernetes, de ahí un apiVersion de aspecto inusual.
# kind-cluster.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: atelier
nodes:
- role: control-plane
- role: worker
- role: worker
kind create cluster --config kind-cluster.yaml
kubectl get nodes
# atelier-control-plane, atelier-worker, atelier-worker2
kind delete cluster --name atelier # eliminación
Una diferencia que conviene conocer desde ya: kind no ve las imágenes de tu demonio Docker local. Una imagen construida en local debe inyectarse explícitamente en el clúster; de lo contrario, el Pod se queda bloqueado en ErrImagePull aunque docker images la muestre presente.
docker build -t mon-api:dev .
kind load docker-image mon-api:dev --name atelier
Con minikube, el equivalente consiste en apuntar el cliente Docker al demonio interno del clúster:
eval $(minikube docker-env)
docker build -t mon-api:dev . # la imagen se construye en el clúster
En ambos casos, indica imagePullPolicy: IfNotPresent en tus manifiestos; de lo contrario, Kubernetes intentará descargar la imagen dev desde un registro público donde no existe.
El archivo kubeconfig y los contextos
Este archivo es la pieza que se ignora durante demasiado tiempo. Por defecto es ~/.kube/config y contiene tres listas independientes:
clusters: las direcciones de los servidores de API y sus certificados;users: las identidades que sirven para autenticarse;contexts: las asociaciones (clúster, usuario, namespace).
Un contexto es, por tanto, simplemente la terna que kubectl utiliza en cada llamada. Cambiar de contexto es cambiar de clúster de destino, de ahí la necesidad de saber en todo momento cuál está activo.
# Listar los contextos ; el asterisco marca el que está activo
kubectl config get-contexts
# Mostrar únicamente el nombre del contexto activo
kubectl config current-context
# Cambiar de clúster
kubectl config use-context kind-atelier
# Ver la configuración completa, con los secretos ocultos
kubectl config view
Acostúmbrate a comprobar el contexto antes de cualquier comando de escritura. Es un reflejo que parece excesivo hasta el día en que te evita un kubectl delete en el clúster equivocado:
# Hacer visible el contexto en el prompt, o como mínimo comprobarlo
kubectl config current-context && kubectl get nodes
Los namespaces
Un namespace es una partición lógica del clúster. Permite aislar conjuntos de recursos por equipo, por entorno o por aplicación, y sirve de soporte para las cuotas y las reglas de acceso.
Un punto importante que suele sorprender: el namespace no aísla la red. Por defecto, un Pod del namespace dev puede alcanzar a un Pod del namespace prod. Ese aislamiento requiere NetworkPolicy, que dependen del complemento de red instalado.
# Los namespaces creados de serie
kubectl get namespaces
# default, kube-system, kube-public, kube-node-lease
kube-system aloja los componentes del clúster. No se despliega nada propio en él, y conviene evitar aplicar allí un manifiesto por descuido: otra razón más para vigilar el contexto.
Crea un namespace de trabajo, preferiblemente de forma declarativa, para que su definición viva en tu repositorio:
apiVersion: v1
kind: Namespace
metadata:
name: atelier
labels:
environnement: developpement
kubectl apply -f namespace.yaml
# Equivalente imperativo, práctico para algo desechable
kubectl create namespace atelier
Todos los comandos de lectura y escritura aceptan -n (o --namespace). Sin esta opción, kubectl usa el namespace registrado en el contexto activo, default la mayoría de las veces:
kubectl get pods -n atelier # en un namespace concreto
kubectl get pods --all-namespaces # en todos ; alias : -A
# Cambiar el namespace por defecto del contexto activo
kubectl config set-context --current --namespace=atelier
Este último comando evita repetir -n atelier cincuenta veces. Tiene una contrapartida: ya no ves en el comando dónde se aplica. Por eso, comprueba con regularidad:
kubectl config view --minify --output 'jsonpath={..namespace}'
Por último, una propiedad que conviene conocer antes de aprenderla por las malas: eliminar un namespace elimina todo lo que contiene, en cascada y sin confirmación.
kubectl delete namespace atelier # Pods, Services, Secrets, PVC : todo desaparece
Comprobar que todo está en su sitio
Encadena estos cuatro comandos. Si todos responden, tu entorno está listo para la siguiente lección:
# 1. El cliente alcanza el servidor de API
kubectl cluster-info
# 2. El nodo o los nodos están Ready
kubectl get nodes
# 3. Los componentes del plano de control están en marcha
kubectl get pods -n kube-system
# 4. Un Pod efímero puede arrancar de verdad y salir a la red
kubectl run test --image=busybox:1.36 --rm -it --restart=Never -- \
wget -qO- https://kubernetes.io/fr/ | head -n 5
El cuarto merece unas palabras: --rm elimina el Pod al salir, --restart=Never crea un Pod aislado en lugar de un Deployment, y -it conecta el terminal. Si tiene éxito, el runtime descarga imágenes, el planificador coloca los Pods y la red de salida funciona. Tres validaciones en un solo comando.
Autocompletado y alias
Los nombres de recursos generados por Kubernetes son largos y aleatorios (mon-api-7d4b8c9f5-xk2mp). Sin autocompletado, vas a teclearlos a mano todo el día.
# bash : añadir a ~/.bashrc
source <(kubectl completion bash)
alias k=kubectl
complete -o default -F __start_kubectl k
# zsh : añadir a ~/.zshrc
source <(kubectl completion zsh)
alias k=kubectl
# PowerShell : añadir al perfil ($PROFILE)
kubectl completion powershell | Out-String | Invoke-Expression
Set-Alias -Name k -Value kubectl
Dos opciones de lectura que conviene conocer desde ya, porque se usan constantemente:
# -o wide añade la IP del Pod y el nodo que lo aloja
kubectl get pods -o wide
# -w (watch) sigue los cambios en directo : indispensable durante un despliegue
kubectl get pods -w
Conclusiones
kubectles un cliente independiente del clúster. Obedece al contexto activo de~/.kube/config, y el error más frecuente del principiante es hablar con un clúster distinto del que cree.- minikube ofrece un clúster completo con extensiones (
ingress,metrics-server); kind es más ligero y permite simular varios nodos. Ambos sirven para este curso. - Una imagen construida en local no es visible para el clúster: usa
kind load docker-imageoeval $(minikube docker-env), y declaraimagePullPolicy: IfNotPresent. - Un namespace particiona los recursos y sirve de soporte para las cuotas, pero no aísla la red sin
NetworkPolicy. Eliminarlo destruye todo su contenido en cascada. - Verifica siempre un despliegue a partir del estado observado (
kubectl get,kubectl describe), y el contexto activo antes de cualquier comando de escritura.
Consejo: destruye y recrea tu clúster local al menos una vez. Saber que se puede empezar de cero en dos minutos cambia por completo la relación con la experimentación.
Comentarios
Los comentarios funcionan con GitHub Discussions
Inicia sesión con GitHub para participar en la discusión