Introducción a los contenedores
Los contenedores son tecnologías que permiten empaquetar aplicaciones junto con todas sus dependencias en un entorno aislado. Son muy útiles para garantizar que las aplicaciones funcionen correctamente en cualquier sistema operativo o infraestructura.
Diferencias entre Podman y Docker
- Docker: Es la herramienta más conocida para la gestión de contenedores, basada en un demonio central.
- Podman: Es una alternativa sin demonios a Docker. Su principal ventaja es que no requiere un daemon en ejecución y permite ejecutar contenedores como usuario sin privilegios.
1. Instalación y Configuración Inicial
Podman
Linux (Archlinux/archlinux-based):
# Actualizamos la base de datos de paquetes y el sistema operativo.
sudo pacman -Syu
# Instalamos el paquete podman
sudo pacman -S podman
# Verificamos la versión de podman
podman --version
Configuración rootless:
# Habilitar usuario no root
echo "tu_usuario:100000:65536" | sudo tee -a /etc/subuid
echo "tu_usuario:100000:65536" | sudo tee -a /etc/subgid
# Verificar
podman info --debug
Docker
Linux (Archlinux/archlinux-based):
sudo pacman -Syu
sudo pacman -S docker
sudo systemctl enable --now docker
sudo usermod -aG docker $USER
newgrp docker
docker --version
Windows/macOS:
- Descargar Docker Desktop desde docker.com
2. Comandos Básicos (Equivalencias)
| Acción | Docker | Podman |
|---|---|---|
| Ejecutar contenedor | docker run -d nginx |
podman run -d nginx |
| Listar contenedores | docker ps -a |
podman ps -a |
| Inspeccionar contenedor | docker inspect <ID> |
podman inspect <ID> |
| Eliminar contenedor | docker rm <ID> |
podman rm <ID> |
| Ver logs | docker logs <ID> |
podman logs <ID> |
| Listar imágenes | docker images |
podman images |
| Eliminar imagen | docker rmi <ID> |
podman rmi <ID> |
3. Trabajo con Imágenes
Construir imagen
Dockerfile (Ambos):
FROM alpine:latest
RUN apk add --no-cache python3
COPY app.py /app/
CMD ["python3", "/app/app.py"]
Docker:
docker build -t mi-app:1.0 .
Podman:
podman build -t mi-app:1.0 .
Push/Pull de imágenes
Docker:
docker pull ubuntu:22.04
docker tag mi-app:1.0 mi-registry.com/mi-app:1.0
docker push mi-registry.com/mi-app:1.0
Podman:
podman pull ubuntu:22.04
podman tag mi-app:1.0 mi-registry.com/mi-app:1.0
podman push mi-registry.com/mi-app:1.0
4. Redes y Volúmenes
Redes personalizadas
Docker:
docker network create mi-red
docker run --network mi-red nginx
Podman:
podman network create mi-red
podman run --network mi-red nginx
Volúmenes persistentes
Docker:
docker volume create mi-volumen
docker run -v mi-volumen:/data alpine
Podman:
podman volume create mi-volumen
podman run -v mi-volumen:/data alpine
5. Ejemplo Avanzado: Aplicación Multi-Contenedor
Docker Compose (docker-compose.yml)
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: secreto
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Ejecución:
docker-compose up -d
Podman Compose (podman-compose.yml)
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: secreto
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Ejecución:
podman-compose up -d
6. Configuración Avanzada
Rootless Containers (Podman)
# Crear usuario para contenedores
useradd -m container-user
su - container-user
# Ejecutar contenedor como usuario normal
podman run -d --name mi-contenedor nginx
SELinux Context (Podman)
podman run -v /host/path:/container/path:Z nginx
Docker Daemon Config
# /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
7. Seguridad
Podman (Rootless por defecto)
# Verificar modo rootless
podman info | grep rootless
# Namespaces de usuario
podman unshare cat /proc/self/uid_map
Docker (Hardening)
# Ejecutar contenedor en modo read-only
docker run --read-only alpine
# Limitar recursos
docker run --memory="512m" --cpus="1.5" nginx
8. Integración con Kubernetes
Docker (Kind)
kind create cluster
kubectl get nodes
Podman (Podman Play)
# k8s-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
Ejecución:
podman play kube k8s-deployment.yaml
9. Monitoreo y Depuración
Inspección de procesos
Docker:
docker stats
docker top <ID>
Podman:
podman stats
podman top <ID>
Análisis de imágenes
Docker:
docker scan nginx:alpine
Podman:
podman inspect nginx:alpine
10. Migración Docker → Podman
Alias para compatibilidad
alias docker=podman
alias docker-compose=podman-compose
Convertir Docker Compose
podman-compose -f docker-compose.yml up
Importar imágenes Docker
docker save mi-imagen > imagen.tar
podman load -i imagen.tar
Comparativa Final: Docker vs Podman
| Característica | Docker | Podman |
|---|---|---|
| Arquitectura | Cliente-Servidor (daemon) | Sin daemon (rootless) |
| Permisos | Requiere root/sudo | Rootless por defecto |
| Compatibilidad Kubernetes | Docker Desktop + Kind | Podman Play + Kind |
| Seguridad | Namespaces de kernel | Namespaces + user namespaces |
| CLI | Comandos propios | Compatible con Docker CLI |
| Imágenes | Docker Hub | Compatible con OCI |
Consejos Profesionales
-
Entornos de producción:
- Usar Podman para cargas de trabajo rootless
- Docker para sistemas legacy con soporte enterprise
-
CI/CD:
# Ejemplo GitHub Actions - name: Build with Docker uses: docker/build-push-action@v3 - name: Build with Podman run: | podman build -t mi-imagen . podman push mi-imagen -
Optimización:
```dockerfile
Multi-stage build (funciona en ambos)
FROM golang:1.19 as builder WORKDIR /app COPY . . RUN go build -o mi-app
Stage final
FROM alpine:latest
COPY --from=builder /app/mi-app /usr/local/bin/
CMD ["mi-app"]
- Almacenamiento eficiente:
# Minimizar capas (ambas herramientas)
pacman -Syu --noconfirm \
paquete1 \
paquete2 \
&& pacman -Sc --noconfirm
- Actualización segura:
# Usar tags específicos en producción
podman pull nginx:1.25.3-alpine
docker pull nginx:1.25.3-alpine
6. Limpieza automatizada:
# Podman
podman system prune --all --force
# Docker
docker system prune --all --force
Conclusión Final
Elección según uso:
-
Desarrolladores principiantes → Docker (mayor documentación)
-
Entornos empresariales → Podman (integración con systemd y SELinux)
-
Kubernetes local → Kind (Docker) vs Minikube (Podman)
Tendencia actual:
# Alternativa moderna para ambos
nerdctl run --rm -it nginx # Compatible con containerd
¡Actualiza tus entornos regularmente y siempre verifica la procedencia de las imágenes! 🐳🔒