Docker容器时间与宿主机不一致/宿主机时间不同步校验问题
作者:Leon_start
一、Docker容器时间与宿主机不一致
如果在启动Docker容器的过程中没有单独配置localtime,很可能造成Docker容器时间与主机时间不一致的情况,比如UTC和CST相差8小时,换句话来说就是容器时间与北京时间相差8个小时。
问题描述
问题:容器时间与北京时间相差8个小时
# 查看主机时间 [root@localhost ~]# date 2020年07月27日 星期三 22:42:44 CST # 查看容器时间 # docker exec -it <containerid> /bin/sh root@b43340ecf5ef:/# date Wed Jul 27 14:43:31 UTC 2020
原因:宿主机设置了时区,而Docker容器并没有设置,导致两者相差8小时
- CST应该是指(China Shanghai Time,东八区时间)
- UTC应该是指(Coordinated Universal Time,标准时间)
所以,这2个时间实际上应该相差8个小时
所以,必须统一两者的时区
解决方案
方法一:初始化容器时,容器时间与宿主机同步,docker run 添加时间参数
docker run -itd --privileged=true -v /etc/localtime:/etc/localtime:ro #实例 docker run -itd \ -e MYSQL_ROOT_PASSWORD=123456 \ -v /home/mysql/data:/var/lib/mysql \ -v /home/mysql/log:/var/log/mysql \ -v /home/mysql/etc/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf \ -v /etc/localtime:/etc/localtime:ro \ --name mysql-server \ --network host \ --restart=always \ --privileged=true \ mysql:5.7.37
方法二:Dockerfile解决方案
# 方法1 # 添加时区环境变量,亚洲,上海 ENV TimeZone=Asia/Shanghai # 使用软连接,并且将时区配置覆盖/etc/timezone RUN ln -snf /usr/share/zoneinfo/$TimeZone /etc/localtime && echo $TimeZone > /etc/timezone # 方法2 # CentOS RUN echo "Asia/shanghai" > /etc/timezone # Ubuntu RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
方法三:docker-compose解决方案
#第一种方式(推荐): environment: TZ: Asia/Shanghai #第二种方式: environment: SET_CONTAINER_TIMEZONE=true CONTAINER_TIMEZONE=Asia/Shanghai #第三种方式: volumes: - /etc/timezone:/etc/timezone - /etc/localtime:/etc/localtime
方法四:正在运行的容器,可以宿主机直接执行命令给某个容器同步时间
#方法1 直接在宿主机操作 docker cp /etc/localtime 【容器ID或者NAME】:/etc/localtime docker cp -L /usr/share/zoneinfo/Asia/Shanghai 【容器ID或者NAME】:/etc/localtime #方法2 登录容器同步时区timezone,一般是因为时区不同导致时间差 ln -sf /usr/share/zoneinfo/Asia/Singapore /etc/localtime
在完成后,再通过date命令进行查看当前时间
但是,在容器中运行的程序的时间不一定能更新过来,比如在容器运行的mysql服务,在更新时间后,通过sql查看mysql的时间
select now() from dual;
可以发现,时间并没有更改过来
这时候必须要重启mysql服务或者重启docker容器,mysql才能读取到更改过后的时间
二、宿主机时间不同步
ntp时间服务器——时间同步
具体两种模式:
1、服务器数量比较少,可以直接与时间服务器同步
2、本地服务器较多,在本地自建时间同步服务器
时间同步的两个命令:
ntpd
:校准时间,一点点的校准过来时间的,最终把时间慢慢的校正对。ntpd服务可以在修正时间的同时,修正cpu tick。ntpd有一个自我保护设置: 如果本机与上源时间相差太大, ntpd不运行ntpdate
:不会考虑其他程序是否会阵痛,直接调整时间,有可能会对程序造成影响
ntpdate [-nv] [ IP/hostname] # ntpdate -u 192.168.0.2 # ntpdate -u time.ntp.org # ntpdate -u ntp.sjtu.edu.cn >>/var/log/ntp.log 2>&1;hwclock -w
注释:-u:指定使用无特权的端口发送数据包,可以越过防火墙与主机同步,这个参数可用可不用,看你自己
理想的做法是:
使用ntpd来校准时钟,而不是调整计算机时钟上的时间。
在计算机刚刚启动,但还没有启动很多服务的那个时候可以使用ntpdate同步时间
直接用命令与时间服务器进行同步
实例:使用ntpdate 进行同步:
ntpdate -u x.x.x.x #这里的x.x.x.x可以是公网时间服务器IP地址,也可以是下面两种我们自建的ntp服务器地址
#公网时间服务器IP地址 #阿里云时间服务器 http://time1.aliyun.com http://time2.aliyun.com http://time3.aliyun.com http://time4.aliyun.com http://time5.aliyun.com http://time6.aliyun.com http://time7.aliyun.com time.pool.aliyun.com #centos也有几个时间服务器(最好还是用国内的吧) 0.centos.pool.ntp.org 1.centos.pool.ntp.org 2.centos.pool.ntp.org
可以加一个定时计划,定时同步
注释:在有时间同步服务器的情况下,直接使用该命令就可以让宿主机实现时间同步
crontab -e */1 * * * * /usr/sbin/ntpdate -u x.x.x.x > /dev/null 2&1
自建ntpd 时间同步服务器
NTP通信协议原理: 首先主机启动NTP。 客户端会向NTP服务器发送调整时间的message。 然后NTP server会送出当前的标准时间给client client接受来自server的时间后,会根据这个信息来调整自己的时间。这样就实现了网络对时。 #NTP这个deamon采用了UDP 123端口 远程服务器的层级(stratum): 由于NTP是层型结构,有顶端的服务器,多层的Relay Server再到客户端. 所以服务器从高到低级别可以设定为1-16. 为了减缓负荷和网络堵塞,原则上应该避免直接连接到级别为1的服务器的
1、配置ntp服务器
1)安装
# yum -y install ntp
2)开机自启动
# systemctl start ntpd # systemctl enable ntpd
3)修改配置文件:(详解)
[root@localhost ~]# less /etc/ntp.conf # For more information about this file, see the man pages # ntp.conf(5), ntp_acc(5), ntp_auth(5), ntp_clock(5), ntp_misc(5), ntp_mon(5). driftfile /var/lib/ntp/drift #系统时间与BIOS事件的偏差记录 配置与本机同步的机器权限↓ # Permit time synchronization with our time source, but do not # permit the source to query or modify the service on this system. restrict default kod nomodify notrap nopeer noquery restrict -6 default kod nomodify notrap nopeer noquery
默认拒绝任何操作,任何ip4地址、ip6地址 不能修改、不能trap远程登录、不能尝试对等、不能校对时间,
restrict 控制相关权限。
语法为: restrict [ 客户端IP ] mask [ IP掩码 ] [参数]
其中IP地址也可以是default ,default 就是指所有的IP
参数有以下几个:
nomodify
:客户端不能更改服务端的时间参数,但是客户端可以通过服务端进行网络校时。notrust
:拒绝没有认证用户端noquery
:客户端不能使用ntpq,ntpc来查询ntp服务器,等于不提供校对时间服务notrap
:不提供trap远程登录功能,trap服务是一种远程时间日志服务 拒绝为匹配的主机提供模式 6 控制消息陷阱服务。陷阱服务是 ntpdq 控制消息协议的子系统,用于远程事件日志记录程序。nopeer
:用于阻止主机尝试与服务器对等kod
: 访问违规时发送 KoD 包,向不安全的访问者发送Kiss-Of-Death报文。 restrict -6 表示IPV6地址的权限设置。
如何控制客户的范围 # Permit all access over the loopback interface. This could #下面的配置 允许运行任何权限的访问在本地接口, # be tightened as well, but to do so would effect some of #这里最好收紧权限,但是会影响一些管理功能 # the administrative functions. restrict 127.0.0.1 restrict ::1 # Hosts on local network are less restricted. #配置 给本地局域网络配置小一些的权限 #restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap 本机与公共时间服务器同步选项 设定NTP主机来源(其中prefer表示优先主机) # Use public servers from the pool.ntp.org project. 使用公共服务器从 时间池工程中 # Please consider joining the pool (http://www.pool.ntp.org/join.html). 请考虑加入这个 时间池 项目 server 0.centos.pool.ntp.org iburst server 1.centos.pool.ntp.org iburst server 2.centos.pool.ntp.org iburst server 3.centos.pool.ntp.org iburst
server host [ key n ] [ version n ] [ prefer ] [ mode n ] [ minpoll n ] [ maxpoll n ] [ iburst ] 其中host是上层NTP服务器的IP地址或域名,随后所跟的参数解释如下所示: ◆ key: 表示所有发往服务器的报文包含有秘钥加密的认证信息,n是32位的整数,表示秘钥号。 ◆ version: 表示发往上层服务器的报文使用的版本号,n默认是3,可以是1或者2。 ◆ prefer: 优先使用。 ◆ mode: 指定数据报文mode字段的值。 ◆ minpoll: 指定与查询该服务器的最小时间间隔为2的n次方秒,n默认为6,范围为4-14。 ◆ maxpoll: 指定与查询该服务器的最大时间间隔为2的n次方秒,n默认为10,范围为4-14。 ◆ iburst: 当初始同步请求时,采用突发方式接连发送8个报文,时间间隔为2秒。
#broadcast 192.168.1.255 autokey # broadcast server #broadcastclient # broadcast client #broadcast 224.0.1.1 autokey # multicast server #multicastclient 224.0.1.1 # multicast client #manycastserver 239.255.254.254 # manycast server #manycastclient 239.255.254.254 autokey # manycast client 当外部时间不可用时,以本地(本机)时间作为服务时间,本地时间以 127.127.1.0 表示 级别为10 # Undisciplined Local Clock. This is a fake driver intended for backup # and when no outside source of synchronized time is available. #server 127.127.1.0 # local clock #fudge 127.127.1.0 stratum 10 下面是一些加密认证的配置 # Enable public key cryptography. #crypto includefile /etc/ntp/crypto/pw # Key file containing the keys and key identifiers used when operating # with symmetric key cryptography. keys /etc/ntp/keys # Specify the key identifiers which are trusted. #trustedkey 4 8 42 # Specify the key identifier to use with the ntpdc utility. #requestkey 8 # Specify the key identifier to use with the ntpq utility. #controlkey 8 # Enable writing of statistics records. #statistics clockstats cryptostats loopstats peerstats
一个简单实例如下:
restrict default kod nomodify notrap nopeer noquery #拒绝所有ip4 的请求 # restrict -6 default kod nomodify notrap nopeer noquery #针对ipv6设置 # 允许本地所有操作 restrict 127.0.0.1 #restrict -6 ::1 # 允许的局域网络段或单独ip 某些权限 restrict 10.0.0.0 mask 255.0.0.0 nomodify motrap restrict 192.168.0.0 mask 255.255.255.0 nomodify motrap restrict 192.168.1.123 mask 255.255.255.255 nomodify motrap # 使用上层的internet ntp服务器 restrict cn.pool.ntp.org restrict 1.cn.poo.ntp.org restrict 0.asia.pool.ntp.org restrict 3.asia.pool.ntp.org server cn.pool.ntp.org prefer server 1.cn.poo.ntp.org server 0.asia.pool.ntp.org server 3.asia.pool.ntp.org # 如果无法与上层ntp server通信以本地时间为标准时间 server 127.127.1.0 # local clock fudge 127.127.1.0 stratum 10 driftfile /var/lib/ntp/drift # 计算本ntp server 与上层ntpserver的频率误差 # Key file containing the keys and key identifiers used when operating # with symmetric key cryptography. keys /etc/ntp/keys logfile /var/log/ntp.log #日志文件
配置/etc/sysconfig/ntpd文件
ntp服务,默认只会同步系统时间。如果想要让ntp同时同步硬件时间,可以设置/etc/sysconfig/ntpd文件,在/etc/sysconfig/ntpd文件中,添加 SYNC_HWCLOCK=yes 这样,就可以让硬件时间与系统时间一起同步。
# 允许BIOS与系统时间同步,也可以通过hwclock -w 命令
# vim /etc/sysconfig/ntpd # 添加 SYNC_HWCLOCK=yes
4)启动ntpd 服务
# systemctl start ntpd
查看ntp的端口,可以看到123端口
# netstat -unlnp
查看ntp服务器有无和上层连通
# ntpstat synchronised to NTP server (84.16.73.33) at stratum 2 time correct to within 184 ms polling server every 128 s
刚启动的时候,一般是:
# ntpstat unsynchronised time server re-starting polling server every 64 s
ntptrace -n 127.0.0.1 127.0.0.1: stratum 3, offset -0.001095, synch distance 0.532610 116.193.83.174: timed out, nothing received
查看ntp服务器与上层ntp服务器的状态:ntpq
# ntpq -p # 其中: # remote - 本机和上层ntp的ip或主机名,“+”有连线可做候选,“*”正在使用的 # refid - 更上一层的ntp地址 # st - stratum的 级别 # when - 多少秒前曾经同步过时间 # poll - 下次更新在多少秒后 # reach - 已经向上层ntp服务器要求更新的次数 # delay - 网络延迟 # offset - 时间补偿 # jitter - 系统时间与bios时间差 # ntpq -p remote refid st t when poll reach delay offset jitter ============================================================================== *time4.aliyun.co 10.137.38.86 2 u 111 128 377 27.480 -5.995 1.852
2、配置NTP客户端
在所有客户端上vim /etc/ntp.conf,添加:
server x.x.x.x #x.x.x.x 为上面配置的ntp服务器地址
注意:当server与client之间的时间误差过大时(可能是1000秒),处于对修改时间可能对系统和应用带来不可预知的问题,NTP将停止时间同步!
所以如果发现NTP启动之后时间并不进行同步时,应该考虑到可能是时间差过大引起的,此时需要先手动进行时间同步 ntpdate !
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。