ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

无外网环境搭建内网时间源:Chrony离线部署与配置全指南

无外网环境搭建内网时间源:Chrony离线部署与配置全指南 最近帮一家200人规模的企业做内网整理时遇到了一个典型的“无安装包”场景公司防火墙策略把服务器到公网的通道卡得很死软件源完全不可用但整个办公网的时钟同步问题已经不能再拖了——AD域控里Kerberos时间差告警刷了一屏监控回放和考勤记录对不上几台服务器各自漂移最离谱的一台已经慢了快四十分钟。在这个前提下我把Chrony时钟同步这套配置从离线取包、装包、配置到全网验证完整走了一遍最后用一台低配虚拟机构建了内网时间源把全网时间偏差稳定收敛到毫秒级。这篇文章就把这套方案的每个关键环节拆开来讲为什么选Chrony而不是老牌ntpd无安装包环境下安装包到底从哪里来chrony.conf里每行参数在定义什么以及实际部署里那些不跑一遍根本发现不了的坑。内容适合正在做中小型办公网络改造、被“没网、没包、时间乱”困扰的运维同行参考也适合刚接触时间同步、想搞清楚原理再动手的新人。1. 200人企业为什么必须把时钟同步当成基础设施先把这个容易被低估的问题说透200人规模的办公网看起来不大但对时间同步的依赖一点不比大厂少。而且正因为规模小往往没人认真管问题反而更隐蔽。1.1 时间不同步到底会坏什么事先说域环境。只要是Windows域环境客户端和域控之间的时间偏差一旦超过默认的Kerberos时钟偏移阈值通常5分钟就会报KDC认证失败用户明明密码没错却登不进域内电脑。更微妙的是即便没触发硬性阈值几百毫秒级别的偏差也会让Kerberos票据的有效期计算偏离出现各种偶发的“间歇性认证失败”。我见过最典型的案例就是一家公司一两百台机器里总有零星几台隔一段时间就登不进域IT排查了很久最后发现是这些机器时间漂了大家才想起来NTP这回事。再看运维基础设施。日志审计和故障排查高度依赖统一时间戳安全事件发生时如果防火墙日志、服务器日志、终端日志各差几分钟还原攻击路径基本靠猜。备份系统如果时间不一致计划窗口可能和业务高峰期撞在一起。定时任务依赖系统时间触发时间错了凌晨的批处理可能提前或滞后连锁影响数据同步。监控系统也一样——监控端和被监控主机的时差一旦超过阈值报警判定就会错位该告的不告、不该告的乱告。终端侧容易被忽略的是门禁、考勤、监控这些IoT设备。很多考勤机没有NTP客户端只有简单时钟需要定期人工校准监控录像如果和门禁记录时间对不上事后查证基本没法用。这类型设备通常不算“IT资产”恰恰是出了事最麻烦、也最容易被指责的地方。1.2 200人规模的特殊性不上不下的档位大型企业有条件做独立的时间源集群甚至采购北斗/GPS授时设备几十人的小公司可能靠路由器或者某台常开的电脑凑合。200人的办公网正好卡在中间——时间同步已经成了刚需但又不能把这件事做成一个需要专门团队运维的大项目。我的经验是这个规模做到“一台到两台低配虚拟机做时间源全网统一指向”就够了重点不在规模而在收敛速度和稳定性。所以下面所有设计都围绕一个原则用最小代价把全网时间偏差稳定收进几十毫秒以内。这也是我常说的一句话200人企业做网络部署设备的配置方案一定要为“可维护”服务而不是为“看起来很高级”服务。1.3 为什么选Chrony而不是老NTP传统的时间同步工具是ntpd/ntpdate但放到今天的场景里我优先用Chrony理由比较实在Chrony是RHEL/CentOS 7开始内置的默认NTP实现也是Ubuntu 18.04之后的默认方案系统层面支持最充分比ntpd轻量收敛速度明显更快尤其适合虚拟机、容器这类漂移率不稳定的环境时钟调整策略更灵活既能快速同步也能在业务敏感的服务器上做平滑渐变而非突然跳变chronyc这个命令行工具的设计比ntpq直观看状态、手动触发调整都更顺手。换句话说选Chrony不是因为它“新”而是因为它能解决老NTP在虚拟化和现代工作负载里表现不佳的问题。哪怕在无安装包的环境里需要多花点心思把包找到也值得。2. 没有外网也没有安装包Chrony从哪来这一节是不少同行卡住的地方。系统里没有可用的yum/apt源也没有现成的安装包怎么把Chrony装上去我梳理了四条可行路径按推荐程度排序。2.1 最优先从系统安装ISO里找一个容易忽略的事实主流Linux发行版的安装ISO里本来就带chrony的rpm包。服务器装系统用的还是当初那版ISO的话这就是最可靠的离线包来源版本和系统完全匹配依赖处理起来也最简单。操作流程如下以RHEL/CentOS系为例mkdir -p /mnt/iso mount -o loop /data/iso/CentOS-7-x86_64-Minimal-2009.iso /mnt/iso find /mnt/iso -iname chrony*.rpm找到rpm后复制出来直接安装rpm -ivh chrony-*.rpm如果提示依赖缺失常见的有libedit、libcap这类基础库同样在ISO的Packages目录里找对应rpm一起装。注意有些发行版ISO内部会区分BaseOS和AppStream等仓库目录比如RHEL 8/9chrony可能放在AppStream里依赖在BaseOS里两个目录都要翻。一个关键原则版本必须匹配系统大版本。el7的chrony包不能装到el8机器上反之也不行。判断系统版本用cat /etc/os-release对照着找同一大版本的ISO。如果手头没有现成的ISO从公司软件档案库或者之前装机的归档里调一份出来就行——这本身就是“无安装包”场景下最该有的企业级习惯。2.2 备选在可联网的同版本机器上拉包如果手边有一台能联网、且发行版版本与离线目标机一致的机器用yumdownloader可以把chrony及其全部依赖一次拉下来再拷贝进去。这个方法在中央仓库里没有所需包时很实用。联网机器上执行yum install -y yum-utils mkdir -p /tmp/chrony_pkgs yumdownloader --resolve --destdir/tmp/chrony_pkgs chrony--resolve参数会把需要的依赖一起下载省去手动逐个找依赖的麻烦。之后打包tar czf /tmp/chrony_pkgs.tar.gz /tmp/chrony_pkgs把压缩包传到内网机器解压后rpm -ivh *.rpm重复的rpm不会重复安装缺依赖会直接报错按报错名继续找即可。有一点必须提醒拉包用的联网机器在拉完包后建议立即把临时repo配置撤掉不要留着一条通向外网的yum源避免安全风险。如果公司安全要求严格最好在一个独立的一次性容器或快照环境里执行不要碰生产环境。2.3 Debian/Ubuntu系的deb包获取Debian/Ubuntu环境的离线安装逻辑类似但稍有差异。在联网机器上可以这样做apt-get update mkdir -p /tmp/chrony_debs cd /tmp/chrony_debs apt-get download chrony依赖获取比rpm繁琐一些更实用的方法是直接在一台联网机器上执行apt-get install -y --download-only chrony ls /var/cache/apt/archives/*.deb把deb拷贝进离线机器后dpkg -i chrony*.deb依赖确实缺失时从系统ISO镜像的pool目录里找对应deb路径一般是pool/main/下面按字母排序的目录。2.4 源码编译能不用就别用理论上也可以拿chrony源码包到目标机器上编译安装但我不推荐原因不是技术难度而是后续维护成本。源码编译需要工具链和一堆库编译出来的版本没有进入系统的软件包管理数据库以后升级、卸载、查依赖都是灾难systemd服务文件和/var/lib/chrony目录权限还得自己手工处理。除非目标机器架构特殊、实在找不到任何现成包否则优先走前面三条路。下表把四种方式做个横向对比方便按自己场景选择获取方式适用场景依赖处理推荐度系统安装ISO内的rpm手头有和目标机版本匹配的系统镜像依赖也大多在ISO里较容易最推荐联网同版本机器 yumdownloader有一台可临时联网的同版本机器--resolve自动带全依赖很推荐apt download / 缓存目录Debian/Ubuntu系列依赖从pool或apt缓存找常用源码编译架构特殊无任何现成包手工处理最折腾不推荐3. chrony.conf逐行拆解每一行参数都是在定义“怎么对表”安装好之后真正决定时间同步成败的是配置。我这里把chrony.conf里和企业场景最相关的几个参数逐行讲清楚不光是给配置更重要的是说明为什么要这么配。3.1 server与pool上游源怎么选、怎么写配置NTP源的基本语法是server ntp.aliyun.com iburst server ntp.tencent.com iburst如果上游域名背后有多台服务器也可以用poolpool ntp.aliyun.com iburst企业内网实践里server和pool的差别不大关键点是服务端向外网同步时至少写2~3个上游源单点源不可靠客户端向内网自建源同步时直接写IP别写域名——离线内网DNS经常不完整域名解析失败就等于没有源iburst一定要加。它让首次同步时连续发送8个NTP包几秒钟内就能完成初步对齐不带iburst时首次同步可能要几十秒甚至几分钟。minpoll和maxpoll控制轮询间隔默认minpoll 664秒、maxpoll 10约1024秒即17分钟。对200人企业来说这个节奏足够了不建议把maxpoll增大去追求“省流量”——内网带宽根本不缺这点NTP报文反而会拖慢发现源异常的速度。3.2 driftfile和makestep两个容易被忽略的“时钟性格”参数driftfile记录本机时钟的频率漂移值driftfile /var/lib/chrony/drift作用在于服务器重启后chrony可以带着之前的漂移数据直接启动不用再从零学习一遍本地时钟的“体质”收敛速度快很多。前提是/var/lib/chrony目录对chrony用户可写——这一点在排错部分还会再提。makestep是最值得理解透彻的参数。它决定当本机时间和源偏差较大时是“大步跳一下”step还是“慢慢调过去”slewmakestep 1 3含义是在前3次时钟更新中只要偏差超过1秒就允许直接大步跳表超过3次之后偏差即使超过阈值也只会用slew渐变的方式慢慢修正。为什么默认要限制次数因为大步跳表对运行中的业务有影响——数据库事务的时间戳会突然前移或后退定时任务可能被跳过或重复执行所以生产系统宁可慢慢收敛也不希望频繁跳变。实际部署中常碰到的情况是一台老服务器已经几个月没同步时间偏差几十分钟甚至更大。默认的makestep 1 3里“前3次更新”的机会可能早已耗尽时间就会一直走渐变看起来永远在收敛但收敛速度极慢。这时候两个处理办法chronyc makestep手动触发一次大步调整或者临时把配置改成makestep 1 -1允许无限次大步跳后重启chrony等时间基本对齐再改回默认。这个“先大步拉齐、再渐进微调”的顺序处理存量设备时几乎可以说是标准动作。3.3 local stratum与allow/deny无外网环境靠它撑起权威这是无安装包、无外网场景里最关键的配置local stratum 10意思很直白这台chrony即使同步不到任何上游也对外宣告自己是第10层时间源。stratum是层次标识0是原子钟1是与原子钟直连的服务器数字越大离权威越远15是无效。为什么需要这一行因为纯内网环境下服务端永远联系不到公网NTP源如果不用local客户端请求它时会发现源不可用自然拒绝同步。设成stratum 10是为了给客户端一个“可用但不高傲”的身份用它同步可以但如果有更上游的源客户端会优先选stratum更小的。如果服务端将来打通了外网能正常同步到公网源它会以真实的较低stratum对外服务local并不会覆盖真实层数但我依然建议打通外网后重新审视配置把local去掉或调高避免兜底源意外成为主源。配合网段授权allow 192.168.0.0/16 deny 192.168.113.0/24allow声明允许哪些网段来请求本机时间服务deny在allow之前可以精确排除某个子网。不写allow的网段默认拒绝。企业里我建议再加一行bindaddress 192.168.0.10让chronyd只监听内网IP。多网卡服务器上这行能防止NTP服务意外暴露到管理网或公网——别小看它不少安全扫描发现的问题就是服务监听范围太广。客户端比较简单指向内网源server 192.168.0.10 iburst3.4 一套可以直接抄的配置文件模板服务端内网时间源双网卡或纯内网均可# 上游公网NTP源有外网权限才保留 server ntp.aliyun.com iburst server ntp.tencent.com iburst # 纯离线环境没有上游就用下面这行撑起权威 local stratum 10 # 漂移记录文件 driftfile /var/lib/chrony/drift # 前3次更新中偏差超过1秒允许大步跳 makestep 1 3 # 授权内网网段 allow 192.168.0.0/16 # 只监听内网IP bindaddress 192.168.0.10客户端办公终端/服务器# 指向内网时间源写IP不要写域名 server 192.168.0.10 iburst server 192.168.0.11 iburst # 客户端不需要local stratum driftfile /var/lib/chrony/drift makestep 1 3如果服务端完全没有外网权限就把最上面两个server行注释掉只保留local stratum 10和allow。这样一台权威时间源就算立起来了。4. 从服务端到200台终端的落地上手操作理论说完了这一节是真正动手的过程。我从部署拓扑、服务端操作、客户端配置、批量验证四个环节讲覆盖200人企业网络部署方案最常见的完整链路。4.1 最简部署拓扑一主一备加全网指向200人规模不建议搞复杂的NTP集群。我的推荐是两台低配虚拟机主源2核2G从公网NTP源同步有外网权限时对内提供服务备源配置基本一致local stratum设成11比主源高一层主源不可用时客户端自动切到它。为什么备源stratum要设成11客户端同时面对两个源时会优先选择stratum更小的那一个所以11能让主源优先被选中主源挂掉后10层不可达客户端才会转向11。这个优先级机制不需要额外软件纯靠配置就实现了。能力方面完全不用担心Chrony单机处理NTP请求的能力以每秒千次为单位200台终端每17分钟同步一次流量几乎可以忽略。真正要关注的是配置正确性和链路可用性。4.2 服务端操作四步搭起来第一步是安装见第二节不再重复。第二步编辑配置参考3.4的服务端模板。如果目标机器时间偏差本身就很大比如慢了几十分钟建议先在配置里临时让makestep允许大步跳或者启动后手动执行chronyc makestep。第三步启动服务。注意服务名的发行版差异# RHEL/CentOS 7/8/9 systemctl enable --now chronyd # Debian/Ubuntu systemctl enable --now chrony顺手确认端口监听ss -ulnp | grep 123输出里看到chronyd/chrony监听123端口服务就绪。第四步验证。最常用的两个命令chronyc sources -v chronyc trackingchronyc sources -v输出中^*表示当前锁定且正在使用的源^表示可用的候选源^-表示被排除的源^?表示源不可达。chronyc tracking里的关键字段有System time系统时钟相对源的偏差、RMS offset均方根偏差值、Last offset最近一次调整值。企业环境下等系统运行十几分钟后RMS offset稳定在个位数到几十毫秒时间同步就基本达标了。物理服务器记得把时间写回硬件时钟防止断电后RTC继续漂移hwclock --systohc虚拟化平台环境这一步通常不需要虚拟机的RTC由宿主机统一管理。4.3 客户端配置Linux和Windows一个都不能少Linux终端/服务器的配置最简单安装chrony后离线场景参考第二节在/etc/chrony.conf里写server 192.168.0.10 iburst server 192.168.0.11 iburst然后enable服务即可。有一点容易忽略域内Windows终端其实不需要手动配置NTP它们自动跟随域控的时间服务需要手工配置的是不在域里的Windows设备、物理服务器和各类Linux主机。Windows设备用系统自带的w32tmw32tm /config /manualpeerlist:192.168.0.10,192.168.0.11 /syncfromflags:manual /reliable:yes /update Restart-Service w32time w32tm /resync w32tm /query /status没有域环境的纯办公网可以用这条命令配合批处理推下去。如果公司用了AD域建议把域控时间同步到内网chrony源让域内机器全部通过域控间接对齐避免域控和终端各自指向不同的源造成二次漂移。4.4 批量验证别只看服务端要跑完200台服务端sources输出正常只能证明服务端本身在工作不能证明终端都指对了。200台设备逐台手动看显然不现实我习惯用一个简单的脚本批量探查。前提是目标Linux终端装了chrony客户端或者用ntpdate做一次查询#!/bin/bash TARGET192.168.0.10 SUBNET192.168.0. 192.168.10. 192.168.20. for ip in ${SUBNET[]}; do for host in $(seq 1 254); do addr${ip}${host} if ping -c1 -W1 $addr /dev/null; then result$(timeout 5 chronyc -h $TARGET -n sources 2/dev/null | grep -E ^\^\* || echo no-sync) echo $addr - $result fi done done这个脚本只是演示批量探查的思路实际跑的时候按公司子网和终端数量调整即可。更规范的做法是用Ansible等配置管理工具批量下发chrony.conf并启动服务一次操作200台不是问题。工具选型上200人规模用Ansible都算轻量方案关键是避免手动一台台改的脏活。5. 实际部署中踩过的坑防火墙、SELinux、虚拟机时间覆盖最后这部分是我认为本文最有价值的地方——配置照抄大家都行但很多问题只有在真实环境里跑过才会知道。我按踩坑频率从高到低讲。5.1 防火墙是“同不同步”最大的分水岭现象配置写了allow服务也起来了但客户端chronyc sources时一直显示^?停留在不可达状态。排查链路先在服务端看123端口是否在监听ss -ulnp | grep 123再确认防火墙策略firewall-cmd --list-all。RHEL系默认firewalld只放行sshUDP 123没放行外面自然访问不到。解决firewall-cmd --permanent --add-servicentp firewall-cmd --reloadntp这个预定义服务对应的就是UDP 123。如果是在云环境云安全组也要放行UDP 123办公网内部的话上级防火墙一般不限制出方向UDP 123但服务端入方向必须放行。千万不要为了调试方便直接systemctl stop firewalld或者把123端口对全网段开放——小企业环境安全审计一样会盯这个正规做法是只放行内网网段。5.2 SELinux标签问题restorecon能救一半现象rpm正常装完systemctl start chronyd却失败journalctl -u chronyd看到permission denied指向/var/lib/chrony目录。原因SELinux Enforcing模式下chronyd对/var/lib/chrony目录的上下文有要求。如果这个目录是后来手动创建的或者rpm安装时没有正确设置标签就会出权限问题。解决restorecon -Rv /var/lib/chrony /var/log/chrony systemctl restart chronyd这条命令我每次部署时都会先执行一遍成本极低能省掉不少莫名其妙的启动失败排查时间。5.3 服务名不一致和ntpd残留两个经典混乱源RHEL系服务名是chronydDebian/Ubuntu是chrony。写文档、做脚本时如果混用部署就会挂。我的习惯是部署脚本里先判断发行版再决定服务名。另一个大坑是系统里残留的ntpd/ntpdate服务。老机器上可能还装过传统的ntpd它和chrony抢同一个UDP 123端口两个一起启就会有一个起不来。还有ntpdate服务或cron里的ntpdate定时任务会不定期把时钟强制拉到某台源上去把chrony的渐变调整逻辑完全打乱。处理办法systemctl disable --now ntpd ntpdate ss -ulnp | grep 123确保123端口只被chrony占用。5.4 虚拟机时间同步覆盖配置再对也白搭现象chrony配置一切正常也能连上源但是虚拟机时间每隔一段时间就跳一下或者长期偏慢chrony日志里频繁出现step事件。原因VMware Tools默认的Time Sync功能会定期把宿主机时间同步给客户机这个动作是直接修改客户机系统时间完全绕过chrony。如果宿主机时间本身有漂移客户机就会被反复带偏。解决vmware-toolbox-cmd timesync disable在ESXi虚拟机配置里把“Time Synchronization”的勾选去掉。这个坑在物理机验证时完全不存在一旦迁移到虚拟化环境就冒出来很多同行排查了半天找不到原因最后发现是宿主机在“捣乱”。Hyper-V、KVM/QEMU也有类似的机制部署到这些平台时同样要检查。5.5 大偏差存量设备的makestep策略现象一台老服务器从没被纳管过时间慢了半小时。配置好chrony指向内网源之后tracking显示offset确实在一点点变小但收敛速度极慢看起来永远追不上。原因默认makestep 1 3对“前三次更新”的限制已经耗尽之后时间只会走slew渐变方式微调。对半小时的偏差来说slew的收敛速度可能是每分钟几毫秒级别等于要跑很久才能对齐。解决直接手动步进chronyc makestep这条命令会立刻把本机时间调整到与源一致风险是业务可能看到一次时间跳变。对已经乱了几十分钟的机器来说这次跳变是完全值得的。处理完大偏差后把配置恢复成makestep 1 3让日常运行走渐变即可。这件事给我的教训是处理“历史欠账”时间偏差大的机器第一反应应该是先手动makestep拉齐再让Chrony做后续微调而不是让它自己慢慢收敛。5.6 域名解析离线环境的隐形杀手chrony.conf里如果写的源是hostname而不是IP离线内网DNS解析不到服务端就会永远没有可用源。离线网络最常见的现象就是配置文件看起来没问题chronyc sources -v却一直显示^?最后发现是域名解析失败。内网自建时间源配置里直接写IP或者确保DNS服务里能解析到内网NTP源的主机名。把这套方案完整跑下来之后我对“无安装包”这个前提反而有了新的体会。对很多企业内部网络来说离线不是什么意外状况而是日常常态。与其每次遇到问题临时找包不如平时就把系统ISO、常用软件包按版本归档起来放到内网软件仓库里。我现在的习惯是每次装完一个新环境就把用到的rpm/deb顺手备份一份十分钟的事等哪天真的需要离线部署时就会知道这些积累有多值钱。部署Chrony只是这类场景里很典型的一个切面——包能搞定配置能落地剩下的就是耐心和排查经验。
返回列表