Docker Logs y Solución de Problemas: Guía Práctica Completa
El logging efectivo y la solución de problemas son críticos para mantener entornos Docker saludables. Esta guía completa cubre mecanismos de logging de Docker, técnicas de depuración, problemas comunes y estrategias de monitoreo listas para producción para aplicaciones contenedorizadas.
Tabla de Contenidos
- Introducción
- Requisitos Previos
- Arquitectura de Logging de Docker
- Logs de Contenedores
- Drivers de Logging
- Configuración de Logs
- Depuración de Contenedores
- Problemas Comunes y Soluciones
- Monitoreo y Alertas
- Mejores Prácticas de Producción
- Solución de Problemas Avanzada
- Conclusión
Introducción
El logging de Docker captura los streams stdout y stderr de los contenedores, proporcionando visibilidad sobre el comportamiento de la aplicación. Las habilidades apropiadas de logging y solución de problemas son esenciales para diagnosticar problemas, monitorear el rendimiento y mantener una infraestructura contenedorizada confiable.
Lo Que Aprenderás
- Gestión y técnicas de visualización de logs de contenedores
- Configuración de drivers de logging para diferentes backends
- Depuración de contenedores en ejecución y fallidos
- Problemas comunes de Docker y sus soluciones
- Estrategias de logging en producción
- Técnicas avanzadas de solución de problemas
Requisitos Previos
- Docker Engine instalado
- Conocimiento básico de Docker (contenedores, imágenes)
- Comprensión de conceptos de logging en Linux
- Acceso a terminal con permisos apropiados
Verifica la configuración:
docker --version
docker info | grep "Logging Driver"
Arquitectura de Logging de Docker
Cómo Funcionan los Logs de Docker
Application (stdout/stderr)
↓
Container Runtime
↓
Logging Driver
↓
Log Destination (json-file, syslog, etc.)
Driver de Logging Predeterminado
# Check default logging driver
docker info | grep "Logging Driver"
# Default is json-file
# Logs stored in: /var/lib/docker/containers/<container-id>/<container-id>-json.log
Tipos de Logs
- Logs de contenedor: stdout/stderr de la aplicación
- Logs del daemon: El daemon Docker en sí
- Logs de build de imagen: Salida del build de Dockerfile
Logs de Contenedores
Visualizando Logs de Contenedores
# View all logs
docker logs container-name
# Follow logs in real-time
docker logs -f container-name
# Show timestamps
docker logs -t container-name
# Show last N lines
docker logs --tail 100 container-name
# Show logs since timestamp
docker logs --since 2024-01-01T00:00:00 container-name
# Show logs from last hour
docker logs --since 1h container-name
# Show logs until timestamp
docker logs --until 2024-01-01T23:59:59 container-name
# Combine options
docker logs -f --tail 50 --since 30m container-name
Filtrado de Logs
# Logs between timestamps
docker logs --since 2024-01-01T00:00:00 --until 2024-01-01T12:00:00 container-name
# Last 24 hours
docker logs --since 24h container-name
# With grep filtering
docker logs container-name 2>&1 | grep ERROR
# Search for pattern
docker logs container-name 2>&1 | grep -i "connection failed"
# Count errors
docker logs container-name 2>&1 | grep -c ERROR
Logs de Múltiples Contenedores
# View logs from multiple containers
docker-compose logs
# Follow all service logs
docker-compose logs -f
# Specific service
docker-compose logs -f web
# Multiple services
docker-compose logs web api database
Formato de Salida de Logs
# Without color
docker logs --no-color container-name
# Details format
docker logs --details container-name
# JSON format (raw)
sudo cat /var/lib/docker/containers/<container-id>/<container-id>-json.log
Drivers de Logging
Docker soporta múltiples drivers de logging para diferentes destinos de logs.
Drivers de Logging Disponibles
- json-file: Predeterminado, formato JSON en disco
- syslog: Daemon de logging del sistema
- journald: Journal de systemd
- gelf: Graylog Extended Log Format
- fluentd: Logging Fluentd
- awslogs: Amazon CloudWatch Logs
- splunk: Logging Splunk
- gcplogs: Google Cloud Logging
- logentries: Logging Logentries
- none: Deshabilitar logging
Configurar Driver de Logging por Contenedor
# Use syslog driver
docker run -d \
--log-driver syslog \
--log-opt syslog-address=tcp://192.168.1.100:514 \
nginx
# Use json-file with options
docker run -d \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx
# Use journald
docker run -d \
--log-driver journald \
--log-opt tag="webapp" \
nginx
# Disable logging
docker run -d --log-driver none nginx
Driver JSON File (Predeterminado)
# Configure size limits
docker run -d \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=5 \
--log-opt labels=production \
--log-opt env=APP_ENV \
nginx
Driver Syslog
# Send to remote syslog
docker run -d \
--log-driver syslog \
--log-opt syslog-address=tcp://syslog.example.com:514 \
--log-opt tag="{{.Name}}/{{.ID}}" \
--log-opt syslog-facility=daemon \
nginx
# Local syslog
docker run -d \
--log-driver syslog \
--log-opt syslog-address=unix:///dev/log \
nginx
Driver Fluentd
# Send logs to Fluentd
docker run -d \
--log-driver fluentd \
--log-opt fluentd-address=localhost:24224 \
--log-opt tag="docker.{{.Name}}" \
nginx
AWS CloudWatch Logs
# Send to CloudWatch
docker run -d \
--log-driver awslogs \
--log-opt awslogs-region=us-east-1 \
--log-opt awslogs-group=my-app \
--log-opt awslogs-stream=container-logs \
nginx
Driver GELF (Graylog)
# Send to Graylog
docker run -d \
--log-driver gelf \
--log-opt gelf-address=udp://graylog.example.com:12201 \
--log-opt tag="nginx" \
nginx
Configuración de Logs
Configuración Global del Daemon
Configura logging predeterminado para todos los contenedores:
# Edit daemon config
sudo nano /etc/docker/daemon.json
Añade:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"labels": "production",
"env": "os,customer"
}
}
Reinicia Docker:
sudo systemctl restart docker
Logging en Docker Compose
version: '3.8'
services:
web:
image: nginx
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
api:
image: my-api
logging:
driver: syslog
options:
syslog-address: "tcp://syslog:514"
tag: "api"
worker:
image: my-worker
logging:
driver: fluentd
options:
fluentd-address: "localhost:24224"
tag: "worker.{{.Name}}"
Logging Específico por Entorno
# docker-compose.yml
version: '3.8'
services:
app:
image: my-app
logging:
driver: "json-file"
options:
max-size: "10m"
# docker-compose.prod.yml
version: '3.8'
services:
app:
logging:
driver: "syslog"
options:
syslog-address: "tcp://logs.example.com:514"
Depuración de Contenedores
Inspeccionar Estado del Contenedor
# View container details
docker inspect container-name
# Get specific field
docker inspect --format '{{.State.Status}}' container-name
# Get exit code
docker inspect --format '{{.State.ExitCode}}' container-name
# Get error message
docker inspect --format '{{.State.Error}}' container-name
# View all state information
docker inspect --format '{{json .State}}' container-name | jq
Ejecutar Comandos en Contenedor en Ejecución
# Get shell access
docker exec -it container-name bash
# Run specific command
docker exec container-name ls -la /app
# Check process list
docker exec container-name ps aux
# Check environment variables
docker exec container-name env
# Check network connectivity
docker exec container-name ping -c 3 google.com
# Check disk usage
docker exec container-name df -h
# View running processes
docker top container-name
Depuración de Contenedores Fallidos
# View logs of stopped container
docker logs container-name
# Start container in foreground
docker start -a container-name
# Commit failed container to image for debugging
docker commit container-name debug-image
docker run -it debug-image bash
# Override entrypoint to debug
docker run -it --entrypoint bash my-image
Adjuntar a Contenedor en Ejecución
# Attach to container's main process
docker attach container-name
# Attach with logs
docker attach --sig-proxy=false container-name
# Detach without stopping: Ctrl+P, Ctrl+Q
Copiar Archivos para Depuración
# Copy file from container
docker cp container-name:/app/log.txt ./log.txt
# Copy file to container
docker cp config.json container-name:/etc/app/config.json
# Copy directory
docker cp container-name:/var/log ./container-logs
Depuración de Red
# Use netshoot for network debugging
docker run -it --rm --network container:target-container nicolaka/netshoot
# Inside netshoot:
# - ping, traceroute, tcpdump
# - curl, wget
# - netstat, ss, lsof
# - iperf, iftop
# Check container IP
docker inspect --format '{{.NetworkSettings.IPAddress}}' container-name
# Check network
docker network inspect network-name
# Test connectivity
docker exec container-name ping other-container
docker exec container-name curl http://other-container:8080
Problemas Comunes y Soluciones
El Contenedor No Inicia
# Check logs
docker logs container-name
# Check exit code
docker inspect --format '{{.State.ExitCode}}' container-name
# Common exit codes:
# 0 - Success
# 1 - Application error
# 125 - Docker daemon error
# 126 - Command cannot be invoked
# 127 - Command not found
# 137 - Container killed (OOM or SIGKILL)
# 139 - Segmentation fault
# 143 - Graceful termination (SIGTERM)
# Try running in foreground
docker run -it my-image
# Check if image exists
docker images | grep my-image
# Pull latest image
docker pull my-image:latest
Puerto Ya en Uso
# Find process using port
sudo netstat -tulpn | grep :8080
sudo lsof -i :8080
# Kill process
sudo kill -9 <PID>
# Or use different port
docker run -p 8081:80 nginx
El Contenedor Sale Inmediatamente
# Check if command completes
docker logs container-name
# Run with interactive shell
docker run -it --entrypoint sh my-image
# Override CMD
docker run my-image your-command
# Keep container running for debugging
docker run -d my-image tail -f /dev/null
Errores de Permiso Denegado
# Check file permissions in container
docker exec container-name ls -la /path
# Run as root to fix permissions
docker exec -u root container-name chown -R appuser:appuser /path
# Check user container runs as
docker exec container-name whoami
# Run container as specific user
docker run --user 1000:1000 my-image
Sin Memoria (OOM)
# Check if container was killed by OOM
docker inspect --format '{{.State.OOMKilled}}' container-name
# Set memory limits
docker run -m 512m --memory-swap 1g my-image
# Monitor memory usage
docker stats container-name
# Check system memory
free -h
docker system df
Disco Lleno
# Check Docker disk usage
docker system df
# Detailed view
docker system df -v
# Clean up unused resources
docker system prune -a --volumes
# Remove specific items
docker container prune
docker image prune -a
docker volume prune
docker network prune
Problemas de Resolución DNS
# Check DNS in container
docker exec container-name cat /etc/resolv.conf
# Test DNS
docker exec container-name nslookup google.com
# Use custom DNS
docker run --dns 8.8.8.8 --dns 8.8.4.4 my-image
# Set DNS in daemon.json
sudo nano /etc/docker/daemon.json
Añade:
{
"dns": ["8.8.8.8", "8.8.4.4"]
}
Problemas de Conectividad de Red
# Check container network
docker network inspect bridge
# Restart networking
docker network disconnect bridge container-name
docker network connect bridge container-name
# Check iptables rules
sudo iptables -t nat -L -n
# Restart Docker daemon
sudo systemctl restart docker
Monitoreo y Alertas
Monitoreo en Tiempo Real
# Monitor all containers
docker stats
# Monitor specific container
docker stats container-name
# No streaming (one-time output)
docker stats --no-stream
# Format output
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
Verificaciones de Salud
# In Dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost/ || exit 1
# Run with health check
docker run -d \
--name web \
--health-cmd="curl -f http://localhost/ || exit 1" \
--health-interval=30s \
--health-timeout=3s \
--health-retries=3 \
nginx
# Check health status
docker inspect --format='{{.State.Health.Status}}' web
# View health check logs
docker inspect --format='{{json .State.Health}}' web | jq
Eventos de Contenedores
# Stream events
docker events
# Filter events
docker events --filter 'type=container'
docker events --filter 'container=my-container'
docker events --filter 'event=start'
# Since timestamp
docker events --since '2024-01-01T00:00:00'
# Format output
docker events --format '{{.Time}} {{.Action}} {{.Actor.Attributes.name}}'
Pila de Logging con ELK
version: '3.8'
services:
app:
image: my-app
logging:
driver: gelf
options:
gelf-address: "udp://logstash:12201"
elasticsearch:
image: elasticsearch:8.11.0
environment:
- discovery.type=single-node
volumes:
- es-data:/usr/share/elasticsearch/data
logstash:
image: logstash:8.11.0
volumes:
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
ports:
- "12201:12201/udp"
kibana:
image: kibana:8.11.0
ports:
- "5601:5601"
environment:
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
volumes:
es-data:
Mejores Prácticas de Producción
Configurar Rotación de Logs
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"compress": "true"
}
}
Usar Logging Estructurado
// Node.js example with structured logging
const winston = require('winston');
const logger = winston.createLogger({
format: winston.format.json(),
transports: [
new winston.transports.Console()
]
});
logger.info('User login', {
userId: 123,
ip: '192.168.1.1',
timestamp: new Date().toISOString()
});
Logging Centralizado
# Send all logs to centralized system
version: '3.8'
x-logging: &default-logging
driver: syslog
options:
syslog-address: "tcp://logs.example.com:514"
tag: "{{.Name}}"
services:
web:
image: nginx
logging: *default-logging
api:
image: my-api
logging: *default-logging
Etiquetar Contenedores para Filtrado de Logs
docker run -d \
--label environment=production \
--label app=web \
--label version=1.0 \
--log-opt labels=environment,app,version \
nginx
Seguridad: No Registres Datos Sensibles
// Bad - logs password
logger.info('Login attempt', { username, password });
// Good - don't log password
logger.info('Login attempt', { username });
// Good - mask sensitive data
logger.info('API request', { apiKey: '***' + apiKey.slice(-4) });
Solución de Problemas Avanzada
Depurar Daemon de Docker
# View daemon logs
sudo journalctl -fu docker.service
# Check Docker service status
sudo systemctl status docker
# Restart Docker daemon in debug mode
sudo dockerd --debug
# View daemon configuration
docker info
Analizar Capas de Imagen
# View image history
docker history my-image
# Analyze with dive
dive my-image
# Check image size
docker images my-image
Captura de Paquetes de Red
# Capture traffic from container
docker exec container-name tcpdump -i eth0 -w /tmp/capture.pcap
# Copy capture file
docker cp container-name:/tmp/capture.pcap ./capture.pcap
# Analyze with Wireshark or tcpdump
tcpdump -r capture.pcap
Análisis de Recursos del Sistema
# Check system load
uptime
top
htop
# Check Docker resource usage
docker system df
docker stats --no-stream
# Check available disk space
df -h
# Check inode usage
df -i
Perfilado de Rendimiento
# CPU profiling
docker stats container-name
# Memory profiling
docker exec container-name ps aux --sort=-%mem | head
# Strace for system call debugging
docker exec container-name strace -p 1
# ltrace for library calls
docker exec container-name ltrace -p 1
Conclusión
El logging efectivo y la solución de problemas son esenciales para mantener entornos Docker saludables. Esta guía cubrió mecanismos de logging, técnicas de depuración y mejores prácticas de producción.
Puntos Clave
- Gestión de Logs: Usa drivers de logging apropiados y rotación
- Herramientas de Depuración: Domina docker logs, exec, inspect y stats
- Problemas Comunes: Comprende códigos de salida y problemas típicos
- Monitoreo: Implementa verificaciones de salud y monitoreo en tiempo real
- Producción: Centraliza logs, usa logging estructurado, rota logs
- Seguridad: Nunca registres datos sensibles, usa transporte de logs seguro
Referencia Rápida
# Logging
docker logs -f --tail 100 container-name # View logs
docker logs --since 1h container-name # Recent logs
docker stats container-name # Resource usage
# Debugging
docker exec -it container-name bash # Shell access
docker inspect container-name # Container details
docker top container-name # Processes
# Troubleshooting
docker events # Docker events
docker system df # Disk usage
docker system prune # Cleanup
# Health
docker inspect --format='{{.State.Health.Status}}' container-name
Próximos Pasos
- Implementar: Configura logging centralizado
- Monitorear: Despliega pila de monitoreo (Prometheus/Grafana)
- Automatizar: Crea alertas para problemas críticos
- Documentar: Mantén runbooks de solución de problemas
- Practicar: Simula fallos para práctica
- Optimizar: Ajusta retención y rotación de logs
- Asegurar: Implementa transporte y almacenamiento de logs seguro
Domina estas técnicas de logging y solución de problemas para mantener aplicaciones contenedorizadas confiables y observables.


