数千台Linux服务器时间同步配置批量整改实操案例

文章讲述了如何应对Linux服务器时间管理混乱的问题,通过使用Ansible脚本实现批量自动化的NTP时间同步,关闭不必要的服务,配置开机启动和定时任务,确保服务器时间与在线NTP服务器保持同步,减少对业务的影响。
摘要由CSDN通过智能技术生成

背景

因“杂乱的管理”和“历史的沉淀”导致大量服务器的时间问题乱象丛生,然而时间的正确对业务保障的重要性是毋庸置疑的,所以很有必要来一次大检查和大整改。

现状

征对Linux系统,问题复杂如下:

  • 系统版本不一样,权限不一样,登陆方式不一样;
  • 有的采用ntp客户端命令ntpdate,或与已下架NTP服务器、在线NTP服务器地址等NTP目标同步;
  • 采用ntp客户端命令ntpdate同步,数量众多,数千台服务器几乎集中在同一时刻和NTP服务器同步,对NTP服务器来讲,请求集中在0.00001%的时间里,另外99.9999%的时间闲置;
  • 有的启用了NTP服务,或与初始默认NTP地址、本地硬件时钟、已下架NTP服务器地址、在线NTP服务器地址等NTP目标同步;
  • 有的采用chrony服务,同步目标也比较乱;
  • 有的不能使用yum源;

需求

保证所有Linux服务器在开机时和开机后定期和在线NTP服务器保持时间同步。

分析和处置思路

因配置杂乱和登陆权限不同,一台一台检查和整改的效率低下,随机考查现场配置后,整理一个可反复执行,且能照顾所有Linux系统的配置脚本,通过Ansible一并反复跑几遍,每遍采用不同的权限。

脚本实现以下功能:

  • 关闭ntp服务,采用ntp客户端命令ntpdate同步;
  • ntpdate同步配置在开机启动和crontab中,通过RANDOM变量实现随机性(有同行采用python实现随机性的,但发现有的系统没有python),解决“NTP服务被请求的时间集中在0.00001%”的问题;
  • rhel7+启用chronyd,考虑到现场的复杂性,不一定能安装chronyd,仍保留ntpdate同步,实践发现两者兼容不冲突;
  • ntpdate同步结果写入日志以便观察,由logrotate管理日志生命周期。

脚本内容

op_timesync_rhel.sh脚本内容
(因信息安全需要,对脚本内容进行了精简,敏感内容进行了替换)

#!/bin/bash
###################################
# function   服务器时间同步配置整改
# 参考创建或使用示例: mkdir -p /root/sh/log; touch /root/sh/op_timesync_rhel.sh; chmod a+x /root/sh/op_timesync_rhel.sh
#
# Change History:
# date        author       note
# 2024/01/04  N            create
#
###################################

export LANG=C
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

#获取系统大版本号,以RHEL为基准,至少适用于RHEL系5-9,包括CentOS,AlmaLinux,Rocky Linux等,目前把openEuler等转换版本后视为rhel判断
if [ -f /etc/redhat-release ];then
    export rhel_release=`cat /etc/redhat-release | awk -F'(' '{ print $1; }' | awk '{ print $(NF-0); }' | awk -F. '{ print $1; }'`
elif [ -f /etc/openEuler-release ];then
    openEuler_release=`cat /etc/openEuler-release | awk '{ print $3; }' | awk -F. '{ print $1; }'`
    if [ "$openEuler_release" == 20 ];then
        export rhel_release=8
    elif [ "$openEuler_release" == 22 ];then
        export rhel_release=9
    fi
fi


if [ "$rhel_release" -le "6" ];then
    #查看服务状态
    /etc/init.d/ntpd status

    #服务配置
    yum install -y ntp
    chkconfig --level 2345 ntpd off; /etc/init.d/ntpd stop
