La ejecución de tareas en segundo plano según una programación es un requisito tipificado de los servicios de backend. La configuración solía ser simple: definiría sus tareas en el crontab
y llámalo un día. Veamos cómo puede utilizar cron
mientras usa Docker para la implementación.
La contenedorización de sus servicios aumenta la productividad de los desarrolladores. Al mismo tiempo, puede dejarlo preguntándose cómo las preocupaciones de los administradores de sistemas tradicionales se asignan a los conceptos de Docker. Tienes varias opciones al usar cron
con contenedores Docker y los exploraremos a continuación en orden de idoneidad. Antiguamente de continuar, asegúrese de acaecer creado una imagen de Docker de su aplicación.
Uso de Crontab del huésped
En su forma más básica, siempre puede utilizar el cron
instalación del host que ejecuta Docker Engine. Comprobar cron
está instalado y luego edite el crontab
como ordinario.
Puedes usar docker exec
para ejecutar un comando adentro de un contenedor existente:
*/5 * * * * docker exec example_app_container /example-scheduled-task.sh
Esto solo funcionará si puede estar seguro del nombre del contenedor con anticipación. Normalmente es mejor crear un nuevo contenedor que exista nada más para ejecutar la tarea:
*/5 * * * * docker run --rm example_app_image:latest /example-scheduled-task.sh
Cada cinco minutos, su sistema cron
La instalación creará un nuevo contenedor Docker usando la imagen de su aplicación. Docker ejecutará el /example-scheduled-task.sh
script adentro del contenedor. El contenedor será destruido (--rm
) una vez que finaliza el script.
Uso de Cron adentro de sus contenedores
Usando el huésped crontab
rompe la contenedorización de Docker ya que las tareas programadas requieren una configuración manual en su sistema. Necesitarás asegurarte cron
está instalado en cada host en el que implemente. Si perfectamente puede ser útil en el mejora, debe inquirir integrar cron
en sus servicios Dockerized cuando sea posible.
Las imágenes colchoneta de Docker más populares no incluyen cron
demonio de forma predeterminada. Puede instalarlo adentro de su Dockerfile
y luego registre su aplicación crontab
.
Primero, cree un nuevo crontab
archivo adentro de su colchoneta de código:
*/5 * * * * /usr/bin/sh /example-scheduled-task.sh
A continuación, modifique su Dockerfile
instalar cron
y registra tu crontab
– así es como puede hacer eso con una imagen basada en Debian:
RUN apt-get update && apt-get install -y cron COPY example-crontab /etc/cron.d/example-crontab RUN chmod 0644 /etc/cron.d/example-crontab && crontab /etc/cron.d/example-crontab
Instalamos cron
y copie nuestro código colchoneta crontab
en el /etc/cron.d
directorio. A continuación, necesitamos modificar los permisos en nuestro crontab
para cerciorarse de que sea accesible para cron
. Finalmente, use el crontab
comando para dar a conocer el archivo al cron
demonio.
Para completar esta configuración, deberá modificar el comando o el punto de entrada de su imagen para iniciar el cron
daemon cuando los contenedores comienzan a ejecutarse. No puedes conseguir esto con un RUN
etapa en tu Dockerfile
porque estos son pasos transitorios que no persisten más allá de la etapa de construcción de la imagen. El servicio se iniciaría adentro del contenedor efímero utilizado para construir la capa, no en los contenedores finales que ejecutan la imagen completa.
Si la única tarea de su contenedor es ejecutar cron
– que discutiremos más a continuación – puede unir ENTRYPOINT ["cron", "-f"]
para usted Dockerfile
para lanzarlo como el proceso de primer plano. Si necesita suministrar otro proceso en primer plano, como un servidor web, debe crear un script de punto de entrada dedicado (p. Ej. ENTRYPOINT ["bash", "init.sh"]
) y añadir service cron start
como un comando adentro de ese archivo.
Separando Cron de los servicios de su aplicación
La implementación de la configuración descrita en la sección susodicho proporciona una posibilidad más sólida que encargar en el host crontab
. Añadiendo el cron
daemon a los contenedores que sirven a su aplicación asegura que cualquier persona que consuma su imagen de Docker tendrá las tareas programadas configuradas automáticamente.
Sin secuestro, esto todavía da como resultado una mezcla de preocupaciones. Sus contenedores terminan con dos responsabilidades: en primer área, proporcionar la funcionalidad de la aplicación y, en segundo área, suministrar cron
vivo y ejecutar las tareas programadas. Idealmente, cada contenedor debería proporcionar una pelotón específica de funcionalidad.
Siempre que sea posible, debe ejecutar su cron
tareas en un contenedor separado de su aplicación. Si está creando un backend web, eso significaría un contenedor para proporcionar su servidor web y otro que se ejecuta cron
en primer plano.
Sin esta separación, no podrá utilizar un orquestador como Docker Swarm o Kubernetes para ejecutar varias réplicas de su aplicación. Cada contenedor funcionaría por su cuenta cron
daemon, lo que provoca que las tareas programadas se ejecuten varias veces. Esto se puede mitigar mediante el uso de archivos de corte vinculados a un comba Docker compartido. No obstante, es más sencillo de suministrar enfrentarse el problema de raíz e introducir un contenedor dedicado para el cron
demonio.
Generalmente, querrá que los dos contenedores se basen en la imagen de Docker de su aplicación. Cada uno de ellos necesitará conexiones a los volúmenes y redes de Docker de su servicio. Esto asegurará cron
El contenedor tiene un entorno idéntico al contenedor de la aplicación, con la única diferencia del proceso de primer plano.
Esta no es una regla estricta; en algunos proyectos, sus tareas programadas pueden ser scripts triviales que operan independientemente de su colchoneta de código. En ese caso, el cron
contenedor puede usar una imagen colchoneta mínima y eliminar las conexiones a medios periféricos innecesarios.
Una forma de configurarlo con un cron
contenedor sería usar docker-compose
. Definirías el cron
contenedor como servicio extra. Puede usar la imagen colchoneta de su aplicación, anulando el comando de punto de entrada para iniciar el cron
demonio. Utilizando docker-compose
asimismo simplifica la conexión del contenedor a los volúmenes y redes compartidos que necesite.
version: "3" services: app: image: demo-image:latest volumes: - data:/app-data cron: image: demo-image:latest entrypoint: /bin/bash command: ["cron", "-f"] volumes: - data:/app-data volumes: data:
Usando el ejemplo susodicho, un contenedor sirve a nuestra aplicación usando el punto de entrada predeterminado en la imagen. Asegúrate de que esto funcione no iniciar el cron
¡demonio! El segundo contenedor anula el punto de entrada de la imagen para ejecutar cron
. Mientras la imagen todavía tenga cron
instalado y tu crontab
configurado, puede utilizar docker-compose up
para que aparezca su solicitud.
Uso de trabajos cron de Kubernetes
Finalmente, veamos un ejemplo simple de ejecución de tareas programadas adentro de Kubernetes. Kubernetes viene con su propio CronJob
petición que puede utilizar en sus manifiestos.
No necesitas instalar cron
en su imagen o configure contenedores especializados si está utilizando Kubernetes. Sé consciente de CronJob
es un petición beta que puede cambiar en futuras versiones de Kubernetes.
apiVersion: batch/v1beta1 kind: CronJob metadata: name: my-cron namespace: my-namespace spec: schedule: "*/5 * * * *" concurrencyPolicy: Forbid jobTemplate: spec: template: spec: containers: - name: my-container image: my-image:latest command: ["/bin/bash", "/my-cron-script.sh"] restartPolicy: OnFailure
Aplique el manifiesto susodicho a su clúster para crear un nuevo cron
trabajo que se ejecutará /my-cron-script.sh
adentro de su recipiente cada cinco minutos. La frecuencia se da como regular cron
definición a la schedule
secreto en el petición spec
.
Puede personalizar el ConcurrencyPolicy
para controlar si Kubernetes permite que sus trabajos se superpongan. Por defecto es Allow
pero se puede cambiar a Forbid
(evitar que se inicien nuevos trabajos mientras ya exista uno) o Replace
(terminar un trabajo existente tan pronto como comience uno nuevo).
El uso del petición integrado de Kubernetes es la forma recomendada de ordenar las tareas programadas adentro de sus clústeres. Puede ceder fácilmente a los registros de trabajos y no necesita preocuparse por preparar sus contenedores para su uso con cron
. Solo necesita producir una imagen de Docker que contenga todo lo que sus tareas necesitan para ejecutarse. Kubernetes se encargará de crear y destruir instancias de contenedores según el cronograma que especifique.