it-swarm.com.de

Wie kann ich von einem Cron-Job aus auf Docker-Umgebungsvariablen zugreifen?

Ich habe vor kurzem versucht, einen Cron-Job in einem verknüpften Docker-Container auszuführen, und habe ein Problem festgestellt. Mein Docker-Hauptcontainer ist mit einem Postgres-Container verknüpft, und seine Portnummer wird vom Docker bei der Erstellung des Containers als Umgebungsvariable festgelegt. Diese Umgebungsvariable ist nicht in ~/.profile oder einer anderen Quelldatei festgelegt, die ich beim Ausführen meines Cron-Jobs laden könnte. Wie kann ich dann von meinem cron-Job aus auf diese Umgebungsvariablen zugreifen?

Vielen Dank!

31
Fabio Berger

Ich bin auf das gleiche Problem gestoßen. Ich habe einen Docker-Container, der cron ausführt, um einige Shell-Skripts regelmäßig auszuführen. Es fiel mir auch schwer, herauszufinden, warum meine Skripte gut laufen würden, wenn ich sie manuell im Container ausführte. Ich habe alle Tricks ausprobiert, ein Shell-Skript zu erstellen, das zuerst ausgeführt wurde, um die Umgebung festzulegen, aber sie funktionierten nie für mich (wahrscheinlich habe ich etwas falsch gemacht). Aber ich schaute weiter und fand das und es funktioniert.

  1. Richten Sie ein Start- oder Einstiegspunkt-Shell-Skript für Ihren cron-Container ein
  2. Machen Sie dies zur ersten Zeile, die ausgeführt werden soll printenv | grep -v "no_proxy" >> /etc/environment

Der Trick hier ist die /etc/environment-Datei. Wenn der Container erstellt ist, ist diese Datei leer, denke ich absichtlich. Ich habe in den Manpages für cron (8) einen Verweis auf diese Datei gefunden. Nachdem Sie sich alle Versionen von cron angesehen haben, entziehen sie sich einer /etc/?-Datei, die Sie verwenden können, um Umgebungsvariablen an untergeordnete Prozesse zu übergeben.

Beachten Sie auch, dass ich meinen Docker-Container erstellt habe, um cron im Vordergrund cron -f auszuführen. Dies half mir, andere Tricks mit tail zu vermeiden, um den Container aufrecht zu erhalten.

Hier ist meine entrypoint.sh-Datei als Referenz und mein Container ist ein debian: jessie-Basis-Image.

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

cron -f

Dieser Trick funktionierte auch mit Umgebungsvariablen, die während der docker run-Befehle festgelegt wurden.

35
Tim Schruben

Ich würde empfehlen, declare zu verwenden, um Ihre Umgebung zu exportieren und Probleme zu vermeiden (CMD oder ENTRYPOINT oder direkt in einem Wrapper-Skript, das möglicherweise von einem von ihnen aufgerufen wird)

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

Grep -v kümmert sich darum, schreibgeschützte Variablen herauszufiltern.

Sie können diese Umgebung später einfach so laden:

Shell=/bin/bash
BASH_ENV=/container.env
* * * * * root /test-cron.sh
9
Alex Fedulov

Sie können die Systemumgebungsvariablen an den Anfang einer Crontab-Datei anhängen, indem Sie ein Wrapper-Shell-Skript zum Ausführen des Cron-Daemons verwenden. Das folgende Beispiel stammt von CentOs 7, 

In der 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

Dies basiert auf einem großartigen Blogeintrag, aber ich habe den Link verloren. 

3
Michael Moyle

Die Umgebung ist festgelegt, aber für den Cronjob nicht verfügbar. Um dies zu beheben, können Sie diese zwei einfachen Dinge ausführen

1) Speichern Sie das env in einer Datei in Ihrem ENTRYPOINT oder CMD

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

2) Dann lese das env in deinen cron-Befehl wie folgt:

0 5 * * * . /tmp/.MyApp.env; /bin/MyApp
2
Mark Riggins

Um ungewöhnlichen Zeichen zu entkommen, die Ihr Skript beschädigen könnten, und entsprechend der Argumentation von Marks Antwort , fügen Sie diese Zeile in Ihren entrypoint.sh ein:

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

Wenn Sie also eine Variable wie affinity:container==My container's friend haben, wird diese in affinity:container='=My container\'s friend und so weiter konvertiert.

0
Yajo

Sie können den folgenden Befehl ausführen

. <(xargs -0 bash -c 'printf "export %q\n" "[email protected]"' -- < /proc/1/environ)

Dies funktioniert in Ausnahmefällen, wenn Sie Umgebungsvariablen mit Sonderzeichen wie '"= Haben.

0