美文网首页
使用dokcer镜像快速搭建ntp服务器实现时间同步

使用dokcer镜像快速搭建ntp服务器实现时间同步

作者: 越大大雨天 | 来源:发表于2022-12-07 16:51 被阅读0次

    使用镜像搭建ntp服务器,并在客户端调用进行定时时间同步。

    一、 ntp服务器搭建

    查询到有现成的ntp服务器docker镜像, 并配有完整使用方法,参考链接如下:

    docker run启动容器,国内时间源可以通过环境变量指定:

    docker run --name=ntp --restart=always --detach --publish=123:123/udp --env=NTP_SERVERS="ntp.ntsc.ac.cn,ntp1.aliyun.com" cturra/ntp
    
    • 可通过docker exec ntp chronyc tracking查看ntp服务器状态:
    Reference ID    : 78197314 (120.25.115.20)
    Stratum         : 3
    Ref time (UTC)  : Thu Dec 08 08:07:08 2022
    System time     : 0.000000000 seconds fast of NTP time
    Last offset     : -0.107805088 seconds
    RMS offset      : 0.107805088 seconds
    Frequency       : 0.000 ppm slow
    Residual freq   : -188.944 ppm
    Skew            : 1000000.000 ppm
    Root delay      : 0.045836508 seconds
    Root dispersion : 7.620638371 seconds
    Update interval : 2.1 seconds
    Leap status     : Normal
    
    
    • 通过docker exec ntp chronyc sources查看ntp源状态
    MS Name/IP address         Stratum Poll Reach LastRx Last sample
    ===============================================================================
    ^? 114.118.7.163                 2   6     1    53   -105ms[ -105ms] +/-  103ms
    ^* 120.25.115.20                 2   6    33   116   -111ms[ -111ms] +/-   24ms
    
    

    二、 客户端使用ntp服务器进行时间同步

    • 服务端安装ntpdate: sudo apt install ntpdate
    • 测试是否能根据ntp服务器更新,例如ntpdate -d <ntp server>
    • 时间同步:ntpdate {ntp_server}

    三、 Python配置定时ntp同步任务

    使用python-crontab库控制linux crontab定时任务,实现ntp同步任务配置

    • 安装python-crontabpip install python-crontab
    • 示例代码如下:
    import datetime
    import os
    import re
    
    from crontab import CronTab
    
    
    NTP_JOB_NAME = "ntpdate"
    
    # crontab任务处理类
    class LinuxCrontab:
        def __init__(self, user=True):
            self.cron = CronTab(user=user)
    
        def set_interval_job(self, command, comment="", cron_str=None, minute=None):
            job = self.cron.new(command=command, comment=comment)
            if cron_str:
                job.setall(cron_str)
            elif minute:
                job.minute.every(minute)
            self.cron.write()
    
        def find_job_by_comment(self, comment):
            comment_abs_compile = re.compile(f"^{comment}$")
            jobs = list(self.cron.find_comment(comment_abs_compile))
            return jobs[0] if jobs else None
    
        def remove_job_by_comment(self, comment):
            job = self.find_job_by_comment(comment)
            if job:
                result = self.cron.remove(job)
                self.cron.write()
                return result
            return 0
    
    # 设置ntp同步任务,或者直接设置系统时间
    def set_server_time(time_str: str = None, ntp_config: dict = None):
        """linux服务器设置时间
            time_str: 若参数存在,则指定时间字符串,强制指定时间为系统时间
            ntp_config: 若参数存在,则解析指定ntp服务器定时同步时间
        """
        cron_handler = LinuxCrontab()
    
        if ntp_config:
            ntp_server = ntp_config.get('host')
            interval_minute = ntp_config.get("interval_minute")
            ntpdate_cmd = f"/usr/sbin/ntpdate {ntp_server} >> /var/log/ti/system_ntp.log 2>&1"
            cron_handler.remove_job_by_comment(NTP_JOB_NAME)
            cron_handler.set_interval_job(command=ntpdate_cmd, comment=NTP_JOB_NAME, minute=interval_minute)
            print("设置ntp定时任务")
        else:
            # cmd = f'date -s "{real_time}";hwclock -w'   # 设置时间并写入bios
            cmd = f'date -s "{time_str}"'   # 设置时间
            result = os.popen(cmd)
            # 删除定时任务
            cron_handler.remove_job_by_comment(NTP_JOB_NAME)
            print(result)
        return True
    
    # 获取ntp同步任务配置或者当前系统时间
    ef get_server_time_conf():
        cron_handler = LinuxCrontab()
        job = cron_handler.find_job_by_comment(comment=NTP_JOB_NAME)
        if job:
            command = job.command
            minute_cron = str(job.minute)  # "*/2"
            if minute_cron == "*":
                minute = 1
            else:
                minute = int(minute_cron.split("/")[1])
            return {
                "user_ntp": True,
                "ntp_config": {
                    "host": command.split(" ")[1],
                    "port": 123,
                    "interval_minute": minute
                },
                "local_time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            }
        else:
            return {
                "user_ntp": False,
                "ntp_config": {},
                "local_time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            }
    
    # 测试ntp服务器连接
    def test_ntp_server(ntp_server):
        ntpdate_test_cmd = f"/usr/sbin/ntpdate -d {ntp_server}"
        exe_result = os.popen(ntpdate_test_cmd).read()
        ok, exe_info = False, "\n".join([line.strip() for line in exe_result.splitlines()])
        if re.search(r"adjust time server .*? offset", exe_result):
            ok = True
        return ok, exe_info
    
    
    if __name__ == '__main__':
        ntp_config = {"host": "ntp.ntsc.ac.cn", "interval_minute": 3}
        set_server_time(ntp_config=ntp_config)
        result = get_server_time_conf()
        print(result)
    

    相关文章

      网友评论

          本文标题:使用dokcer镜像快速搭建ntp服务器实现时间同步

          本文链接:https://www.haomeiwen.com/subject/cvbnfdtx.html