1.问题描述
在kubernetes环境中,我们有一个微服务,微服务运行过程中需要启动新任务进程,任务进程输出的log4j2日志中时区与容器系统的时区不一致,相差8个小时。
2.问题分析
现在我们要找到为什么会相差8个小时。
在容器中,我们模拟任务启动方式查看对应时区环境变量,过程如下所示:
bash-4.2#
bash-4.2# date
Thu Feb 2 11:22:15 CST 2024
bash-4.2#
bash-4.2# echo $TZ
Asia/Shanghai
bash-4.2#
bash-4.2#
bash-4.2#
bash-4.2# su hadoop
[hadoop@abc-gateway-0 /]$ date
Thu Feb 2 11:22:30 CST 2024
[hadoop@abc-gateway-0 /]$ echo $TZ
Asia/Shanghai
[hadoop@abc-gateway-0 /]$ exit
exit
bash-4.2#
bash-4.2#
bash-4.2# su - hadoop
Last login: Thu Feb 2 11:22:33 CST 2024 on pts/0
[hadoop@abc-gateway-0 ~]$ date
Thu Feb 2 03:22:43 UTC 2024
[hadoop@abc-gateway-0 ~]$ echo $TZ
[hadoop@abc-gateway-0 ~]$
在定义pod的yaml文件中,我们找到了对TZ环境变量的设置,如下所示:
apiVersion: v1
kind: Pod
spec:
containers:
- env:
- name: TZ
value: Asia/Shanghai
- name: SERVICE_NAME
value: gateway
通过上述的日志信息,我们可以得到以下信息:容器的启动过程中设置了TZ环境变量,所以进入容器后可以看到TZ环境变量的值。但当通过“su - {username}”切换用户来启动进程时,会重新刷新环境变量,而/etc/profile、/etc/profile.d/*.sh、/etc/bashrc、$HOME/.bash_profile、$HOME/.bashrc中并没有设置对应用户的TZ环境变量,所以使用默认的UTC时区。所以产生了时区的差异。
3.解决方案
参考以上分析,解决方案有两种:
(1)在容器内部启动新的任务进程时,直接通过“su {username}”来切换用户启动,而不是通过“su - {username}”来切换用户启动,环境变量的切换。
(2)在用户的$HOME/.bash_profile、$HOME/.bashrc中设置TZ环境变量,切换时区。
这里就引发了一个问题:容器内部启动任务进程切换用户环境变量的合理性。
现在看来,在启动pod的yaml配置文件、以及创建image的dockerfile中都可以设置多个ENV,保证了这个pod运行时需要用到的环境变量,如果在pod中需要切换用户环境变量的话(su - {username}),则需要在$HOME/.bash_profile、$HOME/.bashrc中重新设置这些环境变量,这个实现起来会很复杂,应该使用“su username”的方式。