docker內時間與北京時間相差8小時解決
2024-01-22 18:32 youxin 閱讀(2917) 評論(0) 收藏 舉報/etc/localtime是用來描述本機時間
/etc/timezone是用來描述本機所屬的時區
在linux中,有一些程序會自己計算時間,不會直接采用帶有時區的本機時間格式,會根據UTC時間和本機所屬的時區等計算出當前的時間。
比如jdk應用,時區為“Etc/UTC”,本機時間改為北京時間,通過java代碼中new 出來的時間還是utc時間,所以必須得修正本機的時區。
在使用docker容器查看日志的過程中,發現容器內的時間與實際時間晚了8小時,其實那個是UTC時間(標準時間),而我們所處的是CST時間(東八區時間)
總結,最佳做法:
創建容器查看日志
啟動一個容器
|
1
|
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql3306 mysql:5.7 |
查看日志
|
1
|
docker logs mysql3306 |
可以看到日志比系統時候少8小時
一,進入容器內修改(已經實踐過的)
(1)更改容器時間
也就是操作的文件夾是容器內的文件夾,不再是宿主機的
首先是從宿主機進入容器,輸入以下命令(containerID就是我們在宿主機通過docker ps -a獲取到的容器id值):
docker exec -it containerID /bin/bash
進入容器后,我們ls即可看到已經進入容器內部,容器內部的文件目錄和我們的linux目錄是一樣的(退出容器是exit),我們輸入以下命令進行修改:
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
我們此使輸入date即可查看到時區已經進行了更改,即便是重啟也會保存此次更改
(2)更改java相關程序獲取到的時間
雖然系統時間有改為CST時區,但是java中的new Date()獲取到的時間仍然是UTC時間,這是因為:
LINUX下:jre是從/etc/sysconfig/clock這個文件中獲取時區信息的,修改次文件即可,沒有的話添加一個。
我們使用以下命令在sysconfig目錄添加一個clock文件(如果目錄也不存在,那么目錄也添加上)
touch clock
clock文件創建好了,我發現沒有辦法使用vim去編輯clock文件,可能容器內沒有裝vim,所以我們分別執行下邊兩條命令進行安裝:
apt update
apt install vim
然后編輯clock文件放入以下內容,然后:wq保存退出,
ZONE="Asia/Shanghai"
UTC=false
ARC=false
就可以發現與java相關的系統日志時間已經是CST的了,我操作時間就是14:10
下邊這兩種方法是在網上找的另外兩種,但是如果要是java相關程序獲取到CST時間,仍然要使用上邊(2)做法
二,在宿主機內對容器進行修改
直接執行以下命令,不需要進入容器內
docker cp /etc/localtime [容器ID或者NAME]:/etc/localtime
三,通過dockerfile對容器進行修改
這個方法的好處是不用每次啟動新的容器都要進行修改,上邊兩種方法修改后只能在同一容器中生效,通過更改dockerfile,進行創建新的容器時就已經是修改過的了,我們需要在對應鏡像的dockerfile中添加如下內容:
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
容器生成前(進入dockerfile里面設置)
FROM ${docker.registry.public}/jdk:8u252
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
WORKDIR /
COPY ${project.build.finalName}.jar ${project.artifactId}.jar
ENTRYPOINT ["java","-Duser.timezone=GMT+08", "-jar", "${project.artifactId}.jar"]
上面指定時區TZ,時間-Duser.timezone
-s --symbolic比較容易,有-s時表示創建軟連接,沒有-s時,表示創建硬鏈接
-f --force 強行刪除任何已存在的目標文件
-n --no-dereference 把符號連接的目的目錄視為一般文件
注意alpine不帶 timezone,需要先安裝timezone,看文章下面
jdk讀取linux系統時間步驟:
0. 先找vm參數 : -Duser.timezone=Asia /Shanghai
1.先找“TZ”變量,沒有,到2,
2.讀/etc/timezone,沒有到3,
3.比較/etc/localtime文件與"/usr/share/zoneinfo目錄下所有時區文件,如果有一致的,就為該時區,如果沒有,到4,
4.默認為標準GMT
JVM加載TimeZone讀取文件優先級實戰分析
在dockerfile中加入:
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo 'Asia/Shanghai' >/etc/timezone \
把時間改成東八區就可以了
鏈接:https://www.jianshu.com/p/387959fc2fae
參考:https://blog.csdn.net/Jarbein/article/details/103631718
在Compose中修改時區
在docker-compose.yml文件中
volumes:
- /etc/timezone:/etc/timezone
- /etc/localtime:/etc/localtime
鏈接:https://www.jianshu.com/p/43e5d72b0f63
alpine 是精簡版鏡像,默認不帶 timezone,需要我們處理一下,步驟如下:
1、安裝 timezone 數據包
apk add -U tzdata
ls /usr/share/zoneinfo
為了防止添加失敗,加上-U 參數,更新倉儲緩存。
列出安裝的時區文件,驗證是否下載成功。
2、拷貝需要的時區文件到localtime,國內需要的是Asia/Shanghai:
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
3、驗證時區
date
CST 即為 中國標準時間。
命令合并
apk add -U tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
官方網址
————————————————
原文鏈接:https://blog.csdn.net/catoop/article/details/105199019
mysql時間
其他系統例如 Docker 官方提供的 mysql
https://github.com/docker-library/mysql/tree/master/5.6
可以先進系統看時區,以及是否存在時區的配置文件,存在的情況下,直接修改即可。示例如下:
FROM 10.10.1.243:5000/mysql:5.6.43
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone
原文鏈接:https://blog.csdn.net/isea533/article/details/87261764
如果用docke compose,可以這么設置:
services:
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example
TZ: Asia/Shanghai
-e TZ=Asia/Shanghai
alpine 鏡像時區調為 Asia/Shanghai 后因 TZ 與 apk del tzdata 導致不生效
現象:
設置 TZ 環境變量,并且最后刪除 tzdata,創建出來的鏡像運行時執行 ??date?? 后顯示日期還是 UTC 時間。
FROM alpine AS runtime
ENV TZ Asia/Shanghai
RUN apk add tzdata && cp /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo ${TZ} > /etc/timezone && apk del tzdata
解決方案
不刪除 tzdata
FROM alpine AS runtime
ENV TZ Asia/Shanghai
RUN apk add tzdata && cp /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo ${TZ} > /etc/timezone
不設置 TZ 環境變量
FROM alpine AS runtime
RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo Asia/Shanghai > /etc/timezone && apk del tzdata
用官方腳本設置(suggest)
在? ?alpine 官方文檔??? 可以看到 timezone 是根據 setup-timezone 指定的,而在 alpine 鏡像上可以發現? ?沒有這個命令???,所以可以用 ??alpine-conf?? 安裝。
FROM alpine AS runtime
ENV TZ Asia/Shanghai
RUN apk add alpine-conf && \
/sbin/setup-timezone -z Asia/Shanghai && \
apk del alpine-conf
現在可以看到是 CST 時間了(又熬夜的一天)
# date
Sun Jan 16 04:44:07 CST 2022
推測
推測是 date 在有 TZ 環境變量時會去 /usr/share/zoneinfo/ 目錄下取時區信息,而我們刪掉的 tzdata 就是這個目錄,導致找不到信息就 fallback 到 UTC 時間了。沒有 TZ 時大概就直接從 /etc/timezone 取時區,再從 /etc/localtime 讀時區信息。而 alpine 本身可能沒有 TZ 指定環境變量的機制,像 debian 鏡像就自帶 /usr/share/zoneinfo/,就不會有這個問題。
相關鏈接
? ?https://github.com/gliderlabs/docker-alpine/issues/136?
-----------------------------------
alpine 鏡像時區調為 Asia/Shanghai 后因 TZ 與 apk del tzdata 導致不生效
https://blog.51cto.com/u_15310543/5010044
浙公網安備 33010602011771號