# 关于Docker容器中时间时区问题的测试
创始人
2024-06-01 20:31:42

关于Docker容器中时间时区问题的测试

文章目录

  • 关于Docker容器中时间时区问题的测试
    • 1 基础知识
      • 1.1 /etc/localtime
      • 1.2 /etc/timezone
    • 2 我在gitlab中遇到的问题与解决方法
    • 3 ubuntu官方镜像时区相关问题的测试
      • 3.0 官方原版测试
      • 3.1 不设置任何参数测试
      • 3.2 只设置`TZ="Asia/Shanghai"`参数测试
      • 3.3 只设置【`-v /etc/localtime:/etc/localtime`】参数测试,或设置【`TZ="Asia/Shanghai"`及`-v /etc/localtime:/etc/localtime`】参数测试(结果是一样的)
      • 3.4 冲突测试:设置【`TZ="Asia/Phnom_Penh"`】(东7区),设置【`-v /etc/localtime:/etc/localtime`】(东8区)
    • 4 最后

1 基础知识

1.1 /etc/localtime

/etc/localtime是用来描述 系统时间,如果系统时间不正确,通过修改该文件来修改时区
/etc/localtime文件通常是一个到/usr/share/zoneinfo/某时区文件的软链接,例如:`/etc/localtime -> /usr/share/zoneinfo/Etc/UTC`
/usr/share/zoneinfo/目录下是各种时区文件
可以通过软连接修改时区`ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime`,也可以通过`tzselect`修改时区。在容器中可以通过变量或挂载卷文件实现修改,具体要看Dockerfile文件的写法

1.2 /etc/timezone

/etc/timezone是用来描述本机所属时区的。有些程序是通过该文件获取时区的,比如:JAVA,也就是说/etc/timezone时区不正确,像java这样的程序,获取的时间可能不正确
修改时区:`echo 'Asia/Shanghai' >/etc/timezone`

2 我在gitlab中遇到的问题与解决方法

我在使用gitlab-ce:13.x.x版本的官方Docker镜像时(基于ubuntu 20.04),设置TZ变量后(TZ=“Asia/Shanghai”),在容器内部运行date,就会显示我设置的这个中国时区,但是gitlab备份计划生成的备份文件名却是UTC时间(gitlab.rb中的时区也已经设置为"Asia/Shanghai"了),此时我看到/etc/localtim是软链接到/usr/share/zoneinfo/Etc/UTC的,故,我把系统的/etc/localtime挂在到容器内部,再次执行备份计划就备份文件名的日期就变成正确的中国时间了。

3 ubuntu官方镜像时区相关问题的测试

注:检验时,我用的是当前最新的ubuntu的官方镜像,是基于20.04的版本打造的。

3.0 官方原版测试

官方原版ubuntu镜像没有时区配置信息,也没有时区数据文件,你看:

  • 结果:
date                 :UTC
/etc/timezone        :不存在
/etc/localtime       :不存在
/usr/share/zoneinfo  :时区数据文件也是不存在的
  • 过程:
[root@v-192-168-11-81-deploy:~]# docker run -it   --name yyy  ubuntu  bash
root@2aa65bac6540:/# 
root@2aa65bac6540:/# date
Fri Mar 10 14:48:00 UTC 2023
root@2aa65bac6540:/# 
root@2aa65bac6540:/# cat /etc/timezone
cat: /etc/timezone: No such file or directory
root@2aa65bac6540:/# 
root@2aa65bac6540:/# cat  /etc/localtime
cat: /etc/localtime: No such file or directory
root@2aa65bac6540:/# 
root@2aa65bac6540:/# ll /etc/localtime
ls: cannot access '/etc/localtime': No such file or directory
root@2aa65bac6540:/# 
root@2aa65bac6540:/# ll  /usr/share/zoneinfo
ls: cannot access '/usr/share/zoneinfo': No such file or directory
root@2aa65bac6540:/# exit
exit
[root@v-192-168-11-81-deploy:~]# 

以上是因为没有安装软件包tzdata,故,我基于ubuntu官方镜像安装tzdata构建新的补丁版的镜像【new-ubuntu】,Dockerfile内容如下:

FROM ubuntu
MAINTAINER ZZXia
RUN  apt-get update  && \apt-get install -y  tzdata

我想gitlab-ce的官方镜像也是这么干的吧

构建他docker build -t new-ubuntu ./
运行它,你会发现上面不存在的文件都有了
另:安装完tzdata后,在交互模式下,你可以运行tzselect命令以设置时区,镜像构建时不行(不方便)。

3.1 不设置任何参数测试

  • 结果:
date                 :UTC
/etc/timezone        :UTC
/etc/localtime       :UTC
/etc/localtime软链接  :UTC
  • 过程:
[root@v-192-168-11-81-deploy:~]# docker run -it   --name yyy  new-ubuntu  bash
root@3fde01074ae6:/# 
root@3fde01074ae6:/# date
2023年 03月 10日 星期五 14:23:27 UTC
root@3fde01074ae6:/# 
root@3fde01074ae6:/# cat  /etc/timezone
Etc/UTC
root@3fde01074ae6:/# 
root@3fde01074ae6:/# cat  /etc/localtime
TZif2UTCTZif2UTC
UTC0
root@3fde01074ae6:/# 
root@3fde01074ae6:/# ll  /etc/localtime 
lrwxrwxrwx 1 root root 27 Mar  9 15:10 /etc/localtime -> /usr/share/zoneinfo/Etc/UTC
root@3fde01074ae6:/# exit
exit
[root@v-192-168-11-81-deploy:~]# 

一切都在意料之中

3.2 只设置TZ="Asia/Shanghai"参数测试

  • 结果:
