自动挂载网络存储的脚本怎么写

wen 实用脚本 1

从入门到实战的完整指南

目录导读

  1. 为什么需要自动挂载网络存储? – 解决手动挂载的痛点
  2. 核心原理 – 理解mount、fstab与自动挂载机制
  3. 准备工作 – 确认网络存储类型(NFS/SMB/iSCSI)
  4. 实战脚本编写 – 分步实现自动挂载
  5. 高级技巧 – 故障重试、日志记录、安全认证
  6. 常见问题与问答 – 解决挂载失败、权限错误等
  7. 总结与最佳实践 – 让你的脚本更健壮

为什么需要自动挂载网络存储?

1 手动挂载的三大痛点

许多运维人员和管理员都有这样的经历:每次重启服务器后,都要手动执行mount -a或重新挂载网络驱动器,这不仅浪费时间,还容易导致:

自动挂载网络存储的脚本怎么写

  • 服务中断:依赖网络存储的服务(如数据库、文件共享)在重启后无法启动
  • 人为错误:忘记挂载导致数据不可访问
  • 批量管理困难:在多台服务器上重复操作

2 自动挂载的典型场景

  • 企业NAS/NFS共享:开发团队共享代码仓库
  • 云存储挂载:阿里云NAS、AWS EFS等云厂商的网络文件系统
  • 备份服务器:定时备份到远程存储设备
  • Docker/虚拟机:持久化数据的自动附挂

关键点:自动挂载脚本的核心需求是“系统启动时自动执行”和“挂载失败时自动重试”。


核心原理:mount、fstab与自动挂载机制

在写脚本之前,你需要理解Linux下的挂载体系:

1 标准挂载命令

# NFS示例
mount -t nfs 192.168.1.100:/export/data /mnt/nfs_data
# SMB/CIFS示例(需安装cifs-utils)
mount -t cifs //192.168.1.101/share /mnt/winshare \
  -o username=admin,password=passwd,domain=WORKGROUP

2 /etc/fstab 的局限性

/etc/fstab是传统的自动挂载方案,但存在明显缺陷:

  • 网络依赖:如果网络在fstab执行时未就绪(如DHCP未完成),挂载会失败
  • 无重试机制:一旦失败不再尝试,导致服务异常
  • 调试困难:错误信息不易追踪

3 为什么需要脚本?

脚本可以弥补fstab的不足:

  • 延迟挂载(等待网络就绪)
  • 失败重试(最多尝试5次)
  • 记录日志(便于排查问题)
  • 灵活配置(按需挂载不同协议)

准备工作:确认你的网络存储类型

在编写脚本前,请先确认以下信息:

1 协议类型与依赖工具

协议 必备软件包 典型挂载命令
NFS nfs-common/nfs-utils mount -t nfs
SMB/CIFS cifs-utils mount -t cifs
iSCSI open-iscsi iscsiadm + mount

2 获取服务器连接信息

  • NFS:服务端IP、导出路径(如/data)、挂载选项(vers=4.2
  • SMB:共享名、用户名/密码、域(可选)
  • iSCSI:目标IQN、LUN编号

3 构建测试环境(推荐)

建议先手动执行挂载命令,验证网络连通性和权限:

# 测试NFS
showmount -e 192.168.1.100
mount -t nfs 192.168.1.100:/export /mnt/test && ls /mnt/test

实战脚本编写:分步实现自动挂载

下面提供一个通用且健壮的自动挂载脚本模板,支持NFS和SMB。

1 脚本结构设计

/opt/scripts/auto_mount.sh  → 主执行脚本
/etc/systemd/system/        → 系统服务单元(可选)
/var/log/auto_mount.log    → 日志文件

2 基础脚本代码(支持NFS示例)

#!/bin/bash
# auto_mount.sh – 自动挂载网络存储(支持重试与日志)
# 版本:1.2 | 适用环境:Ubuntu 20.04+ / CentOS 7+
# 配置区 – 按需修改
MOUNT_POINT="/mnt/nas_data"
SERVER_IP="192.168.1.100"
EXPORT_PATH="/volume1/data"
FS_TYPE="nfs"
MOUNT_OPTS="vers=4.2,hard,intr,timeo=600,retrans=2"
MAX_RETRIES=5
RETRY_INTERVAL=10  # 秒
# 日志函数
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a /var/log/auto_mount.log
}
# 检查挂载点是否存在,不存在则创建
check_mountpoint() {
    if [ ! -d "$MOUNT_POINT" ]; then
        mkdir -p "$MOUNT_POINT"
        log "创建挂载点目录:$MOUNT_POINT"
    fi
}
# 是否已挂载
is_mounted() {
    mountpoint -q "$MOUNT_POINT"
    return $?
}
# 执行挂载
do_mount() {
    mount -t $FS_TYPE "$SERVER_IP:$EXPORT_PATH" "$MOUNT_POINT" -o "$MOUNT_OPTS"
    return $?
}
# 主逻辑
main() {
    check_mountpoint
    if is_mounted; then
        log "目标已挂载,跳过。"
        exit 0
    fi
    log "开始挂载 $SERVER_IP:$EXPORT_PATH 到 $MOUNT_POINT"
    local retry=0
    while [ $retry -lt $MAX_RETRIES ]; do
        if do_mount; then
            log "挂载成功!"
            exit 0
        else
            retry=$((retry + 1))
            log "挂载失败(尝试 $retry/$MAX_RETRIES),等待 ${RETRY_INTERVAL}秒后重试..."
            sleep $RETRY_INTERVAL
        fi
    done
    log "错误:挂载失败,已达最大重试次数。"
    exit 1
}
main

3 扩展支持SMB/CIFS