elif [ "$rhel_release" -ge "7" ];then
    #查看服务状态
    systemctl status chronyd.service; systemctl status ntpd.service

    #服务配置
    yum install -y chrony ntp
    systemctl enable chronyd.service; systemctl restart chronyd.service
    systemctl disable ntpd.service; systemctl stop ntpd.service

    # 配置chronyd
    sed -i '/oldntpip/d' /etc/chrony.conf
    if (! grep -q auto_op_mark /etc/chrony.conf); then
        sed -ri '/pool.ntp.org/s/^server .*/#&/' /etc/chrony.conf
        sed -i '6a### auto_op_mark_begin ###' /etc/chrony.conf
        sed -i '7aserver newntp_ip_or_domain_1 iburst' /etc/chrony.conf
        sed -i '8aserver newntp_ip_or_domain_2 iburst' /etc/chrony.conf
        sed -i '9a### auto_op_mark_end ###' /etc/chrony.conf
    elif (grep -q auto_op_mark /etc/chrony.conf); then
        echo "The time service automation configuration already exists, replace"
        sed -i '/auto_op_mark_begin/,/auto_op_mark_end/d' /etc/chrony.conf
        sed -ri '/pool.ntp.org/s/^server .*/#&/' /etc/chrony.conf
        sed -i '6a### auto_op_mark_begin ###' /etc/chrony.conf
        sed -i '7aserver newntp_ip_or_domain_1 iburst' /etc/chrony.conf
        sed -i '8aserver newntp_ip_or_domain_2 iburst' /etc/chrony.conf
        sed -i '9a### auto_op_mark_end ###' /etc/chrony.conf
    else
        echo "error"    
    fi
    systemctl restart chronyd.service
    sleep 5 # 停顿5秒才可能查询到正常状态
    #同步状态
    chronyc tracking | egrep "Reference ID|Leap status"
else
    echo "error"
fi



# NTP配置
sed -i '/ntpdate.*oldntpip/d' /var/spool/cron/root
if (! grep -q auto_op_mark /var/spool/cron/root); then
    echo '### auto_op_mark_begin ###' >> /var/spool/cron/root
    echo '*/30 * * * * sleep $(expr $RANDOM \% 1800 + 1); /usr/sbin/ntpdate -u newntp_ip_or_domain_1 &>> /var/log/ntpdate.log && /sbin/hwclock -w' >> /var/spool/cron/root
    echo '*/30 * * * * sleep $(expr $RANDOM \% 1800 + 1); /usr/sbin/ntpdate -u newntp_ip_or_domain_2 &>> /var/log/ntpdate.log && /sbin/hwclock -w' >> /var/spool/cron/root
    echo '### auto_op_mark_end ###' >> /var/spool/cron/root
elif (grep -q auto_op_mark /var/spool/cron/root); then
    echo "The time service automation configuration already exists, replace"
    sed -i '/auto_op_mark_begin/,/auto_op_mark_end/d' /var/spool/cron/root
    echo '### auto_op_mark_begin ###' >> /var/spool/cron/root
    echo '*/30 * * * * sleep $(expr $RANDOM \% 1800 + 1); /usr/sbin/ntpdate -u newntp_ip_or_domain_1 &>> /var/log/ntpdate.log && /sbin/hwclock -w' >> /var/spool/cron/root
    echo '*/30 * * * * sleep $(expr $RANDOM \% 1800 + 1); /usr/sbin/ntpdate -u newntp_ip_or_domain_2 &>> /var/log/ntpdate.log && /sbin/hwclock -w' >> /var/spool/cron/root
    echo '### auto_op_mark_end ###' >> /var/spool/cron/root
else
    echo "error"    
fi


sed -i '/ntpdate.*oldntpip/d' /etc/rc.local
if (! grep -q auto_op_mark /etc/rc.local); then
    echo '### auto_op_mark_begin ###' >> /etc/rc.local
    echo 'echo "$(date) Ntpdate is executed when the system starts." &>> /var/log/ntpdate.log'  >> /etc/rc.local
    echo "/usr/sbin/ntpdate -u newntp_ip_or_domain_1 &>> /var/log/ntpdate.log && /sbin/hwclock -w" >> /etc/rc.local
    echo "/usr/sbin/ntpdate -u newntp_ip_or_domain_2 &>> /var/log/ntpdate.log && /sbin/hwclock -w" >> /etc/rc.local
    echo '### auto_op_mark_end ###' >> /etc/rc.local
elif (grep -q auto_op_mark /etc/rc.local); then
    echo "The time service automation configuration already exists, replace"
    sed -i '/auto_op_mark_begin/,/auto_op_mark_end/d' /etc/rc.local
    echo '### auto_op_mark_begin ###' >> /etc/rc.local
    echo 'echo "$(date) Ntpdate is executed when the system starts." &>> /var/log/ntpdate.log'  >> /etc/rc.local
    echo "/usr/sbin/ntpdate -u newntp_ip_or_domain_1 &>> /var/log/ntpdate.log && /sbin/hwclock -w" >> /etc/rc.local
    echo "/usr/sbin/ntpdate -u newntp_ip_or_domain_2 &>> /var/log/ntpdate.log && /sbin/hwclock -w" >> /etc/rc.local
    echo '### auto_op_mark_end ###' >> /etc/rc.local
else
    echo "error"    
fi    
chmod a+x /etc/rc.d/rc.local
#立即同步
/usr/sbin/ntpdate -u newntp_ip_or_domain_1 && /sbin/hwclock -w
/usr/sbin/ntpdate -u newntp_ip_or_domain_2 && /sbin/hwclock -w

#日志管理
cat <<\EOF> /etc/logrotate.d/ntpdate
/var/log/ntpdate.log {
    monthly
    copytruncate
    rotate 6
    minsize 20M
}
EOF

ansible操作

inventory配置示例

cat <<EOF>inventory_20240104
[servers1]
1.2.3.[1:200]
1.2.4.[1:200]
1.2.5.[1:200]
1.2.6.[1:200]
1.2.7.[1:200]
1.2.8.[1:200]
1.2.9.[1:200]

[servers2]
2.2.3.[1:200]
2.2.4.[1:200]
2.2.5.[1:200]
2.2.6.[1:200]
2.2.7.[1:200]
2.2.8.[1:200]
2.2.9.[1:200]
EOF

#检验inventory配置
ansible -i inventory_20240104 all[0:] --list-hosts
ansible -i inventory_20240104 all[0:] -m shell -a ‘ip a | egrep “scope global” | egrep “eth|ens|eno|bond”’ -u username -k -b -K #查询系统IP,可选操作
#其中username是系统普通用户名

评估的对业务的影响

ansible -i inventory_20240104 all[0:] -m shell -a ‘date’ -u username -k -b -K
核对服务器时区时间,和北京时间接近,便判断为无影响。

一些因时间同步影响业务的案例

  • 前不久看到一遍文档,讲修改下系统时间就导致数百的用户账号无法登陆,领导随后调集各部门同事分析,确定了原因是账号过期,因系统时间回归正常导致,DBA批量修改账号过期时间才得已解决;
  • 一游戏服务器,因时间同步频率较低,和客户端时间精确度每超过几秒就会导致游戏场景里的走位异常。

大批量执行

ansible -i inventory_20240104 all[0:] -m shell -a "mkdir -p /root/sh/20240104/" -u username -k -b -K
ansible -i inventory_20240104 all[0:] -m copy -a "src=op_timesync_rhel.sh dest=/root/sh/20240104/" -u username -k -b -K
ansible -i inventory_20240104 all[0:] -m shell -a "bash /root/sh/20240104/op_timesync_rhel.sh" -u username -k -b -K
#查看
ansible -i inventory_20240104 all[0:] -m shell -a 'cat /etc/rc.local;crontab -l;systemctl status chronyd.service; systemctl status ntpd.service;chronyc tracking | egrep "Reference ID|Leap status"' -u username -k -b -K

统计变更数量

把上面的执行结果导入日志中便可统计,例:
grep CHANGED ansible.log | uniq -c | wc -l

工作结果

有个别服务器因特殊原因未能整改的,可单独执行脚本;
能顺利变更的数千台,大概1小时内就能完成,比“一台一台手动检查和修改每个配置”的效率快上千倍以上,并且有更可靠的保障,如果需要再次变更,改下脚本便可执行;
试想一下,如果手动刚修改完一千台,NTP地址又需要变更了,会是一种什么心情?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沉思的归零者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值