diff --git a/bushu.conf b/bushu.conf index 1a5fa69..1a606ae 100644 --- a/bushu.conf +++ b/bushu.conf @@ -37,6 +37,29 @@ NODE_NAME="rk3588" NODE_IP="10.250.0.5" NODE_EXT_IP="10.250.0.5" + +# ----------------------- +# 时间同步配置 +# ----------------------- + +# 是否启用 chrony:true / false +ENABLE_CHRONY=true + +# 是否启用 gPTP:true / false +ENABLE_GPTP=true + +# gPTP 使用的物理网卡 +GPTP_IFACE="eth11" + +# chrony 时间服务器 +CHRONY_SERVERS=( + "10.250.0.1 iburst prefer" + "10.250.0.2 iburst" + "10.250.0.3 iburst" +) + + + # ------------------- # 域名解析列表 (每行一个条目) # 格式: "IP hostname1 hostname2 ..." diff --git a/bushujb.sh b/bushujb.sh index f7a2b47..b89cfe1 100644 --- a/bushujb.sh +++ b/bushujb.sh @@ -301,9 +301,48 @@ mirrors: EOF # ----------------------- -# NVMe 初始化 +# NVMe 分区与格式化 # ----------------------- +# 检查磁盘是否存在 +if [[ ! -b /dev/nvme0n1 ]]; then + echo "错误:/dev/nvme0n1 不存在" + exit 1 +fi + +# 如果分区不存在,则创建 +if [[ ! -b /dev/nvme0n1p1 ]]; then + echo "/dev/nvme0n1p1 不存在,开始创建分区..." + + if lsblk -nr /dev/nvme0n1 | awk '{print $6}' | grep -q '^part$'; then + echo "检测到已有分区,但没有 nvme0n1p1,请手动检查" + exit 1 + fi + + parted -s /dev/nvme0n1 mklabel gpt + parted -s /dev/nvme0n1 mkpart primary 0% 100% + + partprobe /dev/nvme0n1 + sleep 2 + + if [[ ! -b /dev/nvme0n1p1 ]]; then + echo "错误:分区创建失败" + exit 1 + fi + + echo "分区创建成功:/dev/nvme0n1p1" +else + echo "/dev/nvme0n1p1 已存在,跳过创建分区" +fi + +# 如果没有文件系统,则格式化 +if ! blkid /dev/nvme0n1p1 >/dev/null 2>&1; then + echo "/dev/nvme0n1p1 没有文件系统,开始格式化为 ext4..." + mkfs.ext4 -F /dev/nvme0n1p1 +else + echo "/dev/nvme0n1p1 已有文件系统,跳过格式化" +fi + # ----------------------- # NVMe 挂载与绑定挂载 # ----------------------- @@ -319,6 +358,10 @@ else echo "/mnt/nvme 已经挂载,跳过挂载" fi +# ✅ 确保源目录存在(关键修复点) +mkdir -p /mnt/nvme/rancher +mkdir -p /mnt/nvme/longhorn + # 确保绑定挂载目标目录存在 mkdir -p /var/lib/rancher mkdir -p /var/lib/longhorn @@ -339,49 +382,205 @@ else echo "/var/lib/longhorn 已经挂载,跳过绑定挂载" fi -# 更新 /etc/fstab,保证开机自动挂载 +# ----------------------- +# 更新 /etc/fstab +# ----------------------- + NVME_UUID=$(blkid -s UUID -o value /dev/nvme0n1p1) +NVME_FSTYPE=$(blkid -s TYPE -o value /dev/nvme0n1p1) +if [[ -z "$NVME_UUID" || -z "$NVME_FSTYPE" ]]; then + echo "错误:无法获取 UUID 或文件系统类型,停止写入 fstab" + exit 1 +fi + +# 主挂载(安全) grep -qE "[[:space:]]/mnt/nvme[[:space:]]" /etc/fstab || \ -echo "UUID=${NVME_UUID} /mnt/nvme ext4 defaults,nofail 0 2" >> /etc/fstab +echo "UUID=${NVME_UUID} /mnt/nvme ${NVME_FSTYPE} defaults,nofail,x-systemd.device-timeout=5 0 2" >> /etc/fstab -grep -qE "^/mnt/nvme/rancher[[:space:]]+/var/lib/rancher[[:space:]]+none[[:space:]]+bind" /etc/fstab || \ -echo "/mnt/nvme/rancher /var/lib/rancher none bind 0 0" >> /etc/fstab +# bind mount(安全) +grep -qE "[[:space:]]/var/lib/rancher[[:space:]]" /etc/fstab || \ +echo "/mnt/nvme/rancher /var/lib/rancher none bind,nofail,x-systemd.requires-mounts-for=/mnt/nvme 0 0" >> /etc/fstab -grep -qE "^/mnt/nvme/longhorn[[:space:]]+/var/lib/longhorn[[:space:]]+none[[:space:]]+bind" /etc/fstab || \ -echo "/mnt/nvme/longhorn /var/lib/longhorn none bind 0 0" >> /etc/fstab +grep -qE "[[:space:]]/var/lib/longhorn[[:space:]]" /etc/fstab || \ +echo "/mnt/nvme/longhorn /var/lib/longhorn none bind,nofail,x-systemd.requires-mounts-for=/mnt/nvme 0 0" >> /etc/fstab -# 显示挂载状态 +# ----------------------- +# 验证 +# ----------------------- + +echo "测试 fstab..." +mount -a + +echo "显示挂载状态" findmnt /mnt/nvme findmnt /var/lib/rancher findmnt /var/lib/longhorn - # ----------------------- # 时间同步 # ----------------------- -echo "=== 安装并配置 chrony ===" -apt update -apt install -y chrony linuxptp -cp /etc/chrony/chrony.conf /etc/chrony/chrony.conf.bak 2>/dev/null -cat > /etc/chrony/chrony.conf << EOF -server 10.250.0.1 iburst prefer -server 10.250.0.2 iburst -server 10.250.0.3 iburst +echo "=== 时间同步配置 ===" + +: "${ENABLE_CHRONY:=true}" +: "${ENABLE_GPTP:=false}" + +if [[ "${ENABLE_CHRONY}" == "true" || "${ENABLE_GPTP}" == "true" ]]; then + echo "安装时间同步相关组件..." + apt update + apt install -y chrony linuxptp +fi + +# =================================================== +# chrony 配置:由客户选择是否启用 +# =================================================== +if [[ "${ENABLE_CHRONY}" == "true" ]]; then + echo "=== 启用 chrony 时间同步 ===" + + cp /etc/chrony/chrony.conf /etc/chrony/chrony.conf.bak 2>/dev/null || true + + cat > /etc/chrony/chrony.conf << EOF +# 由 bushu.sh 自动生成 + +EOF + + for server in "${CHRONY_SERVERS[@]}"; do + echo "server ${server}" >> /etc/chrony/chrony.conf + done + + cat >> /etc/chrony/chrony.conf << EOF driftfile /var/lib/chrony/chrony.drift makestep 1.0 3 rtcsync logdir /var/log/chrony EOF -systemctl enable chrony -systemctl restart chrony -chronyc sources -chronyc tracking -echo "=== 启动 PTP 同步 ===" -ptp4l -i $CLOUD_IFACE -m & -phc2sys -s $CLOUD_IFACE -c CLOCK_REALTIME -m & + systemctl enable chrony + systemctl restart chrony + + chronyc sources || true + chronyc tracking || true + + echo "chrony 已启用" +else + echo "=== 未启用 chrony ===" + systemctl disable chrony 2>/dev/null || true + systemctl stop chrony 2>/dev/null || true +fi + +# =================================================== +# gPTP 配置:由客户选择是否启用 +# =================================================== +if [[ "${ENABLE_GPTP}" == "true" ]]; then + echo "=== 启用 gPTP 时间同步 ===" + + : "${GPTP_IFACE:?请在 bushu.conf 中配置 GPTP_IFACE}" + + echo "gPTP 使用物理网卡: ${GPTP_IFACE}" + + mkdir -p /usr/local/bin + mkdir -p /etc/linuxptp + + # ----------------------- + # 创建 gPTP 配置文件 + # ----------------------- + cat > /etc/linuxptp/gptp.cfg << EOF +# 由 bushu.sh 自动生成 +# gPTP / IEEE 802.1AS 配置 + +[global] +gmCapable 1 +priority1 248 +priority2 248 +logAnnounceInterval 0 +logSyncInterval -3 +syncReceiptTimeout 3 +neighborPropDelayThresh 800 +min_neighbor_prop_delay -20000000 +assume_two_step 1 +path_trace_enabled 1 +follow_up_info 1 +transportSpecific 0x1 +ptp_dst_mac 01:80:C2:00:00:0E +network_transport L2 +delay_mechanism P2P +time_stamping hardware +EOF + + # ----------------------- + # 创建 gPTP 执行脚本 + # ----------------------- + cat > /usr/local/bin/start-gptp.sh << 'EOF' +#!/bin/bash +set -euo pipefail + +GPTP_IFACE="${1:?Usage: start-gptp.sh }" + +echo "gPTP interface: ${GPTP_IFACE}" + +# 等待网卡出现 +while ! ip link show "${GPTP_IFACE}" >/dev/null 2>&1; do + echo "等待网卡 ${GPTP_IFACE} 出现..." + sleep 1 +done + +# 启动网卡 +ip link set dev "${GPTP_IFACE}" up + +# 检查网卡是否支持硬件时间戳 +if ethtool -T "${GPTP_IFACE}" 2>/dev/null | grep -q "hardware-transmit"; then + TS_MODE="hardware" +else + echo "警告:${GPTP_IFACE} 可能不支持硬件时间戳,切换为 software timestamp" + TS_MODE="software" + sed -i 's/^time_stamping.*/time_stamping software/' /etc/linuxptp/gptp.cfg +fi + +echo "gPTP timestamp mode: ${TS_MODE}" + +# 启动 ptp4l,使用 gPTP 配置 +exec /usr/sbin/ptp4l \ + -i "${GPTP_IFACE}" \ + -f /etc/linuxptp/gptp.cfg \ + -m +EOF + + chmod +x /usr/local/bin/start-gptp.sh + + # ----------------------- + # 创建 gPTP systemd 服务 + # ----------------------- + cat > /etc/systemd/system/gptp.service << EOF +[Unit] +Description=gPTP IEEE 802.1AS Service +Documentation=man:ptp4l +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/start-gptp.sh ${GPTP_IFACE} +Restart=always +RestartSec=5 +User=root + +[Install] +WantedBy=multi-user.target +EOF + + systemctl daemon-reload + systemctl enable gptp.service + systemctl restart gptp.service + + echo "gPTP 服务已启用" + systemctl status gptp.service --no-pager || true +else + echo "=== 未启用 gPTP ===" + systemctl disable gptp.service 2>/dev/null || true + systemctl stop gptp.service 2>/dev/null || true +fi + # ----------------------- # 域名解析