若需挂载Windows共享,只需修改配置区:

# 修改为
FS_TYPE="cifs"
MOUNT_OPTS="username=admin,password=your_pwd,domain=WORKGROUP,vers=3.0"
SERVER_IP="//192.168.1.101"  # SMB使用双斜杠
EXPORT_PATH="shared_folder"   # 注意无需冒号
do_mount() {
    mount -t cifs "$SERVER_IP/$EXPORT_PATH" "$MOUNT_POINT" -o "$MOUNT_OPTS"
}

4 集成到系统启动(Systemd服务单元)

创建 /etc/systemd/system/auto-mount.service

[Unit]
Description=Auto Mount Network Storage
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/opt/scripts/auto_mount.sh
RemainAfterExit=yes
StandardOutput=journal
[Install]
WantedBy=multi-user.target

然后执行:

systemctl daemon-reload
systemctl enable auto-mount.service
systemctl start auto-mount.service

高级技巧:让脚本更强大

1 故障重试增强

  • 指数退避:失败后等待时间递增(10s,20s,40s...)
  • 网络预检查:先ping目标IP再挂载
# 添加网络检测
ping -c 1 -W 2 $SERVER_IP &>/dev/null
if [ $? -ne 0 ]; then
    log "警告:目标IP不可达,尝试继续挂载..."
fi

2 日志分级与清理

# 日志轮转(配合logrotate)
/var/log/auto_mount.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
}

3 安全认证优化

  • 使用凭据文件(避免密码明文):

    # 创建凭据文件 /etc/samba/credentials
    username=admin
    password=secure_pass
    domain=WORKGROUP
    # 脚本中使用 credentials=/etc/samba/credentials
  • NFS使用Kerberossec=krb5 选项(需配置kdc)

4 多存储挂载支持

通过配置文件(如YAML/JSON),脚本循环读取:

while IFS="|" read mount_point server export ops; do
    # 逐个挂载
done < /etc/auto_mount.conf

配置文件示例:

/mnt/data1|192.168.1.100|/exports/data|vers=4.2
/mnt/backup|//192.168.1.101|backups|username=backup,dir_mode=0755

常见问题与问答

Q1:脚本执行后依然无法挂载,日志显示“mount.nfs: Connection refused”

A:这通常表明NFS服务端未运行或防火墙阻止,请按以下顺序排查:

  1. 在服务端执行 systemctl status nfs-server 确认服务已启动
  2. 检查防火墙:ufw statusfirewall-cmd --list-all,需要开放NFS端口(2049/TCP+UDP,及rpcbind)
  3. 使用 showmount -e <server_ip> 验证导出路径是否匹配

Q2:系统重启后脚本未执行,如何调试?

A:检查以下几点:

  1. systemctl is-enabled auto-mount.service 确保服务已启用
  2. 查看启动日志:journalctl -u auto-mount.service
  3. 确认 network-online.target 已成功(可能需安装 network-wait-online
  4. 尝试手动执行 /opt/scripts/auto_mount.sh 测试脚本本身是否有语法错误

Q3:SMB挂载时提示“mount error(13): Permission denied”

A:可能性及解决方案:

  • 密码错误:重新检查凭据文件或命令行密码
  • 用户权限不足:确认服务端对应用户有共享目录的写入权限
  • 协议版本不兼容:尝试 vers=1.0vers=3.0 选项
  • 需要启用guest访问:guest,uid=nobody,gid=nogroup

Q4:脚本挂载成功后,但应用程序仍提示“文件系统只读”

A:检查挂载选项中的权限设置:

  • NFS:确保服务端导出选项包含 rwno_root_squash(若需root写入)
  • SMB:在选项中添加 file_mode=0777,dir_mode=0777 以开放权限,同时检查服务端共享权限

Q5:如何判断脚本是否已经挂载,避免重复挂载?

A:脚本已内置 mountpoint -q $MOUNT_POINT 检测,如果之前挂载成功,在下次执行时会直接退出,也可通过检查 /proc/mounts

grep "$MOUNT_POINT" /proc/mounts > /dev/null && echo "已挂载"

Q6:有没有更简单的方式,不需要自己写脚本?

A:对于简单场景,可以使用 autofs 实现按需挂载,但它的配置对新手有一定门槛,如果你的环境较复杂(多协议、多存储、需要特定重试策略),自定义脚本是最灵活的方式,云服务商通常有CLI脚本生成器(如阿里云NAS的自动挂载脚本),但缺乏重试机制。


总结与最佳实践

1 核心建议

  1. 始终包含日志tee -a 写在每一行输出,方便事后追踪
  2. 测试先于部署:在测试环境用 bash -x auto_mount.sh 跟踪执行过程
  3. 避免硬编码密码:使用凭据文件或环境变量(注意权限安全)
  4. 考虑网络延迟timeoretrans 参数要适配实际网络质量
  5. 脚本标准化:放在 /opt/scripts 并赋予755权限,所有者设为root

2 扩展阅读

  • 官方文档:man mountman nfsman mounts
  • 查找挂载失败的原因:dmesg | tailtail -f /var/log/messages
  • 性能调优:调整 rsize(读取块大小)和 wsize 参数

3 最后的检查清单

  • [ ] 网络存储可达(ping通)
  • [ ] 服务端导出/共享配置正确
  • [ ] 挂载点目录存在且不为空
  • [ ] 脚本具有执行权限
  • [ ] Systemd服务已启用并检查状态

通过以上步骤,你将拥有一个稳定、可重用的自动挂载脚本,让网络存储的维护变得轻松高效,如果你在实施过程中遇到任何问题,欢迎根据文中的QA部分逐一排查,或参考官方手册深入调试。

抱歉,评论功能暂时关闭!