Получить переменную среды из контейнера Docker


126

Какой самый простой способ получить переменную среды из контейнера докеров, который не был объявлен в файле Dockerfile ?

Например, переменная среды, которая была установлена ​​через какой-то docker exec container /bin/bashсеанс?

Я могу это сделать docker exec container env | grep ENV_VAR, но я бы предпочел что-то, что просто возвращает значение.

Я пробовал использовать docker exec container echo "$ENV_VAR", но замена, похоже, происходит за пределами контейнера, поэтому я получаю не env var из контейнера, а env var с моего собственного компьютера.

Спасибо.


Есть ли причина, по которой не следует использовать env и grep?
aisbaa 02

Мне просто нужна ценность. Если я правильно понимаю, мне нужно будет проанализировать вывод вызова grep, и я бы предпочел этого избежать.
Citronen

Я думал, что переменная, установленная в сеансе exec, не влияет на основной процесс или последующие сеансы exec?
Пол Бекотт

Ответы:


139

Правильный способ запуска echo "$ENV_VAR"внутри контейнера, чтобы в нем происходила подстановка переменных:

docker exec <container_id> bash -c 'echo "$ENV_VAR"'

4
ВНИМАНИЕ, что все эти ответы зависят от некоторой оболочки. Я не могу получить переменные env с исполняемым файлом и базовым образом с нуля.
Ричард

docker run --rm -it CONTAINER bash -c 'echo "$MY_ENV_VAR"'
Хенрик

Я получаю сообщение об ошибке «Ошибка: нет такого контейнера: контейнер». Я выполняю команду после входа в систему через SSH.
kunwar nitesh 03

1
@kunwarnitesh: вам нужно заменить «контейнер» на имя контейнера, с которым вы хотите работать.
jwodder 03

1
Сделайте containerслово таким, чтобы люди поняли, что это переменная
Анвар

117

Чтобы просмотреть все переменные env:

docker exec container env

Чтобы получить один:

docker exec container env | grep VARIABLE | cut -d'=' -f2

В моем вопросе сказано, что я бы предпочел не идти этим путем. Кроме того , последующий вопрос: docker exec container envа docker exec -it container /bin/bashзатем envвыплюнуть разные вещи. Зачем?
Citronen

Ах ... может быть, конкретный способ, которым я создаю образ докера, объясняет это ...
Цитронен

2
Хм, теперь намного сложнее. Попробуй docker inspect container.
aisbaa

docker inspect containerпохоже, есть такое же ограничение. Если я создаю переменную среды после запуска контейнера, она не отображается при вызове docker inspect(в разделе env).
Citronen

Я считаю, что это лучший ответ, чем принятый в настоящее время ответ. bashНапример, у нас есть несколько контейнеров, которые не поддерживаются командой alpine-node. Так что использование exec container bash -c "echo $ENV_VAR"не работает. Использование exec container envработает в моем случае. Использование exec container printenvтоже работает.
rahmatns

78

Вы можете использовать printenv VARIABLEвместо /bin/bash -c 'echo $VARIABLE. Это намного проще и не выполняет подстановку:

docker exec container printenv VARIABLE

7
Это должен быть окончательный ответ
Ki Jéy 06

5
или просто printenvраспечатать все переменные.
naXa 07

Это работает даже для кубернетов: kubectl exec имя-модуля printenv MY_VARIABLE.
Тибу,

58

Обратной стороной использования docker execявляется то, что для этого требуется работающий контейнер, что docker inspect -fможет быть удобно, если вы не уверены, что контейнер работает.

Пример №1. Выведите список переменных среды через пробел в указанном контейнере:

docker inspect -f \
   '{{range $index, $value := .Config.Env}}{{$value}} {{end}}' container_name

вывод будет выглядеть так:

ENV_VAR1=value1 ENV_VAR2=value2 ENV_VAR3=value3

Пример №2. Выведите каждую переменную env в новой строке и grepнеобходимые элементы, например, настройки контейнера mysql можно получить следующим образом:

docker inspect -f \
    '{{range $index, $value := .Config.Env}}{{println $value}}{{end}}' \
    container_name | grep MYSQL_

выведет:

MYSQL_PASSWORD=secret
MYSQL_ROOT_PASSWORD=supersecret
MYSQL_USER=demo
MYSQL_DATABASE=demodb
MYSQL_MAJOR=5.5
MYSQL_VERSION=5.5.52

Пример №3. Давайте изменим приведенный выше пример, чтобы получить дружественный к bash результат, который можно напрямую использовать в ваших скриптах:

docker inspect -f \
   '{{range $index, $value := .Config.Env}}export {{$value}}{{println}}{{end}}' \
   container_name | grep MYSQL

выведет:

export MYSQL_PASSWORD=secret
export MYSQL_ROOT_PASSWORD=supersecret
export MYSQL_USER=demo
export MYSQL_DATABASE=demodb
export MYSQL_MAJOR=5.5
export MYSQL_VERSION=5.5.52

Если вы хотите погрузиться глубже, перейдите к документации по текстовому / шаблонному пакету Go со всеми подробностями о формате.


1
это лучший ответ. Думаю, это должен быть ответ на отдельный вопрос (когда контейнер опущен)
Николай Кондратенко

Это единственный ответ, который у меня сработал. docker execвсегда говорил, что мой контейнер не знает.
Good Night Nerd Pride

7

Ни один из приведенных выше ответов не показывает вам, как извлечь переменную из неработающего контейнера (если вы используете echoподход с run, вы не получите никакого вывода).

Просто runс printenv, например , так:

docker run --rm <container> printenv <MY_VAR>

(Обратите внимание, что docker-composeвместо dockerтоже работает)


очень просто! Я согласился на такой подход.
opncow

или просто printenvраспечатать все переменные.
naXa 07


0

Ответ @aisbaa работает, если вам все равно, когда была объявлена ​​переменная среды. Если вам нужна переменная среды, даже если она была объявлена ​​внутри exec /bin/bashсеанса, используйте что-то вроде:

IFS="=" read -a out <<< $(docker exec container /bin/bash -c "env | grep ENV_VAR" 2>&1)

Это не очень красиво, но выполняет свою работу.

Чтобы затем получить значение, используйте:

echo ${out[1]}

См. Ответ jwodder.
Citronen

0

Эта команда проверяет среду процессов стека докеров на хосте:

pidof   dockerd containerd containerd-shim | tr ' ' '\n' \
      | xargs -L1 -I{} -- sudo xargs -a '/proc/{}/environ' -L1 -0

0

Мы можем изменить entrypointнеработающий контейнер с помощью docker runкоманды.

Пример показывает переменную среды PATH:

  1. с помощью bash and echo: В этом ответе утверждается, что echoникакого вывода не будет, что неверно.

    docker run --rm --entrypoint bash <container> -c 'echo "$PATH"'
  2. с помощью printenv

    docker run --rm --entrypoint printenv <container> PATH
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.