Docker解决容器时间与主机时间不一致的问题

首先要确保服务器有安装docker容器

查看本地是否有否有安装docker容器命令

docker --version
Docker version 24.0.2, build cb74dfc

问题描述

在使用Docker部署应用的过程中,有时会发现容器内的时间和宿主机的时间不一致,导致日志、定时任务等功能出现异常。例如,宿主机的时间是北京时间(CST),而容器内的时间是标准时间(UTC),两者相差8个小时。

问题原因

这个问题的原因是宿主机设置了时区,而Docker容器并没有设置,导致两者使用了不同的时区。

#使用date命令,来查看服务器时间以及容器内时间来查看
[root@ixxxxxxx ~]# date
2023年 05月 30日 星期二 10:21:31 CST
root@bxxxxxx:/# date
Tue May 30 02:21:24 UTC 2023

解决方案

为了使容器时间与主机时间同步,有以下三种解决方案:

  • 方案一:在创建容器的时候指定启动参数,挂载localtime文件到容器内,保证两者所采用的时区是一致的。
  • 方案二:在宿主机上执行命令,将localtime文件到容器内。
  • 方案三:创建自定义的dockerfile文件,设置时区环境变量和软链接。

实验验证

为了验证以上方案是否有效,我分别使用了三种方法来创建一个mysql容器,并查看其时间是否与主机时间一致。

方案一

我使用以下命令来创建一个mysql容器,并挂载localtime文件到容器内:

docker run -p 3306:3306 --name mysql -v /etc/localtime:/etc/localtime -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

然后我进入容器内,使用date命令查看当前时间:

docker exec -it mysql bash
root@xxxxxx:/# date
2023年 05月 30日 星期二 10:21:31 CST

我也在宿主机上查看当前时间:

date
2023年 05月 30日 星期二 10:22:01 CST

可以看到,两者的时间是一致的。

方案二

我使用以下命令来创建一个mysql容器,并不挂载localtime文件到容器内:

docker run -p 3306:3306 --name mysql2 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

然后我进入容器内,使用date命令查看当前时间:

docker exec -it mysql2 bash
root@fxxxxx:/# date
Tue May 30 02:30:24 UTC 2023

我也在宿主机上查看当前时间:

date
2023年 05月 30日 星期二 10:38:31 CST

可以看到,两者的时间是不一致的。

接下来,我在宿主机上执行命令,将localtime文件到容器内:

docker cp /etc/localtime:mysql2/etc/localtime

然后我再次进入容器内,使用date命令查看当前时间:

docker exec -it mysql2 bash
root@fxxxxx:/# date
Tue May 30 10:40:59 CST 2023

可以看到,两者的时间已经同步了。

方案三

我创建了一个自定义的dockerfile文件,内容如下:

FROM mysql:5.7

ENV TimeZone=Asia/Shanghai

RUN /bin/cp /usr/share/zoneinfo/$TimeZone /etc/localtime \
    && echo $TimeZone > /etc/timezone \

然后我使用以下命令来构建一个自定义的mysql镜像,并创建一个mysql容器:

docker build -t mysql-custom .
docker run -p 3306:3306 --name mysql3 -e MYSQL_ROOT_PASSWORD=123456 -d mysql-custom

然后我进入容器内,使用date命令查看当前时间:

docker exec -it mysql3 bash
root@fxxxxx:/# date
Tue May 30 10:58:09 CST 2023

我也在宿主机上查看当前时间:

date
2023年 05月 30日 星期二 10:59:08 CST

可以看到,两者的时间也是一致的。

问题

Error response from daemon: invalid symlink "/etc/localtime" -> "../usr/share/zoneinfo/Asia/Shanghai"

#解决
docker cp /usr/share/zoneinfo/Asia/Shanghai <容器的CONTAINER ID>:/etc/localtime
Successfully copied 2.56kB to bd85c75a3678:/etc/localtime

总结

本文介绍了Docker解决容器时间与主机时间不一致的问题的三种解决方案,并通过实验验证了其有效性。希望本文对你有所帮助。