Вопрос или проблема
У меня в /etc/environment
следующее:
http_proxy=http://myproxy.net:12345
После перезагрузки машины я вхожу в систему и проверяю переменную:
root@d6c44fa03243:/# echo $http_proxy
(пусто)
Почему переменная не установлена?
Примечание: я должен упомянуть, что это контейнер Docker, хотя я не вижу, почему это должно иметь значение.
РЕДАКТИРОВАНИЕ
Дополнительные сведения о системе (Ubuntu 16.04.4 Xenial Xerus
):
root@d6c44fa03243:/# uname -a
Linux d6c44fa03243 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:23:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
root@d6c44fa03243:/# cat /etc/issue
Ubuntu 16.04.4 LTS \n \l
РЕДАКТИРОВАНИЕ2
Согласно документации Ubuntu:
/etc/environment
Этот файл предназначен специально для системных настроек переменных среды. Это не сценарий, а представляет собой выражения присваивания, по одному на строку.
У меня (была) эта проблема на Ubuntu 18.04. Я не смог заставить /etc/environment
работать, но использовал сценарий в /etc/profile.d/
(как задокументировано здесь), и это сработало.
Для получения дополнительной информации, см. мой ответ на этот связанный вопрос на askubuntu.com. Надеюсь, это поможет 🙂
Поскольку инструменты UNIX созданы с учетом прозрачности (гл. 6), вы можете найти ответ с помощью grep
. Не имеет значения, работаете ли вы с полной ОС или контейнером (в последнем случае вам, возможно, придется предпринять дополнительные шаги для установки необходимых инструментов).
Убедитесь, что у вас установлен grep
в вашей ОС, и выполните sudo grep -R "/etc/environment" /etc/*
. Это поисковик системных сценариев и конфигураций, чтобы увидеть, какие из них используют этот файл. В стандартном ящике ubuntu/xenial64 vagrant сценарии и конфигурации, использующие этот файл, в основном находятся в /etc/init.d/
/etc/pam.d/
и /etc/rc.*.*
.
Следующие конфигурации определяют, как переменные в /etc/environment
устанавливаются в моей оболочке:
/etc/pam.d/su
/etc/pam.d/sshd
Из man pam_env
:
Модуль pam_env PAM позволяет устанавливать или снимать переменные среды.
…Этот модуль также может разбирать файл с простыми парами KEY=VAL на отдельных строках (по умолчанию /etc/environment). Вы можете изменить файл по умолчанию для разбора с помощью флага envfile и включить или выключить его, установив флаг readenv в 1 или 0 соответственно.
…
Выполните аналогичный поиск в вашем контейнере Docker. Вы можете проверить, использует ли ваш контейнер pam_env.so
.
Наиболее вероятно, что лучшим решением будет создать процесс инициализации, который создаст переменные среды из /etc/environment
, но этот совет дается без понимания того, что вы строите. Например, использования в `/etc/rc*.d/ могут быть хорошими примерами для достижения этой цели.
Большинство людей следуют совету @ben-njeri и устанавливают переменные в файлах настроек по умолчанию для оболочки bash.
Настройте файлы /etc/profile
или ~/.bashrc
или ~/.bash_profile
для экспорта переменных при запуске новой оболочки.
/etc/profile
предназначен для всей системы, а другие — для конкретных пользователей.
Просто добавьте такие строки в конце:
export http_proxy="http://myproxy.net:12345"
export ftp_proxy="http://myproxy.net:12345"
export https_proxy="http://myproxy.net:12345"
Таким образом, каждый раз при запуске оболочки переменные будут загружаться, и вы сможете их использовать.
Ответ или решение
При настройке переменной окружения в файле /etc/environment
и последующей проверке ее в системе Docker-контейнера, возникает проблема, когда переменная не устанавливается должным образом. В данном случае речь идет о переменной http_proxy
, которая должна была бы быть доступна после перезагрузки системы, но при проверке через команду echo $http_proxy
в терминале остается пустой.
Обоснование (Теория)
Первоначально, необходимо понять, как система Linux управляет и загружает переменные окружения. Файл /etc/environment
был разработан для системных настроек переменных окружения и задуман быть не скриптом, а простым списком пар "ключ-значение". Фактически, он считывается при входе пользователя в систему через разные механизмы, такие как модули PAM (Pluggable Authentication Modules), которые позволяют системе интегрировать различные методы аутентификации. В частности, pam_env.so
– это модуль, который читает и устанавливает значения переменных из /etc/environment
.
Однако, контейнеры Docker обладают своими особенностями. Контейнеры чаще всего представляют капсульные, изолированные окружения, которые не всегда взаимодействуют с файловой системой хоста самыми прямыми способами. В то время как Docker-контейнер может работать под управлением Ubuntu, как в описанном случае с Ubuntu 16.04.4 Xenial Xerus, механизмы аутентификации и конфигурации окружения иногда работают иначе.
Пример
В неприятной ситуации, подобной описанной, пользователь добавил строку http_proxy=http://myproxy.net:12345
в файл /etc/environment
, ожидая, что она будет автоматически подхвачена системой после перезагрузки. Тем не менее, результаты показывают, что переменная не устанавливалась должным образом.
Это связано с тем, что в контейнерах Docker процессы не всегда инициируют читающие шаги, как это было бы в традиционной установке операционной системы. В стандартной среде, при входе в систему файлы инициализации, такие как /etc/profile
, /etc/bash.bashrc
, и другие пользовательские скрипты, выполнялись бы при запуске сессии оболочки. Однако, в изолированном окружении, таком как Docker-контейнер, сессия может не инициировать те же скрипты конфигурации окружения. Это особенно верно, если запуск осуществляется не через интерпретатор, который поддерживает PAM.
Применение (Решение)
Существует несколько подходов для решения этой проблемы:
-
Использование Docker ENV: Наиболее прямолинейный способ – установить переменные окружения непосредственно через команду Docker, используя директиву
ENV
в вашемDockerfile
, или в командной строке при запуске контейнера. Например:ENV http_proxy=http://myproxy.net:12345
Или при запуске контейнера:
docker run -e http_proxy=http://myproxy.net:12345 <image_name>
-
Использование скриптов и файлов инициализации: Можно создавать собственные скрипты, которые будут выполняться при запуске контейнера. Один из методов – добавить скрипт запуска в
/etc/profile.d/
, который будет запускаться при каждой инициализации оболочки, устанавливая необходимые переменные:echo 'export http_proxy=http://myproxy.net:12345' > /etc/profile.d/myenvvars.sh
-
Установка через
bashrc
иprofile
: Вы можете изменить.bashrc
или.bash_profile
для назначенного пользователя внутри контейнера, добавив строки экспорта переменной, что гарантирует их загрузку в новых сеансах оболочки:export http_proxy=http://myproxy.net:12345
В заключение, важно учитывать специфику работы приложения и способ применения контейнеров Docker. Понимание различий между традиционными системами и контейнерами позволяет более эффективно управлять конфигурациями окружения и минимизировать проблемы, подобные описанной.