Saltar al contenido

AWS Elastic Beanstalk, ejecutando un cronjob

Traemos la mejor respuesta que encontramos online. Nuestro deseo es que te sea útil y si quieres compartir alguna mejora siente la libertad de hacerlo..

Solución:

Así es como agregué un trabajo cron a Elastic Beanstalk:

Cree una carpeta en la raíz de su aplicación llamada .ebextensions si aún no existe. Luego cree un archivo de configuración dentro de la carpeta .ebextensions. Usaré example.config con fines ilustrativos. Luego agregue esto a example.config

container_commands:
  01_some_cron_job:
    command: "cat .ebextensions/some_cron_job.txt > /etc/cron.d/some_cron_job && chmod 644 /etc/cron.d/some_cron_job"
    leader_only: true

Este es un archivo de configuración YAML para Elastic Beanstalk. Cuando copie esto en su editor de texto, asegúrese de que su editor de texto use espacios en lugar de tabulaciones. De lo contrario, obtendrá un error YAML cuando envíe esto a EB.

Entonces, lo que esto hace es crear un comando llamado 01_some_cron_job. Los comandos se ejecutan en orden alfabético, por lo que el 01 se asegura de que se ejecute como el primer comando.

Luego, el comando toma el contenido de un archivo llamado some_cron_job.txt y lo agrega a un archivo llamado some_cron_job en /etc/cron.d.

Luego, el comando cambia los permisos en el archivo /etc/cron.d/some_cron_job.

El líder_solo key garantiza que el comando solo se ejecute en la instancia ec2 que se considera líder. En lugar de ejecutarse en cada instancia ec2 que pueda tener en ejecución.

Luego cree un archivo llamado some_cron_job.txt dentro de la carpeta .ebextensions. Colocará sus trabajos cron en este archivo.

Así por ejemplo:

# The newline at the end of this file is extremely important.  Cron won't run without it.
* * * * * root /usr/bin/php some-php-script-here > /dev/null

Entonces, este trabajo cron se ejecutará cada minuto de cada hora de cada día como usuario raíz y descartará la salida a /dev/null. /usr/bin/php es la ruta a php. Luego reemplace some-php-script-here con la ruta a su archivo php. Obviamente, esto supone que su trabajo cron necesita ejecutar un archivo PHP.

Además, asegúrese de que el archivo some_cron_job.txt tenga una nueva línea al final del archivo, como dice el comentario. De lo contrario, cron no se ejecutará.

Actualizar:
Hay un problema con esta solución cuando Elastic Beanstalk amplía sus instancias. Por ejemplo, supongamos que tiene una instancia con el trabajo cron en ejecución. Obtiene un aumento en el tráfico, por lo que Elastic Beanstalk lo escala hasta dos instancias. leader_only se asegurará de que solo tenga un trabajo cron ejecutándose entre las dos instancias. Su tráfico disminuye y Elastic Beanstalk lo reduce a una instancia. Pero en lugar de finalizar la segunda instancia, Elastic Beanstalk finaliza la primera instancia que era líder. Ahora no tiene ningún trabajo cron en ejecución, ya que solo se estaban ejecutando en la primera instancia que finalizó. Vea los comentarios a continuación.

Actualización 2:
Solo aclarando esto a partir de los comentarios a continuación: AWS ahora tiene protección contra la terminación automática de instancias. Simplemente habilítelo en su instancia de líder y estará listo para comenzar. — Nicolás Arévalo el 28 oct.

Esta es la forma oficial de hacerlo ahora (2015+). Intente esto primero, es el método más fácil actualmente disponible y también el más confiable.

De acuerdo con los documentos actuales, uno es capaz de ejecutar tareas periódicas en su llamado nivel de trabajador.

Citando la documentación:

AWS Elastic Beanstalk admite tareas periódicas para niveles de entornos de trabajo en entornos que ejecutan una configuración predefinida con una pila de soluciones que contiene “v1.2.0” en el nombre del contenedor. Debes crear un nuevo entorno.

También es interesante la parte sobre cron.yaml:

Para invocar tareas periódicas, el paquete fuente de su aplicación debe incluir un archivo cron.yaml en el nivel raíz. El archivo debe contener información sobre las tareas periódicas que desea programar. Especifique esta información utilizando la sintaxis crontab estándar.

Actualizar: Pudimos conseguir este trabajo. Aquí hay algunos errores importantes de nuestra experiencia (plataforma Node.js):

  • Cuando usas cron.yaml archivo, asegúrese de tener la última versión de awsebcli, ya que las versiones anteriores no funcionarán correctamente.
  • También es vital crear un nuevo entorno (al menos en nuestro caso lo fue), no solo clonar el antiguo.
  • Si desea asegurarse de que CRON sea compatible con su instancia de nivel de trabajador de EC2, acceda a ella mediante ssh (eb ssh), y correr cat /var/log/aws-sqsd/default.log. Debe informar como aws-sqsd 2.0 (2015-02-18). Si no tiene la versión 2.0, algo salió mal al crear su entorno y necesita crear uno nuevo como se indicó anteriormente.

Con respecto a la respuesta de jamieb, y como menciona alrdinleal, puede usar la propiedad ‘leader_only’ para asegurarse de que solo una instancia EC2 ejecute el trabajo cron.

Cita tomada de http://docs.amazonwebservices.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html:

puede usar leader_only. Se elige una instancia para que sea líder en un grupo de Auto Scaling. Si el valor leader_only se establece en trueel comando se ejecuta solo en la instancia que está marcada como líder.

Estoy tratando de lograr algo similar en mi eb, así que actualizaré mi publicación si lo resuelvo.

ACTUALIZAR:

Ok, ahora tengo cronjobs en funcionamiento usando la siguiente configuración de eb:

files:
  "/tmp/cronjob" :
    mode: "000777"
    owner: ec2-user
    group: ec2-user
    content: |
      # clear expired baskets
      */10 * * * * /usr/bin/wget -o /dev/null http://blah.elasticbeanstalk.com/basket/purge > $HOME/basket_purge.log 2>&1
      # clean up files created by above cronjob
      30 23 * * * rm $HOME/purge*
    encoding: plain 
container_commands:
  purge_basket: 
    command: crontab /tmp/cronjob
    leader_only: true
commands:
  delete_cronjob_file: 
    command: rm /tmp/cronjob

Esencialmente, creo un archivo temporal con los cronjobs y luego configuro el crontab para leer desde el archivo temporal, luego elimino el archivo temporal después. Espero que esto ayude.

Si para ti ha resultado de ayuda este post, sería de mucha ayuda si lo compartes con el resto entusiastas de la programación de esta forma nos ayudas a dar difusión a esta información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *