Sistemas de control y automatización
Implementación de contenedores Docker con sistema para arranque automatizado
Table of Contents
Por qué Combine Sistemado con Docker para Despliegues de Producción
La infraestructura moderna exige que los servicios containerizzatos sobrevivan reinicios inesperados, fallos de hardware o actualizaciones de paquetes. Mientras Docker proporciona políticas de reinicio (), estas políticas sólo funcionan siempre y cuando el daemon Docker esté funcionando. Sistémico – el sistema de entrada utilizado por Ubuntu, Debian, Fedora, CentOS y la mayoría de las distribuciones modernas de Linux – toma esto más adelante mediante la gestión del sistema de la vida del contenedor Docker
- Orden de inicio garantizado a través de directivas de dependencia (por ejemplo, después de red.target, después de docker.service)
- Registro unificado a través de , haciendo depuración directa
- Control de grano fino sobre los límites de recursos (CPU, memoria, I/O) utilizando directivas de unidad sistematizadas
- Reinicie automáticamente en el fracaso con los límites de demora configurable y de ráfaga
- Soporte para activación de tomas y arranque templado
Al envolver cada contenedor Docker en un archivo de servicio sistematizado, los equipos de operaciones obtienen una interfaz consistente para iniciar, detener y monitorear contenedores, reduciendo la dependencia de scripts ad-hoc e intervención manual.
Crear un servicio sistema para un contenedor de muelles único
El enfoque estándar implica la escritura de un archivo de unidad de servicio que llama a los comandos Docker para ejecutar y detener el contenedor. A continuación caminamos a través del proceso paso a paso, comenzando con un ejemplo básico y luego cubriendo los requisitos de producción comunes.
Paso 1: Escriba el archivo de la unidad de servicio
Crear un archivo llamado . Usar la siguiente plantilla como punto de partida:
[Unit]
Description=My Application Container
After=network-online.target docker.service
Wants=network-online.target
Requires=docker.service
[Service]
Restart=always
RestartSec=10
StartLimitBurst=3
ExecStartPre=-/usr/bin/docker kill myapp
ExecStartPre=-/usr/bin/docker rm myapp
ExecStart=/usr/bin/docker run --rm --name myapp \
-e DB_HOST=10.0.1.50 \
-e DB_PORT=5432 \
-v /data/myapp:/app/data \
-p 8080:8080 \
myregistry/myapp:latest
ExecStop=/usr/bin/docker stop -t 10 myapp
ExecStopPost=-/usr/bin/docker rm myapp
[Install]
WantedBy=multi-user.target
Explicación de las directivas clave:
- ] – asegura que el daemon Docker se está ejecutando antes de comenzar el contenedor.
- – Si se detiene Docker, este servicio también se detiene.
- ] – limpia cualquier contenedor sobrante de una pasada (el prefijo significa que las fallas aquí no son mortales).
- ]] [para eliminar automáticamente el contenedor cuando se detiene.
- – Detiene con gracia el recipiente con un tiempo de espera (10 segundos).
- ] – restaure el contenedor independientemente del código de salida.
- – espera 10 segundos antes de reestablecer.
- [Los límites se reinician a 3 intentos por intervalo (por defecto 10 segundos) para evitar los lazos de reiniciación.
Paso 2: Activar y iniciar el servicio
sudo systemctl daemon-reload
sudo systemctl enable myapp.service
sudo systemctl start myapp.service
El dice sistematizado para volver a leer los archivos de servicio. crea el sim Enlace para que el servicio comience en la bota.
Gestión del Servicio con Mandos Sistemados Estándar
Una vez que el servicio se ejecuta, lo controlas como cualquier otro servicio del sistema:
- Comienza:
- Basta:
- Reiniciar:
- Status:
- Logs: [seguir registros en vivo]
Patrones de configuración avanzados
Las implementaciones de producción a menudo requieren más que un simple . A continuación se presentan mejoras comunes que puede añadir a sus archivos de servicio sistematizados.
Pasando variables ambientales
No se recomienda la configuración o secretos de codificación dura en el archivo de servicio. En lugar de ello, utilice un archivo de entorno separado:
[Service]
EnvironmentFile=-/etc/myapp/env.conf
ExecStart=/usr/bin/docker run --rm --name myapp \
--env-file /etc/myapp/env.conf \
myregistry/myapp:latest
El prefijo antes de la ruta significa que el servicio comenzará incluso si el archivo no existe (útil durante la configuración inicial).
Redes y accesorios de puertos
Para contenedores que necesitan comunicarse entre sí en el mismo host, considere utilizar o redes de puente definidas por el usuario. Ejemplo:
ExecStart=/usr/bin/docker run --rm --name web \
--network=my-net \
-p 443:443 \
-v /etc/ssl/certs:/etc/ssl/certs:ro \
myregistry/web:latest
Si utiliza una red personalizada, asegúrese de que la red existe antes de que el servicio comience. Puede añadir un comando para crearlo:
ExecStartPre=/usr/bin/docker network create my-net
Dependencias entre los contenedores
Cuando un contenedor requiere que otro esté listo antes de comenzar (por ejemplo, una aplicación web que espera una base de datos), sistemad puede hacer cumplir el pedido. Cree un segundo archivo de servicio para la base de datos y luego:
[Unit]
Description=Web App Container
After=network-online.target docker.service mydb.service
BindsTo=mydb.service
vincula el ciclo de vida de la aplicación web con el contenedor de bases de datos – si la base de datos se detiene, también se detiene la aplicación web.
Comprobaciones y Lecturas de Salud
Los controles de salud de los docker pueden integrarse con sistematizados para evitar la disponibilidad de servicios prematura. Use con un script que encuesta el punto final de la salud:
ExecStartPost=/usr/local/bin/wait-for-health.sh http://localhost:8080/health 30
El script debe salir 0 sólo cuando el contenedor es saludable. Si falla, sistematizado marca la unidad como falló.
Limites de recursos mediante sistemas
Puede limitar la CPU de un contenedor y la memoria a nivel de grupo sin las propias banderas de recursos de Docker. Esto es especialmente útil cuando se ejecutan múltiples contenedores en un solo host:
[Service]
MemoryMax=512M
CPUQuota=50%
Estas configuraciones crean un límite difícil que se ejecuta de forma independiente de Docker.
Gestión de múltiples contenedores: Systemd vs. Docker Compose
Para un pequeño número de contenedores (por ejemplo, 2-5), los archivos de servicio sistematizados individuales son simples y sostenibles. Sin embargo, cuando un proyecto implica muchos servicios interconectados, Docker Compose se vuelve más conveniente. Todavía puede utilizar sistematizado para orquestar toda la pila Docker Compose mediante la creación de una unidad de servicio única que llama .
[Unit]
Description=My Application Stack
After=network-online.target docker.service
Requires=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/myapp
ExecStart=/usr/local/bin/docker-compose up -d
ExecStop=/usr/local/bin/docker-compose down
[Install]
WantedBy=multi-user.target
Este enfoque le da la sencillez de Compositiva para definir los servicios combinados con la gestión del ciclo de vida del sistema. Tenga en cuenta que ] se utiliza porque sale inmediatamente. mantiene la unidad en un estado "activo" hasta que ] se llame.
¿Qué método debería elegir?
- Servicios de sistema individual] – mejores para aplicaciones heredadas, servicios con estricto orden de arranque, o cuando necesite límites de recursos por contenedor.
- Docker Componga con sistemad – ideal para pilas de microservicios donde las dependencias se manejan internamente por Compose, y desea una unidad única para administrar todo el grupo.
Problemas comunes
Incluso con una configuración cuidadosa, puede encontrar problemas. A continuación se presentan frecuentes dificultades y sus soluciones.
Servicio falla con “No se puede conectar con el daemon Docker”
Esto generalmente significa que el servicio comienza antes de que el socket Docker esté listo. Asegúrese de que su unidad contiene y . También comprueba que el daemon Docker está habilitado: .
Container Restarts en un bucle
Si el contenedor sale inmediatamente, el sistemad seguirá reiniciándolo según y . Chequee los registros de contenedores con . Aumente (por ejemplo, 30 segundos) y establezca para evitar un bucle ocupado.
El servicio no para limpiamente
Un configurado incorrectamente puede dejar el contenedor funcionando. Verifique que utiliza el nombre correcto del contenedor. Use para eliminar forzadamente el contenedor si la parada falla.
Variables del medio ambiente no cargadas
Si utiliza , confirme que el archivo existe y es legible por root. Evite citar problemas – citas de tiras sistematizadas de valores variables. Para la inyección secreta, considere usar credenciales sistematizadas o un gestor secreto dedicado.
Consideraciones de seguridad
La ejecución de contenedores Docker a través de sistemad aumenta algunos puntos de seguridad:
- Siempre ejecute el servicio sistematizado como usuario no root si es posible (utilizar y ] directivas, pero asegúrese de que el usuario tenga acceso al socket Docker o se ejecute en modo sin raíz).
- Evite usar en unidades sistemadas a menos que sea absolutamente necesario.
- Utilice sólo montajes de unión de lectura () siempre que el contenedor no necesite escribir al host.
- El sistema de palancas y endurecer la unidad contra los escapes.
[Service]
ProtectSystem=strict
ReadWritePaths=/var/log/myapp
PrivateTmp=true
User=myappuser
Recursos externos
Para más lectura, consulte estas referencias oficiales:
- Políticas de reiniciamiento de los muelles Documentación
- Manual de la unidad de servicio de sistema
- Docker Compose Overview
Conclusión
Integrando los contenedores Docker te ofrece un robusto mecanismo de arranque automatizado que integra perfectamente con el resto de tu sistema Linux. Al escribir archivos de unidad de servicio bien estructurados, puedes controlar el orden de arranque, gestionar dependencias, establecer límites de recursos y monitorear registros utilizando herramientas que tu equipo de operaciones ya sabe. Si eliges servicios individuales para cada contenedor o una unidad única para orquestar una pila de Compose, sistematizado proporciona la fiabilidad y previsibilidad.
Comience con un archivo de unidad simple, pruebe a fondo, luego capa en opciones avanzadas como archivos de entorno, controles de salud y endurecimiento de seguridad. Con este enfoque, sus contenedores Docker sobrevivirán reinicios, fallos y cambios de configuración sin intervención manual, liberando a su equipo para centrarse en aplicaciones de construcción.