解析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),能够实现一样的效果。

相关文章
相关标签/搜索