DataSkills Hub

Kubernetes

Kubernetes es el orquestador de contenedores estándar de la industria. Gestiona el despliegue, escalado y operación de servicios en un stack de datos.

#Getting Started

#Conectarse al clúster

Verificar acceso y contexto actual

# Ver clúster y contexto activo
$ kubectl config current-context
$ kubectl cluster-info

# Cambiar al contexto de producción
$ kubectl config use-context production

Verificar versión y estado del clúster

$ kubectl version --short
$ kubectl get componentstatus

#Comandos esenciales

Comando Descripción
kubectl get all Ver todos los recursos del namespace
kubectl get all -A Ver todos los recursos de todo el clúster
kubectl get <recurso> Listar un tipo de recurso
kubectl describe <recurso> <nombre> Detalle completo de un recurso
kubectl logs <pod> Ver logs de un pod
kubectl exec -it <pod> -- sh Shell interactiva dentro de un pod
kubectl apply -f <archivo> Aplicar manifiesto YAML
kubectl delete -f <archivo> Eliminar recursos de un manifiesto

#Abreviaciones de recursos

Recurso Abreviación Recurso Abreviación
nodes no services svc
pods po deployments deploy
namespaces ns replicasets rs
configmaps cm daemonsets ds
persistentvolumes pv ingresses ing
persistentvolumeclaims pvc storageclasses sc
serviceaccounts sa statefulsets sts

#Formato de salida

# Salida amplia con más columnas
$ kubectl get po -o wide

# Salida en YAML (útil para copiar manifiestos)
$ kubectl get deploy airflow -o yaml

# Salida en JSON
$ kubectl get svc -o json

# Campos específicos con jsonpath
$ kubectl get nodes -o jsonpath='{.items[*].metadata.name}'

# Columnas personalizadas
$ kubectl get po -o custom-columns=NAME:.metadata.name,STATUS:.status.phase

#Ver Recursos

#Nodos

# Listar nodos del clúster
$ kubectl get no -o wide

# Detalle de un nodo específico
$ kubectl describe no <nombre_nodo>

# Ver consumo de CPU/memoria por nodo
$ kubectl top node

# Filtrar nodos por label
$ kubectl get no -l environment=production

#Pods

# Listar pods del namespace actual
$ kubectl get po -o wide

# Listar pods de todos los namespaces
$ kubectl get po -A

# Ver pods con labels
$ kubectl get po --show-labels

# Filtrar pods por label
$ kubectl get po -l app=airflow-webserver

# Filtrar pods por estado
$ kubectl get po --field-selector status.phase=Running

# Ver consumo de recursos por pod
$ kubectl top pod

#Deployments y ReplicaSets

# Listar deployments
$ kubectl get deploy -o wide

# Detalle de un deployment
$ kubectl describe deploy <nombre>

# Ver historial de rollouts
$ kubectl rollout history deploy <nombre>

# Ver replicasets asociados
$ kubectl get rs -o wide

#Services e Ingress

# Listar servicios
$ kubectl get svc -o wide

# Listar servicios con labels
$ kubectl get svc --show-labels

# Detalle de un servicio
$ kubectl describe svc <nombre>

# Listar ingresses
$ kubectl get ing -A

#ConfigMaps y Secrets

# Listar configmaps
$ kubectl get cm

# Ver contenido de un configmap
$ kubectl describe cm <nombre>

# Listar secrets (no muestra valores)
$ kubectl get secrets

# Ver detalle de un secret (base64)
$ kubectl get secret <nombre> -o yaml

#Persistent Volumes y Claims

# Ver persistent volumes
$ kubectl get pv

# Ver persistent volume claims
$ kubectl get pvc

# Detalle de un PVC
$ kubectl describe pvc <nombre>

# Ver storage classes disponibles
$ kubectl get sc -o yaml

#Eventos

# Ver eventos recientes (ordenados por tiempo)
$ kubectl get events --sort-by='.lastTimestamp'

# Eventos de un namespace específico
$ kubectl get events -n data-platform

