在使用Linux操作系统或者容器的时候,我们可能会发现时间差了8
个小时,这就说明系统或者容器时区配置存在问题。
1,查看时间与时区
我们使用date
命令即可查看当前系统时间与时区:
最后的CST
就表示中国标准时间时区。
如果你的输出显示的是UTC
,就说明你的时区为世界标准时间,通常会比北京时间早8
小时:
2,修改时区
在修改时间之前,我们需要确保系统已安装tzdata
软件包,该软件包包含了全部时区的信息:
# 若不是root用户,请在命令前加上sudo
# Debian系操作系统
apt install tzdata
# Alpine操作系统
apk add tzdata
安装完成后,所有的时区数据都在/usr/share/zoneinfo
目录下:
修改时区通常有两种方式,这里分别进行讲解,大家视情况选择其一即可。
(1) 链接/etc/localtime
文件
将时区数据/usr/share/zoneinfo
想要配置的时区文件链接到/etc/localtime
文件即可,例如我们需要配置中国时区,通常将/usr/share/zoneinfo/Asia/Shanghai
链接到/etc/localtime
文件即可:
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
执行命令后,可以发现时区已成功配置:
在/usr/share/zoneinfo
目录下,Asia
目录存放全部亚洲地区的时区数据,其它目录类似,存放其它世界区域的时区数据。
(2) 使用TZ
环境变量
直接指定TZ
环境变量为标准时区名称也可以实现时区修改,例如配置为中国标准时间:
# Bash终端
export TZ="Asia/Shanghai"
# Fish终端
set -x TZ "Asia/Shanghai"
结果:
那么如何知道有哪些标准时区名称呢?事实上我们看一下/usr/share/zoneinfo
目录即可,例如:
- 中国标准时间对应的时区文件是
/usr/share/zoneinfo/Asia/Shanghai
,那么就可以推断出其标准时区名称是Asia/Shanghai
- 美国纽约时间对应的时区文件是
/usr/share/zoneinfo/America/New_York
,那么就可以推断出其标准时区名称是America/New_York
- 新加坡标准时间对应的时区文件是
/usr/share/zoneinfo/Singapore
,那么就可以推断出其标准时区名称是Singapore
需要注意的是:
- 使用
TZ
环境变量配置的时区仅在当前终端会话有效,关闭或者重启终端会失效,而链接/etc/localtime
文件是永久生效的 TZ
环境变量的优先级是最高的
3,/etc/timezone
配置文件
/etc/timezone
配置文件也是和时区配置有关的文件,其中包含文本形式的时区配置:
但需要注意的是:该配置文件通常并不是用于配置系统时区的,而是一些应用程序通过读取该文件来确定时区,该文件中仅包含所使用的时区的标准时区名称。
在一些操作系统中,可能并不存在该文件。
4,容器时区配置
通常我们运行Docker容器时会发现很多容器内时区使用的是UTC
时间,这可能影响我们数据库或者日志输出的时间等,因此在制作镜像或者运行容器时,需要做一些时区的配置。
(1) 制作镜像的时区配置
在编写Dockerfile时,我们可以通过RUN
指令安装tzdata
,并配合TZ
环境变量实现镜像默认的时区配置,假设你是用的是Debian系列镜像:
FROM debian
# 设置DEBIAN_FRONTEND为noninteractive,避免安装tzdata时出现交互式配置
ENV DEBIAN_FRONTEND=noninteractive
# 安装tzdata
RUN apt update \
&& apt install -y tzdata
# 配置时区环境变量
ENV TZ="Asia/Shanghai"
# ...
可见在安装tzdata
时,我们需要先将DEBIAN_FRONTEND
环境变量设置为noninteractive
,否则安装时会出现配置时区的交互性选项,导致制作镜像失败。如果你用的是Alpine作为基本镜像,那就不会出现该问题。
(2) 运行容器时的时区
如果镜像已经包含tzdata
软件包,那么我们运行容器时直接指定TZ
环境变量即可:
docker run -id --name xxx -e TZ="Asia/Shanghai" ...
在容器中,使用TZ
环境变量的方式会更加方便。