天天看點

linux時間路徑,linux中的時區問題到底怎麼處理

背景

這兩天在打docker的時候,發現自己的容器啟動之後,裡面date -R的輸出時區是UTC,總是和中原標準時間差了8個小時。

linux時間路徑,linux中的時區問題到底怎麼處理

标準鏡像

linux時間路徑,linux中的時區問題到底怎麼處理

時區是UTC

檢視/etc/localtime,發現預設指向的是Etc/UTC時區。而且TZ環境變量也沒有被設定。

linux時間路徑,linux中的時區問題到底怎麼處理

linux中的時區問題到底是怎麼處理的

實際上,我們所有關于時區處理的問題都是glibc中處理時區的問題。 這個問題最權威的文檔就是glibc的官方文檔,裡面關于TZ環境變量的描述介紹了時區問題的處理。

https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html#TZ-Variable

其中和我們相關的部分如下。

linux時間路徑,linux中的時區問題到底怎麼處理

核心意思如下: 在glibc中,TZ環境變量的值是一個檔案的名字,這個檔案的内容描述了時區相關的資訊。

如果TZ這個環境變量沒有設定,那麼系統會選擇一個預設值,在glibc中,其預設值為/etc/localtime. 如果TZ環境變量有值,并且這個值是以/開頭的,那麼是一個絕對路徑的檔案名,否則檔案名為/usr/share/zoneinfo/$TZ. /usr/share/zoneinfo目錄下面有世界各地的本地時間資訊,比如Asia/Shanghai.一般這個目錄下面的檔案是被tzdata這個包安裝的。

按照這個思路,我們強制指定TZ環境變量為Asia/Shanghai,時區正确

linux時間路徑,linux中的時區問題到底怎麼處理

強制修改/etc/localtime檔案,時區也正确。

linux時間路徑,linux中的時區問題到底怎麼處理

docker容器處理時區的方法

根據上面的描述,在docker容器中設定時區其實有兩個主要的方法。 一個是直接進行TZ環境變量設定,另一個是不設定TZ環境變量,直接修改/etc/localtime的内容(通過軟連結或者檔案直接複制都可以)

這裡以設定TZ環境變量為例(我自己比較喜歡這樣做,感覺比修改/etc/localtime更友善)。

首先,我們可以在Dockerfile裡面添加ENV TZ=Asia/Shanghai,這樣docker build出來的鏡像預設TZ環境變量就是我們要的值了。

linux時間路徑,linux中的時區問題到底怎麼處理

其次,我們也可以在容器拉起的時候使用-e TZ=Asia/Shanghai進行TZ環境變量設定,這個設定就是動态的,同一個鏡像我們可以在拉起的時候設定不同的值。

linux時間路徑,linux中的時區問題到底怎麼處理

總結

docker中的時區處理實際上就是glibc中的時區處理,了解了glibc中對事情的處理方法,核心是TZ環境變量和/etc/localtime檔案,docker中的時期問題處理就簡單了.