# Watch en tiempo real
$ kubectl get events -w

#Múltiples recursos

# Consultar varios tipos a la vez
$ kubectl get svc,po,deploy

# Todo en todos los namespaces
$ kubectl get all -A

# Recursos de un namespace específico
$ kubectl get all -n data-platform

#Gestionar Recursos

#Crear recursos desde manifiesto

# Aplicar un archivo YAML
$ kubectl apply -f deployment.yaml

# Aplicar todos los YAML de un directorio
$ kubectl apply -f ./manifests/

# Aplicar desde URL
$ kubectl apply -f https://raw.githubusercontent.com/org/repo/main/manifest.yaml

#Crear recursos rápidos (imperativo)

# Crear un pod
$ kubectl run test-pod --image=busybox --restart=Never -- sleep 3600

# Crear un deployment
$ kubectl create deploy nginx-test --image=nginx:latest

# Exponer un deployment como servicio
$ kubectl expose deploy nginx-test --port=80 --type=ClusterIP

# Crear un configmap desde archivo
$ kubectl create cm app-config --from-file=config.properties

# Crear un secret genérico
$ kubectl create secret generic db-creds \
    --from-literal=username=admin \
    --from-literal=password=changeme

#Generar YAML sin aplicar (dry-run)

# Generar manifiesto de deployment
$ kubectl create deploy airflow-worker \
    --image=apache/airflow:2.8.0 \
    --dry-run=client -o yaml > worker-deploy.yaml

# Generar manifiesto de servicio
$ kubectl create svc clusterip my-svc \
    --tcp=<puerto>:<puerto> \
    --dry-run=client -o yaml > svc.yaml

#Escalar y actualizar

# Escalar replicas
$ kubectl scale deploy <nombre> --replicas=3

# Actualizar imagen de un deployment
$ kubectl set image deploy/<nombre> <container>=<nueva_imagen>

# Ver estado del rollout
$ kubectl rollout status deploy/<nombre>

# Rollback al revision anterior
$ kubectl rollout undo deploy/<nombre>

# Rollback a una revisión específica
$ kubectl rollout undo deploy/<nombre> --to-revision=2

#Labels y anotaciones

# Agregar label a un pod
$ kubectl label po <nombre> env=staging

# Agregar label a un nodo
$ kubectl label no <nodo> disktype=ssd

# Eliminar un label (con guión al final)
$ kubectl label po <nombre> env-

# Agregar anotación
$ kubectl annotate po <nombre> description="Pod de prueba"

#Mantenimiento de nodos

# Marcar nodo como no programable (cordon)
$ kubectl cordon <nodo>

# Evacuar pods de un nodo (drain)
$ kubectl drain <nodo> --ignore-daemonsets --delete-emptydir-data

# Restaurar nodo como programable
$ kubectl uncordon <nodo>

#Eliminar recursos

# Eliminar un pod
$ kubectl delete po <nombre>

# Eliminar un deployment (y sus pods)
$ kubectl delete deploy <nombre>

# Eliminar recursos desde manifiesto
$ kubectl delete -f deployment.yaml

# Eliminar todos los pods de un namespace
$ kubectl delete po --all -n <namespace>

# Forzar eliminación de un pod atascado
$ kubectl delete po <nombre> --grace-period=0 --force

#Debugging

#Logs de pods

# Logs del pod
$ kubectl logs <pod>

# Logs de la última hora
$ kubectl logs --since=1h <pod>

# Últimas 50 líneas
$ kubectl logs --tail=50 <pod>

# Logs en tiempo real (follow)
$ kubectl logs -f <pod>

# Logs de un contenedor específico (multi-container pod)
$ kubectl logs <pod> -c <contenedor>

# Logs de un pod anterior (crashed)
$ kubectl logs <pod> --previous

# Guardar logs a archivo
$ kubectl logs <pod> > /tmp/pod-debug.log

#Shell interactiva

# Abrir shell en un pod existente
$ kubectl exec -it <pod> -- /bin/bash