date                  :CST
/etc/timezone         :UTC
/etc/localtime        :UTC
/etc/localtime软链接   :UTC
  • 过程:
[root@v-192-168-11-81-deploy:~]# docker run -it  --env TZ="Asia/Shanghai"  --name yyy  new-ubuntu  bash
root@f85aa804a1fc:/# 
root@f85aa804a1fc:/# date
2023年 03月 10日 星期五 22:24:11 CST
root@f85aa804a1fc:/# 
root@f85aa804a1fc:/# cat  /etc/timezone
Etc/UTC
root@f85aa804a1fc:/# 
root@f85aa804a1fc:/# cat  /etc/localtime
TZif2UTCTZif2UTC
UTC0
root@f85aa804a1fc:/# 
root@f85aa804a1fc:/# ll  /etc/localtime 
lrwxrwxrwx 1 root root 27 Mar  9 15:10 /etc/localtime -> /usr/share/zoneinfo/Etc/UTC
root@f85aa804a1fc:/# exit
exit
[root@v-192-168-11-81-deploy:~]# 

/etc/timezone/etc/localtime都是UTC,但date输出的却是CST时区,TZ这环境变量到底是怎么达成这个结果的。在我前面gitlab-ce镜像中备份任务中却使用的是UTC时间

3.3 只设置【-v /etc/localtime:/etc/localtime】参数测试,或设置【TZ="Asia/Shanghai"-v /etc/localtime:/etc/localtime】参数测试(结果是一样的)

  • 结果:
date                  :CST
cat /etc/timezone     :UTC
cat /etc/localtime    :CST
/etc/localtime软链接   :为UTC,实际生效的是`-v`挂载的这个,即CST
  • 过程:
[root@v-192-168-11-81-deploy:~]# docker run -it  -v /etc/localtime:/etc/localtime  --name yyy  new-ubuntu  bash
root@b8d2b195f6bf:/# 
root@b8d2b195f6bf:/# date
2023年 03月 10日 星期五 22:25:12 CST
root@b8d2b195f6bf:/# 
root@b8d2b195f6bf:/# cat  /etc/timezone
Etc/UTC
root@b8d2b195f6bf:/# 
root@b8d2b195f6bf:/# cat  /etc/localtime
TZif�����y��Y^��	�p�ӽ����|@�;>�Ӌ{��B���E"�L���<��fp���A|��R i�� ~��!I}�"g� #)_�$G� %|&'e &�^(G (�@~�p�CDTCSTTZif2����~6C)�������������y������Y^������	�p�����ӽ������������|@�����;>�����Ӌ{������B�������E"�����L�������<������fp�����������A|��R i�� ~��!I}�"g� #)_�$G� %|&'e &�^(G (�@q�~�pLMTCDTCST
CST-8
root@b8d2b195f6bf:/# 
root@b8d2b195f6bf:/# ll  /etc/localtime 
lrwxrwxrwx 1 root root 27 Mar  9 15:10 /etc/localtime -> /usr/share/zoneinfo/Etc/UTC
root@b8d2b195f6bf:/# exit
exit
[root@v-192-168-11-81-deploy:~]# 

一切都在意料之中,正与我在前面【我在gitlab中遇到的问题与解决方法】一节中讲到的一样,在date与计划任务中都能达成想要的结果

3.4 冲突测试:设置【TZ="Asia/Phnom_Penh"】(东7区),设置【-v /etc/localtime:/etc/localtime】(东8区)

  • 结果:
date                  :+07
cat /etc/timezone     :UTC
cat /etc/localtime    :CST(+08)
/etc/localtime软链接   :UTC
  • 过程:
[root@v-192-168-11-81-deploy:~]# docker run -it  --env TZ="Asia/Phnom_Penh"  -v /etc/localtime:/etc/localtime  --name yyyx  my-oracle-java-8  bash
root@29561a94da99:/# 
root@29561a94da99:/# date
2023年 03月 11日 星期六 13:20:16 +07
root@29561a94da99:/# 
root@29561a94da99:/# cat /etc/timezone 
Etc/UTC
root@29561a94da99:/# 
root@29561a94da99:/# cat  /etc/localtime 
TZif�����y��Y^��	�p�ӽ����|@�;>�Ӌ{��B���E"�L���<��fp���A|��R i�� ~��!I}�"g� #)_�$G� %|&'e &�^(G (�@~�p�CDTCSTTZif2����~6C)�������������y������Y^������	�p�����ӽ������������|@�����;>�����Ӌ{������B�������E"�����L�������<������fp�����������A|��R i�� ~��!I}�"g� #)_�$G� %|&'e &�^(G (�@q�~�pLMTCDTCST
CST-8
root@29561a94da99:/# 
root@29561a94da99:/# ll  /etc/localtime 
lrwxrwxrwx 1 root root 27 3月   9 14:10 /etc/localtime -> /usr/share/zoneinfo/Etc/UTC
root@29561a94da99:/# 
root@29561a94da99:/# exit
exit
[root@v-192-168-11-81-deploy:~]# 

看到没,两个相互冲突的设置,最终date命令取得是TZ变量的设置,为什么?他是怎么做到的?网上说(简单查下)ubuntu镜像的Dockerfile是这么写的:

FROM ubuntu:bionic
ENV TZ=Asia/Shanghai
RUN apt update&& apt install -y tzdata&& echo "${TZ}" > /etc/timezone&& rm -f /etc/localtime  &&  ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime

4 最后

  • 猜测:交互程序一般会使用date的结果,但计划任务之类的程序可能会使用/etc/localtime的设置(/etc/localtime可能属于系统级的)
  • 容器中TZ变量是怎么做到影响date命令结果的,以后有时间再研究下

爱你

相关内容

热门资讯

苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...