2015-01-05 14 views
21

Ho recentemente provato a eseguire un cron job da un container docker collegato e ho riscontrato un problema. Il mio contenitore docker principale è collegato a un contenitore postgres e il suo numero di porta viene impostato come variabile di ambiente tramite finestra mobile durante la creazione dei contenitori. Questa variabile d'ambiente non è impostata in ~/.profile o qualsiasi altro file sorgente che potrei caricare durante l'esecuzione del mio cron job. Come posso accedere a queste variabili d'ambiente dal mio cron job?Come accedere alla finestra mobile Imposta variabili di ambiente da un processo Cron

Grazie!

+1

Questo post sembra di rispondere alla domanda http://stackoverflow.com/questions/26822067/running-cron-python-jobs-within-docker – user2915097

risposta

3

È possibile aggiungere le variabili di ambiente di sistema all'inizio di un file crontab utilizzando lo script della shell wrapper per eseguire il demone cron. L'esempio seguente è da CentOS 7,

Nel Dockerfile

COPY my_cron /tmp/my_cron 
COPY bin/run-crond.sh run-crond.sh 
RUN chmod -v +x /run-crond.sh 
CMD ["/run-crond.sh"] 

run_cron.sh:

#!/bin/bash 

# prepend application environment variables to crontab 
env | egrep '^MY_VAR' | cat - /tmp/my_cron > /etc/cron.d/my_cron 

# Run cron deamon 
# -m off : sending mail is off 
# tail makes the output to cron.log viewable with the $(docker logs container_id) command 
/usr/sbin/crond -m off && tail -f /var/log/cron.log 

Questo si basa su un grande post sul blog da qualche parte, ma ho perso il link.

2

L'ambiente è impostato, ma non disponibile per il cron job. Per rimediare, si possono fare queste due cose semplici

1) Salva l'ENV in un file nel vostro EntryPoint o CMD

CMD env > /tmp/.MyApp.env && /bin/MyApp 

2) Poi leggi che ENV nel vostro comando cron in questo modo:

0 5 * * * . /tmp/.MyApp.env; /bin/MyApp 
+3

Questo non funzionerà quando i valori env contengono caratteri come spazi bianchi o pipe –

+0

Avrete bisogno di evadere correttamente env vars con spazi vuoti o pipe. – GDorn

19

Mi sono imbattuto in questo stesso problema. Ho un contenitore docker che esegue cron per eseguire periodicamente degli script di shell. Anch'io ho avuto difficoltà a scoprire perché i miei script funzionavano correttamente quando li eseguivo manualmente all'interno del contenitore. Ho provato tutti i trucchi per creare uno script di shell che sarebbe stato eseguito prima per impostare l'ambiente, ma non hanno mai funzionato per me (molto probabilmente ho fatto qualcosa di sbagliato). Ma ho continuato a cercare e ho trovato questo e funziona.

  1. Setup uno script di shell di partenza o punto di ingresso per il vostro contenitore cron
  2. Trasforma questa la prima linea per eseguire printenv | grep -v "no_proxy" >> /etc/environment

Il trucco è il file /etc/environment. Quando il contenitore è stato creato, quel file è vuoto, penso di proposito. Ho trovato un riferimento a questo file nelle pagine man per cron(8). Dopo aver esaminato tutte le versioni di cron, tutti sfuggono a un file /etc/? che è possibile utilizzare per alimentare le variabili di ambiente ai processi figli.

Inoltre, si noti che ho creato il contenitore docker per eseguire cron in primo piano, cron -f. Questo mi ha aiutato a evitare altri trucchi con tail in esecuzione per mantenere il contenitore attivo.

Ecco il mio file entrypoint.sh come riferimento e il mio contenitore è un debian: immagine di base jessie.

printenv | grep -v "no_proxy" >> /etc/environment 

cron -f 

Inoltre, questo trucco ha lavorato anche con le variabili d'ambiente impostate durante docker run comandi.

+1

printenv>/etc/environment è stata l'unica cosa che ha funzionato per me dopo 4 giorni e sperimentando diverse opzioni! Grazie! – Deko

+0

L'utilizzo di "/ etc/environment" ha funzionato per me, tuttavia tieni presente che la lettura di questo file non è un comportamento standard per cron, funziona solo se hai installato il modulo pam cron, consulta https://askubuntu.com/a/ 700126 – llmora

+0

Attenzione ai limiti dell'utilizzo del file '/ etc/environment' in quanto non vi è alcuna possibilità di sfuggire al segno di commento' # ', quindi non è possibile utilizzarlo nei valori delle variabili lì ... – AuHau

0

Per uscire eventuali caratteri strani che potrebbero rompere lo script, e in base al ragionamento da Mark's answer, aggiungere questa linea al vostro entrypoint.sh:

env | sed -r "s/'/\\\'/gm" | sed -r "s/^([^=]+=)(.*)\$/\1'\2'/gm" \ > /etc/environment 

In questo modo, se si dispone di una variabile come affinity:container==My container's friend, sarà convertito in affinity:container='=My container\'s friend e così via.

2

mi consiglia di utilizzare declare per esportare il proprio ambiente e di evitare la fuga problemi (utilizzando CMD o EntryPoint o direttamente in uno script wrapper che potrebbe essere chiamato da una di quelle):

declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env

grep -v si occupa di filtrare le variabili di sola lettura.

Si può poi facilmente caricare questo ambiente come questo:

SHELL=/bin/bash 
BASH_ENV=/container.env 
* * * * * root /test-cron.sh 
Problemi correlati