Как я могу получить доступ к значениям переменных окружения Docker из задания Cron
Недавно я попытался запустить задание cron из связанного контейнера докеров и столкнуться с проблемой. Мой основной контейнер-докер связан с контейнером postgres, а его номер порта устанавливается как переменная среды докерером при создании контейнеров. Эта переменная среды не задана в ~/.profile или любом другом исходном файле, который я мог бы загрузить при запуске моего задания cron. Как я могу получить доступ к этим переменным среды из моего задания cron?
Спасибо!
Ответы
Ответ 1
Я столкнулся с этой проблемой. У меня есть контейнер докеров, который запускает cron для выполнения некоторых сценариев оболочки периодически. Мне тоже было трудно узнать, почему мои скрипты будут работать нормально, когда я вручную их выполнил в контейнере. Я пробовал все трюки создания оболочки script, которая запускала бы сначала, чтобы установить среду, но они никогда не работали для меня (скорее всего, я сделал что-то не так). Но я продолжал искать и находил это, и он действительно работает.
- Настройка оболочки запуска или точки входа script для вашего контейнера cron
- Сделать это первой строкой для выполнения
printenv | grep -v "no_proxy" >> /etc/environment
Трюк здесь - это файл /etc/environment
. Когда контейнер построен, этот файл пуст, я думаю, что это совершенно необходимо. Я нашел ссылку на этот файл на страницах man для cron (8). После просмотра всех версий cron они все ускользают от файла /etc/?
, который можно использовать для комбинирования переменных среды дочерним процессам.
Также обратите внимание, что я создал контейнер докера для запуска cron на переднем плане, cron -f
. Это помогло мне избежать других трюков при запуске tail
, чтобы сохранить контейнер.
Вот мой файл entrypoint.sh для ссылки, а мой контейнер - это изображение debian: jessie base.
printenv | grep -v "no_proxy" >> /etc/environment
cron -f
Кроме того, этот трюк работал даже с переменными среды, заданными во время команд docker run
.
Ответ 2
Я бы порекомендовал использовать declare
для экспорта вашей среды и избежания проблем (используя CMD или ENTRYPOINT или непосредственно в скрипте-обертке, который может быть вызван одним из них):
declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' >/container.env
Grep -v занимается фильтрацией переменных только для чтения.
Позже вы можете легко загрузить эту среду следующим образом:
SHELL=/bin/bash
BASH_ENV=/container.env
* * * * * root /test-cron.sh
Ответ 3
Можно добавить переменные системной среды в начало файла crontab с помощью оболочки оболочки script для запуска демона cron. Следующий пример из CentOs 7,
В файле 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
Это основано на отличном сообщении в блоге где-то, но я потерял ссылку.
Ответ 4
Окружающая среда установлена, но недоступна для задания cron. Чтобы исправить это, вы можете сделать эти две простые вещи
1) Сохраните env в файл в ENTRYPOINT или CMD
CMD env > /tmp/.MyApp.env && /bin/MyApp
2) Затем прочитайте это env в своей команде cron следующим образом:
0 5 * * * . /tmp/.MyApp.env; /bin/MyApp
Ответ 5
Чтобы избежать каких-либо странных символов, которые могут сломать ваш script, и согласно аргументам из Отметить ответ, добавьте эту строку в свой entrypoint.sh
:
env | sed -r "s/'/\\\'/gm" | sed -r "s/^([^=]+=)(.*)\$/\1'\2'/gm" \ > /etc/environment
Таким образом, если у вас есть переменная типа affinity:container==My container friend
, она будет преобразована в affinity:container='=My container\ friend
и т.д.
Ответ 6
В этом блоге подробно рассказывается обо всем, что необходимо сделать: https://roboslang.blog/post/2017-12-06-cron-docker/