环境:linux centons7 docker
(一)问题出现
查询容器内部时间和宿主机时间相差8小时,时区同步完成时间不对。
查询命令:(不进入容器内部,执行命令)
docker exec -it b6d75a836b9a date 也可以如下写法
docker exec -it b6d75a836b9a bin/bash -c 需要执行的命令( date )
《注》-c docker 命令里面在外部执行命名参数
二(问题出现底层原理)
在构建容器的时候用到(时间、时区)时候有jdk,宿主机,和容器,只要保证3者时间一致即可。
如果不关注基础镜像的底层构建时候的时区,在容器构建时候加网上如下办法只会出现以上图片问题,时区改变了,时间还是差8小时。
三(各个时间段网上解决办法)
1.容器生成后(复制主机的时间文件)
如果本机时区正确:
直接复制
docker cp /etc/localtime 【容器ID或者NAME】:/etc/localtime
如果本机时区不正确:
在容器中创建文件:
mkdir -p /usr/share/zoneinfo/Asia
在宿主机上面执行命令,拷贝时区文件:
docker cp /usr/share/zoneinfo/Asia/Shanghai 容器ID或容器名:/usr/share/zoneinfo/Asia
如果报错 cp: failed to access '/etc/localtime': Too many levels of symbolic links cat /etc/localtime 先rm 再cp
#rm /etc/localtime
再次查询时间:
如果还是不行,则进入容器内部执行:
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2.容器生成后(进入容器内部直接修改时间)
修改时间
以root身份进入容器 docker exec -it -u root 24795ac94ae7 /bin/sh
可以使用date -R 查看时间
sudo date -s MM/DD/YY//修改日期
sudo date -s hh:mm:ss//修改时间
在修改时间以后,修改硬件CMOS的时间
sudo hwclock --systohc//非常重要,如果没有这一步的话,后面时间还是不准
3.容器生成前(进入dockerfile里面设置)
FROM ${docker.registry.public}/jdk:8u252 ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezoneWORKDIR /COPY ${project.build.finalName}.jar ${project.artifactId}.jarENTRYPOINT ["java","-Duser.timezone=GMT+08", "-jar", "${project.artifactId}.jar"]
上面指定时区TZ,时间-Duser.timezone
jdk读取linux系统时间步骤:
1.先找“TZ”变量,没有,到2,
2.读/etc/timezone,没有到3,
3.比较/etc/localtime文件与"/usr/share/zoneinfo目录下所有时区文件,如果有一致的,就为该时区,如果没有,到4,
4.默认为标准GMT
四(作者方法)
因为工作项目当中构建频繁,所以只能在构建前进行修改,在dockerfile里面修改最佳,但当上面方法都失效的时候,就应该关注底层镜像构建时候jdk的时间。
FROM 工作IP:端口8888/jdk:8u252
ENV TZ=Asia/Shanghai
五(思考)
既然时间可以配置为什么我们不用好的插件来管理。
时间同步服务器ntpdate和IANA维护的tzdata都是好的选择,下面推荐2篇centons7 的有关文章。
(1)Centos7服务器时间同步及国内常用时间同步服务器地址 && 自建时间同步服务器ntpdate
http://www.mamicode.com/info-detail-1523743.html
(2)解决Docker容器时区及时间不同步问题的方法
http://www.cppcns.com/jiqiao/fuwuqi/173661.html
还有很多好的方法和一些命令容易遇到的bug希望有时间来和大家分享探讨。