解析docker中的環境變量使用和常見問題解決

docker容器中的環境變量

docker能夠爲容器配置環境變量。配置的途徑有兩種:java

  1. 在製做鏡像時,經過ENV命令爲鏡像增長環境變量。在容器啓動時使用該環境變量。
  2. 在容器啓動時候,經過參數配置環境變量,若是與鏡像中有重複的環境變量,會覆蓋鏡像的環境變量。

使用docker exec {containerID} env便可查看容器中生效的環境變量。docker

[root@localhost ~]# docker exec 984 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/java/default/bin
TERM=xterm
AUTHORIZED_KEYS=**None**
JAVA_HOME=/usr/java/default
HOME=/root
...

容器啓動的進程,也就是ENTRYPOINT+CMD中,能夠經過相應的系統庫獲取容器的環境變量。session

進入到容器中,查看進程的環境變量,能夠經過/proc下進行查看。運維

cat /proc/{pid}/environ

所以,容器中的環境變量也能夠經過在容器中查看1號進程的環境變量來獲取。能夠經過執行cat /proc/1/environ |tr '\0' '\n'命令進行查看。ssh

[root@localhost ~]# docker exec -it 984 cat /proc/1/environ |tr '\0' '\n'
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/java/default/bin
TERM=xterm
AUTHORIZED_KEYS=**None**
JAVA_HOME=/usr/java/default
HOME=/root
...

通常來講,從父進程產生出來的子進程都會默認繼承父進程的環境變量。所以容器中的各個進程的環境變量應該是大體相同的。固然,在一些特殊的狀況下,環境變量也會被重置,致使產生一些誤解和問題。下面就對容器中一些常見的狀況進行相關講解。日誌

常見問題及解決

切換不一樣用戶後環境變量消失

在容器中,啓動後切換不一樣用戶,好比使用su - admin切換admin用戶後,發現配置的容器環境變量丟失了。code

這是由於切換用戶會致使環境變量重置。所以要使用su -p admin這樣的方式,才能夠繼承先前的環境變量。繼承

咱們能夠經過help來看下su的相關參數描述。進程

[root@adworderp-03a38d62-4103555841-m81qk /]# su --help
Usage: su [OPTION]... [-] [USER [ARG]...]
Change the effective user id and group id to that of USER.

...
  -m, --preserve-environment   do not reset HOME, SHELL, USER, LOGNAME
                               environment variables
  -p                           same as -m
...

容器中的亂碼問題

一些業務在遷移到容器中時,經常報告打印日誌亂碼。通常的緣由是locale沒有配置正確致使。it

能夠經過locale查看當前容器的語言環境。若是沒設置,通常會是POSIX。咱們能夠經過locale -a查看當前容器支持的語言環境,然後根據須要進行設置。
要想一勞永逸,最好的方式仍是在容器啓動或者鏡像的環境變量中添加LANG={xxx},選擇合適的語言,從而避免所以致使的亂碼問題。

ssh的環境變量問題

容器中啓用sshd,能夠方便鏈接和排障,以及進行一些平常的運維操做。
可是不少用戶進入到容器中卻發現,在docker啓動時候配置的環境變量經過env命令並不可以正常顯示。
這個的主要緣由仍是ssh爲用戶創建鏈接的時候會致使環境變量被重置。
這樣致使的最大問題就是經過ssh啓動的容器進程將沒法獲取到容器啓動時候配置的環境變量。

瞭解了原理後,這個問題有個簡單的方法解決。就是能夠經過將容器的環境變量從新設置到ssh鏈接後的session中。
具體的實現方式是,ssh鏈接後,會自動執行source /etc/profile
那麼咱們其實只要在/etc/profile追加幾行代碼,從1號進程獲取容器自己的環境變量,而後循環將環境變量export一下便可。

如下是一個簡單的for循環實現。

for item in `cat /proc/1/environ |tr '\0' '\n'`
do
 export $item
done

固然,有更簡潔的命令,就是export $(cat /proc/1/environ |tr '\0' '\n' | xargs),能夠實現一樣的效果。

相關文章
相關標籤/搜索