Tutoriales
DevOpsbeginnerDestacado

De Docker a Kubernetes: Guía completa para principiantes

Aprende desde los fundamentos de Docker hasta el despliegue en un clúster Kubernetes real, con ejemplos prácticos de Dockerfiles, deployments y servicios.

2026-03-2212 min de lectura60 minCloud360.net · Tutoriales
DockerKubernetesDevOps

Introducción

Docker y Kubernetes son las dos tecnologías más fundamentales del DevOps moderno. Docker te permite empaquetar aplicaciones con todas sus dependencias en contenedores portables, mientras que Kubernetes orquesta esos contenedores a escala. Esta guía te llevará desde cero hasta desplegar tu primera aplicación en un clúster funcional.

Paso 1: Instalar Docker

En Ubuntu/Debian, instala Docker Engine con los siguientes comandos:

bash
# Añadir el repositorio oficial de Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list

# Instalar Docker sudo apt-get update && sudo apt-get install -y docker-ce docker-ce-cli containerd.io

# Añadir tu usuario al grupo docker (evita usar sudo) sudo usermod -aG docker $USER newgrp docker ```

Verifica la instalación con `docker --version` y `docker run hello-world`.

Paso 2: Entender los conceptos clave de Docker

Antes de escribir tu primer Dockerfile, necesitas entender la terminología básica:

  • Imagen: Plantilla inmutable con el sistema de archivos y configuración de tu aplicación
  • Contenedor: Instancia en ejecución de una imagen, aislada del sistema host
  • Dockerfile: Archivo de texto con instrucciones para construir una imagen
  • Registry: Repositorio de imágenes (Docker Hub, GitHub Container Registry, etc.)
  • Layer: Cada instrucción del Dockerfile crea una capa inmutable; Docker las reutiliza en caché

Paso 3: Escribir tu primer Dockerfile

Crea una aplicación web simple con Node.js y su Dockerfile:

dockerfile
# Usar imagen base oficial de Node.js (versión LTS)
FROM node:20-alpine

# Establecer directorio de trabajo dentro del contenedor WORKDIR /app

# Copiar archivos de dependencias primero (optimización de caché) COPY package*.json ./

# Instalar dependencias de producción únicamente RUN npm ci --only=production

# Copiar el resto del código fuente COPY . .

# Exponer el puerto que usa la aplicación EXPOSE 3000

# Usuario no-root por seguridad USER node

# Comando para iniciar la aplicación CMD ["node", "server.js"] ```

El orden de las instrucciones importa: poner `COPY package*.json` antes del código fuente aprovecha el sistema de caché de Docker, acelerando las reconstrucciones cuando solo cambia el código.

Paso 4: Construir y ejecutar imágenes Docker

bash
# Construir la imagen con una etiqueta
docker build -t mi-app:1.0 .

# Ejecutar el contenedor mapeando el puerto 8080 del host al 3000 del contenedor docker run -d -p 8080:3000 --name mi-contenedor mi-app:1.0

# Ver contenedores en ejecución docker ps

# Ver logs del contenedor docker logs mi-contenedor

# Acceder al shell del contenedor para depuración docker exec -it mi-contenedor sh ```

Paso 5: Docker Compose para entornos multi-contenedor

La mayoría de aplicaciones necesitan múltiples servicios (app, base de datos, caché). Docker Compose los orquesta localmente:

yaml
# docker-compose.yml
version: '3.9'
services:
  app:
    build: .
    ports:
      - "8080:3000"
    environment:
      - DATABASE_URL=postgresql://postgres:password@db:5432/miapp
      - REDIS_URL=redis://cache:6379
    depends_on:
      db:
        condition: service_healthy

db: image: postgres:16-alpine environment: POSTGRES_PASSWORD: password POSTGRES_DB: miapp volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 5

cache: image: redis:7-alpine volumes: - redis_data:/data

volumes: postgres_data: redis_data: ```

bash
docker compose up -d    # Iniciar todos los servicios
docker compose down -v  # Detener y eliminar volúmenes

Paso 6: Instalar Kubernetes con minikube

Para aprender Kubernetes localmente, minikube crea un clúster de un solo nodo:

bash
# Instalar minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Instalar kubectl curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" sudo install kubectl /usr/local/bin/kubectl

# Iniciar el clúster minikube start --cpus=2 --memory=4096 ```

Paso 7: Conceptos fundamentales de Kubernetes

Kubernetes introduce su propia jerarquía de objetos:

  • Pod: La unidad mínima de despliegue; uno o más contenedores que comparten red y almacenamiento
  • Deployment: Gestiona el ciclo de vida de Pods, garantizando el número deseado de réplicas
  • Service: Expone los Pods a través de una IP estable y balanceo de carga interno
  • Namespace: Partición lógica del clúster para aislar recursos entre equipos
  • ConfigMap/Secret: Gestión de configuración y datos sensibles separados del código

Paso 8: Tu primer Deployment

Crea el archivo `deployment.yaml`:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mi-app
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mi-app
  template:
    metadata:
      labels:
        app: mi-app
    spec:
      containers:
        - name: mi-app
          image: mi-app:1.0
          ports:
            - containerPort: 3000
          resources:
            requests:
              memory: "64Mi"
              cpu: "100m"
            limits:
              memory: "128Mi"
              cpu: "500m"
          readinessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 10
bash
kubectl apply -f deployment.yaml
kubectl get pods -w  # Observar el estado en tiempo real

Paso 9: Exponer la aplicación con un Service

yaml
apiVersion: v1
kind: Service
metadata:
  name: mi-app-service
spec:
  selector:
    app: mi-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
  type: LoadBalancer
bash
kubectl apply -f service.yaml
minikube service mi-app-service --url  # Obtener URL de acceso

Paso 10: Gestionar ConfigMaps y Secrets

bash
# Crear un ConfigMap
kubectl create configmap app-config --from-literal=APP_ENV=production --from-literal=LOG_LEVEL=info

# Crear un Secret (los valores se codifican en base64 automáticamente) kubectl create secret generic app-secrets --from-literal=DB_PASSWORD=mipassword ```

Referencia estos objetos en tu Deployment usando `envFrom` o variables de entorno individuales.

Paso 11: Actualizaciones sin downtime con Rolling Updates

bash
# Actualizar la imagen del contenedor
kubectl set image deployment/mi-app mi-app=mi-app:2.0

# Ver el progreso de la actualización kubectl rollout status deployment/mi-app

# Revertir si algo sale mal kubectl rollout undo deployment/mi-app ```

Kubernetes actualiza los Pods gradualmente, siempre manteniendo disponibles el número de réplicas configurado, lo que garantiza cero tiempo de inactividad durante las actualizaciones.

Paso 12: Monitorización básica y siguiente pasos

bash
# Ver recursos consumidos por cada Pod
kubectl top pods

# Describir un Pod con detalles de eventos kubectl describe pod <nombre-del-pod>

# Ver logs de un Pod específico kubectl logs <nombre-del-pod> -f ```

Con estos 12 pasos dominas los fundamentos esenciales. Como siguiente paso, explora Helm para gestionar aplicaciones complejas como paquetes, Ingress controllers para enrutar tráfico HTTP, y herramientas de monitorización como Prometheus y Grafana para observabilidad completa de tu clúster.

Newsletter12,500+ suscriptores

Recibe el mejor contenido tech cada mañana

Gratis · Sin spam · Cancela cuando quieras