问题描述
是最近在使用k8s的过程中出现的一个问题,我在deployment 的yaml文件中,给pod配置了env环境变量,类似的如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deploy
namespace: test
spec:
template:
spec:
containers:
- env:
- name: test-key
value: test-value
可以看到我在设置这个env环境变量时,变量名使用了小写,然后pod启动后,我的程序里没有读到这个变量,我通过sh
登录容器之后执行env
命令,排查发现这个变量也没有出现在环境变量中。
后来,我又通过bash
登录容器,居然发现这个变量又出现了。
原因
因为我的dockerfile里是直接使用CMD启动程序的,所以我们默认的程序也是通过sh
启动,在容器中执行 ps aux
也可以看到,容器内的应用进程是以sh
启动的。
sh# ps aux
PID USER TIME COMMAND
1 root 11:42 java -Xmx2g -Xms2g -Xmn1024m -XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -XX:+ExplicitGCInvokesConcurrent -XX:+PrintGC -XX:+PrintGCD
4265 root 0:00 /bin/sh
然后问题就比较清楚了,我在k8s中设置的变量只注入到了bash shell
中,却没有注入到sh shell
里,但是通常情况下,我们的/bin/sh
只是一个指向/bin/bash
的软连接,不应该出现不一致的情况。
但是我登陆容器之后通过 ls -lh /bin/sh
命令发现,容器中的 /bin/sh
实际指向的却是dash shell
。
# ls -lh /bin/sh
lrwxrwxrwx 1 root root 4 Jan 24 2017 /bin/sh -> dash
到这里就明白为什么了,后来查阅资料发现debain
和ubuntu
的系统都是默认指向了dash
, 而我使用的基础镜像恰好是基于debain
的。
解决办法
解决办法就比较简单了,其实我们只要修改一下sh
的软连接指向即可,在dockerfile中运行如下命令:
# 修改默认的shell
RUN ln -sf /bin/bash /bin/sh