# Si no tiene bash, usar sh
$ kubectl exec -it <pod> -- /bin/sh

# Ejecutar un comando sin shell interactiva
$ kubectl exec <pod> -- cat /etc/config/app.conf

# Pod temporal de debugging
$ kubectl run debug --image=busybox --rm -it --restart=Never -- sh

#Diagnosticar pods con problemas

# Ver estado y eventos del pod
$ kubectl describe po <pod>

# Ver razón de un CrashLoopBackOff
$ kubectl logs <pod> --previous

# Ver métricas de recursos
$ kubectl top pod <pod>

# Verificar endpoints de un servicio
$ kubectl get endpoints <servicio>

# Test de conectividad DNS desde un pod
$ kubectl exec -it <pod> -- nslookup <servicio>.<namespace>.svc.cluster.local

#Depurar manifiesto YAML

Manifiesto ejemplo para debugging

apiVersion: v1
kind: Pod
metadata:
  name: debug-pod
  namespace: data-platform
  labels:
    app: debug
spec:
  containers:
    - name: debug
      image: nicolaka/netshoot:latest
      command: ['sleep', '3600']
      resources:
        requests:
          cpu: '100m'
          memory: '128Mi'
        limits:
          cpu: '200m'
          memory: '256Mi'

Aplicar y usar

$ kubectl apply -f debug-pod.yaml
$ kubectl exec -it debug-pod -n data-platform -- bash
# Dentro del pod: curl, dig, nslookup, tcpdump, etc.

#Port-forward para acceso local

# Forward a un pod
$ kubectl port-forward <pod> <puerto-local>:<puerto-pod>

# Forward a un servicio
$ kubectl port-forward svc/<servicio> <puerto-local>:<puerto-svc>

# Forward con bind a IP específica
$ kubectl port-forward --address <ip-bind> svc/<servicio> <puerto-local>:<puerto-svc>

#Namespaces

#Namespaces del stack de datos

Namespace Propósito
data-platform Servicios core: Airflow, Spark, NiFi
data-warehouse Trino, dbt, metastore
data-lake MinIO, Delta Lake, Iceberg
monitoring Prometheus, Grafana, AlertManager
ml-workloads MLflow, Jupyter, serving endpoints
ingestion Kafka, Debezium, conectores CDC
data-governance OpenMetadata, Apache Atlas
default No usar para cargas de datos

#Trabajar con namespaces

# Ver namespaces disponibles
$ kubectl get ns

# Establecer namespace por defecto para la sesión
$ kubectl config set-context --current --namespace=data-platform

# Ver el namespace actual
$ kubectl config view --minify -o jsonpath='{..namespace}'

# Crear un namespace nuevo
$ kubectl create ns <nombre>

# Ver recursos de un namespace específico
$ kubectl get all -n monitoring

#Ejemplo: verificar stack de datos

# Estado de Airflow
$ kubectl get po -n data-platform -l app=airflow

# Estado de Trino
$ kubectl get po -n data-warehouse -l app=trino

# Estado de Kafka
$ kubectl get po -n ingestion -l app=kafka

# Estado del monitoreo
$ kubectl get po -n monitoring

# Verificar todos los servicios expuestos
$ kubectl get svc -A | grep -E "LoadBalancer|NodePort"

#Ejemplo: manifiesto de deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: data-api
  namespace: data-platform
  labels:
    app: data-api
    team: data-engineering
    environment: production
spec:
  replicas: 2
  selector:
    matchLabels:
      app: data-api
  template:
    metadata:
      labels:
        app: data-api
        team: data-engineering
    spec:
      containers:
        - name: api
          image: <tu-url>/data-api:v1.2.0
          ports:
            - containerPort: <puerto>
          resources:
            requests:
              cpu: '250m'
              memory: '512Mi'
            limits:
              cpu: '500m'
              memory: '1Gi'
          envFrom:
            - configMapRef:
                name: data-api-config
            - secretRef:
                name: data-api-secrets

#Also see