时区是Linux 系统的基础功能,设置系统时区也是很基础日常的Linux操作。然而,容器时代来了,问题也就来了。
除非精心设置,docker容器默认采用UTC时间,且容器镜像具有不可变的特性,导致容器共享产生了意想不到的困难。
先说说Linux 系统中如何识别时区?
- 如果存在环境变量$TZ
按照$TZ的设置,去文件系统/usr/share/zoneinfo下寻找对应的时区文件
如果文件不存在,则回滚到默认值UTC
- 如果不存在环境变量$TZ
读取/etc/localtime,如果不存在,则回滚到默认值UTC
(debian系还会尝试/etc/timezone文件)
时区问题对应的解决方案,总结下来共有如下7种:
- 躺平
躺平的意思就是默认使用UTC,这是一种国际化高端线路,不用付出任何努力。有问题?不存在的。
- 为容器设置ENV
为每个容器手动设置ENV,貌似合理,但重复劳动显然不值得提倡。
- 挂载时区文件到docker容器里
同上,这也是可行的方法,具体分为文件挂载和configmap挂载。
- 重构docker镜像
这显然是一个并不聪明的办法,只能解决局部问题,阻碍了容器共享,而且,对一些通用的docker镜像,逆向重构可能比较困难。
- 从容器引擎注入环境变量
这是个人认为最优雅的解决方案,在容器启动时神不知鬼不觉的注入TZ环境变量,一切都变得那么丝滑和自然,一劳永逸。cri-o 支持该功能,但containerd不支持。
- k8stz
这是一个神奇的项目,可以为k8s集群里所有容器的注入时区,位于
https://github.com/k8tz/k8tz,可以了解下。
- 应用程序内指定时区
已知mysql、java、php等程序可以在程序范围内指定时区,可以是配置文件,启动参数,或代码内部。
欢迎评论交流,以便支持我进行更多的创作。