date顯示的是CST標(biāo)準(zhǔn)時(shí)間,使用timedatectl查看localtime依舊為UTC時(shí)間。
時(shí)區(qū)為Asia/Shanghai,但是顯示卻為(UTC+0000)
查了很多網(wǎng)上的辦法,都沒(méi)解決。最后發(fā)現(xiàn)是/usr/share/zoneinfo/Asia/Shanghai里的內(nèi)容被換成UTC的內(nèi)容,最后找了虛擬機(jī)的正確文件替換了/usr/share/zoneinfo/Asia/Shanghai,
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 重新做軟鏈
重啟就發(fā)現(xiàn)UTC變成(+0800)啦
————————————————----------------------------------------------------------------------------
/etc/localtime是最重要的時(shí)間設(shè)置,運(yùn)行容器時(shí),如果想要修改docker鏡像中默認(rèn)的時(shí)區(qū),只能通過(guò)-v /etc/localtime:/etc/localtime 掛載卷的方式(你不會(huì)想啟動(dòng)之后進(jìn)到容器內(nèi)部修改吧),/etc/timezone可以用相同的方式設(shè)置
TZ是系統(tǒng)內(nèi)部變量,但此變量默認(rèn)不存在,此時(shí)date命令會(huì)使用/etc/localtime中的設(shè)置。如果設(shè)置了TZ變量,則date命令會(huì)輸出TZ變量設(shè)置的時(shí)區(qū)時(shí)間
1.1 /etc/localtime
/etc/localtime是用來(lái)描述 系統(tǒng)時(shí)間,如果系統(tǒng)時(shí)間不正確,通過(guò)修改該文件來(lái)修改時(shí)區(qū)
/etc/localtime文件通常是一個(gè)到/usr/share/zoneinfo/某時(shí)區(qū)文件的軟鏈接,例如:`/etc/localtime -> /usr/share/zoneinfo/Etc/UTC`
/usr/share/zoneinfo/目錄下是各種時(shí)區(qū)文件
可以通過(guò)軟連接修改時(shí)區(qū)`ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime`,也可以通過(guò)`tzselect`修改時(shí)區(qū)。在容器中可以通過(guò)變量或掛載卷文件實(shí)現(xiàn)修改,具體要看Dockerfile文件的寫法
1.2 /etc/timezone
/etc/timezone是用來(lái)描述本機(jī)所屬時(shí)區(qū)的。有些程序是通過(guò)該文件獲取時(shí)區(qū)的,比如:JAVA,也就是說(shuō)/etc/timezone時(shí)區(qū)不正確,像java這樣的程序,獲取的時(shí)間可能不正確
修改時(shí)區(qū):`echo 'Asia/Shanghai' >/etc/timezone`
2 我在gitlab中遇到的問(wèn)題與解決方法
我在使用gitlab-ce:13.x.x版本的官方Docker鏡像時(shí)(基于ubuntu 20.04),設(shè)置TZ變量后(TZ=“Asia/Shanghai”),在容器內(nèi)部運(yùn)行date,就會(huì)顯示我設(shè)置的這個(gè)中國(guó)時(shí)區(qū),但是gitlab備份計(jì)劃生成的備份文件名卻是UTC時(shí)間(gitlab.rb中的時(shí)區(qū)也已經(jīng)設(shè)置為"Asia/Shanghai"了),此時(shí)我看到/etc/localtim是軟鏈接到/usr/share/zoneinfo/Etc/UTC的,故,我把系統(tǒng)的/etc/localtime掛在到容器內(nèi)部,再次執(zhí)行備份計(jì)劃就備份文件名的日期就變成正確的中國(guó)時(shí)間了
3 ubuntu官方鏡像時(shí)區(qū)相關(guān)問(wèn)題的測(cè)試
注:檢驗(yàn)時(shí),我用的是當(dāng)前最新的ubuntu的官方鏡像,是基于20.04的版本打造的。
3.0 官方原版測(cè)試
官方原版ubuntu鏡像沒(méi)有時(shí)區(qū)配置信息,也沒(méi)有時(shí)區(qū)數(shù)據(jù)文件,你看:
結(jié)果:
date? ? ? ? ? ? ? ? :UTC
/etc/timezone? ? ? ? :不存在
/etc/localtime? ? ? :不存在
/usr/share/zoneinfo? :時(shí)區(qū)數(shù)據(jù)文件也是不存在的
過(guò)程:
[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:~]#
以上是因?yàn)闆](méi)有安裝軟件包tzdata,故,我基于ubuntu官方鏡像安裝tzdata構(gòu)建新的補(bǔ)丁版的鏡像【new-ubuntu】,Dockerfile內(nèi)容如下:
FROM ubuntu
MAINTAINER ZZXia
RUN? apt-get update? && apt-get install -y? tzdata
我想gitlab-ce的官方鏡像也是這么干的吧
構(gòu)建他docker build -t new-ubuntu ./
運(yùn)行它,你會(huì)發(fā)現(xiàn)上面不存在的文件都有了
另:安裝完tzdata后,在交互模式下,你可以運(yùn)行tzselect命令以設(shè)置時(shí)區(qū),鏡像構(gòu)建時(shí)不行(不方便)。
3.1 不設(shè)置任何參數(shù)測(cè)試
結(jié)果:
date? ? ? ? ? ? ? ? :UTC
/etc/timezone? ? ? ? :UTC
/etc/localtime? ? ? :UTC
/etc/localtime軟鏈接? :UTC
過(guò)程:
[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
一切都在意料之中
3.2 只設(shè)置TZ="Asia/Shanghai"參數(shù)測(cè)試
結(jié)果:
date? ? ? ? ? ? ? ? ? :CST
/etc/timezone? ? ? ? :UTC
/etc/localtime? ? ? ? :UTC
/etc/localtime軟鏈接? :UTC
過(guò)程:
[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
/etc/timezone及/etc/localtime都是UTC,但date輸出的卻是CST時(shí)區(qū),TZ這環(huán)境變量到底是怎么達(dá)成這個(gè)結(jié)果的。在我前面gitlab-ce鏡像中備份任務(wù)中卻使用的是UTC時(shí)間
3.3 只設(shè)置【-v /etc/localtime:/etc/localtime】參數(shù)測(cè)試,或設(shè)置【-v /etc/localtime:/etc/localtime 及 TZ="Asia/Shanghai"】參數(shù)測(cè)試(結(jié)果是一樣的)
結(jié)果:
date? ? ? ? ? ? ? ? ? :CST
cat /etc/timezone? ? :UTC
cat /etc/localtime? ? :CST
/etc/localtime軟鏈接? :為UTC,實(shí)際生效的是`-v`掛載的這個(gè),即CST
過(guò)程:
[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
一切都在意料之中,正與我在前面【我在gitlab中遇到的問(wèn)題與解決方法】一節(jié)中講到的一樣,在date與計(jì)劃任務(wù)中都能達(dá)成想要的結(jié)果
3.4 沖突測(cè)試:設(shè)置【TZ="Asia/Phnom_Penh"】(東7區(qū)),設(shè)置【-v /etc/localtime:/etc/localtime】(東8區(qū))
結(jié)果:
date? ? ? ? ? ? ? ? ? :+07
cat /etc/timezone? ? :UTC
cat /etc/localtime? ? :CST(+08)
/etc/localtime軟鏈接? :UTC
過(guò)程:
[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
看到?jīng)],兩個(gè)相互沖突的設(shè)置,最終date命令取得是TZ變量的設(shè)置,下節(jié)我們來(lái)測(cè)試下這個(gè)變量
3.5 測(cè)試變量【TZ】
測(cè)試環(huán)境為我的筆記本電腦(避開容器環(huán)境),結(jié)果如下:
kevin@TM1701-b38cbc23:~$ cat? /etc/timezone? ? ? #--- /etc/timezone 東8區(qū)
Asia/Shanghai
kevin@TM1701-b38cbc23:~$
kevin@TM1701-b38cbc23:~$ cat /etc/localtime? ? ? #--- /etc/localtime 東8區(qū)
TZif2
? ? ??????y??Y^?? ?p??????|@?;>??{??B???E"?L???<??fp???A|??R i?? ~??!I}?"g? #)_?$G? %|&'e &?^(G (?@q?~?pLMTCDTCSTTZif2
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ????~6C)?????????????y??????Y^?????? ?p??????????????????|@?????;>??????{??????B???????E"?????L???????<??????fp???????????A|??R i?? ~??!I}?"g? #)_?$G? %|&'e &?^(G (?@q?~?pLMTCDTCST
CST-8
kevin@TM1701-b38cbc23:~$
kevin@TM1701-b38cbc23:~$.
kevin@TM1701-b38cbc23:~$ export | grep TZ? #--- 可以看出,原始安裝不存在TZ變量,時(shí)間顯示為東8區(qū)
kevin@TM1701-b38cbc23:~$ echo $TZ? ? ? ? ?
kevin@TM1701-b38cbc23:~$ date
2023年 03月 28日 星期二 09:06:22 CST
kevin@TM1701-b38cbc23:~$.
kevin@TM1701-b38cbc23:~$.
kevin@TM1701-b38cbc23:~$ export TZ="Asia/Phnom_Penh"? ? #--- TZ設(shè)置為東7區(qū),時(shí)間顯示為東7區(qū)
kevin@TM1701-b38cbc23:~$ date
2023年 03月 28日 星期二 08:09:01 +07
kevin@TM1701-b38cbc23:~$.
kevin@TM1701-b38cbc23:~$.
kevin@TM1701-b38cbc23:~$ export TZ=? ? ? ? #--- 置空TZ變量,時(shí)間顯示為UTC時(shí)間
kevin@TM1701-b38cbc23:~$ date
2023年 03月 28日 星期二 01:09:25 UTC
kevin@TM1701-b38cbc23:~$.
kevin@TM1701-b38cbc23:~$.
kevin@TM1701-b38cbc23:~$ unset TZ? ? ? ? ? #--- 刪除TZ變量,時(shí)間顯示為東8區(qū)
kevin@TM1701-b38cbc23:~$ date
2023年 03月 28日 星期二 09:09:36 CST
4 一般用法
制作鏡像:
FROM ubuntu:bionic
ARG TZF="Asia/Shanghai"
ENV TZ=${TZF}
RUN apt update
? ? && apt install -y tzdata
? ? && ln -sf /usr/share/zoneinfo/${TZF} /etc/localtime
? ? && echo ${TZF} > /etc/timezone
在運(yùn)行了ln -sf /usr/share/zoneinfo/${TZF} /etc/localtime之后,可以運(yùn)行dpkg-reconfigure -f noninteractive tzdata自動(dòng)創(chuàng)建修改/etc/timezone
構(gòu)建:
dockerbuild? --build-argTZF="Asia/Phnom_Penh"-t new-ubuntu? ./
運(yùn)行:
docker run -it? --env TZ="Asia/Phnom_Penh"? new-ubuntu? bash? ? ? ? #--- date命令生效
docker run -it? -v /etc/localtime:/etc/localtime? -v /etc/timezone:/etc/timezone? new-ubuntu? bash? #--- 全部生效,此時(shí)變量TZ必須是unset的
docker run -it? --env TZ="Asia/Phnom_Penh"? -v /etc/localtime:/etc/localtime? -v /etc/timezone:/etc/timezone? new-ubuntu? bash? #--- 也是全部生效
TZF與``TZ只是為了演示他們生效的范圍,一般用相同的就好,比如TZ`;
ARG參數(shù)只在構(gòu)建時(shí)有效,可以在構(gòu)建時(shí)從外部傳入;
ENV參數(shù)在構(gòu)建與運(yùn)行時(shí)都有效,但只能在運(yùn)行時(shí)傳入;
TZ是內(nèi)部變量,可以不存在,如果設(shè)置了,則date命令會(huì)使用他的設(shè)置;
5 最后
猜測(cè):交互程序一般會(huì)使用date的結(jié)果,但計(jì)劃任務(wù)之類的程序可能會(huì)使用/etc/localtime的設(shè)置(/etc/localtime可能屬于系統(tǒng)級(jí)的)