- ansible/files 改为与文档 XX-YY 对齐的目录结构,更新相关 playbook 路径 - 新增 scripts/verify.sh 与 ansible/playbooks/verify/*.yml,移除单体 verify-matrix.yml - 补充 docs/00-02 矩阵状态、00-05 验证框架与流程、00-04 环境与 ylc65 工作机说明 - 增加 k3s 存储准备、Longhorn、local-path 等 playbook 与辅助脚本 Made-with: Cursor
8.2 KiB
01-05-armv7 NFS 服务安装
本文只讲 armv7 主机侧 NFS 服务安装与导出配置,目标是把
/sdcard作为 NFS 共享目录导出给 K3s 节点使用。
前置条件
- 已完成
01-03-armv7-standalone-docker.md - armv7 与 K3s 节点网络互通
- armv7 上存在挂载点
/sdcard(先用mount | grep /sdcard确认)
操作步骤
- 在 armv7 安装 NFS 服务(
nfs-utils或nfs-kernel-server) - 将
/sdcard目录配置为导出目录 - 配置
/etc/exports - 使导出生效并启用开机自启
- (可选)配置防火墙
1) 安装 NFS 服务(按发行版二选一)
# RHEL/CentOS/Fedora
sudo dnf install -y nfs-utils
sudo systemctl enable --now nfs-server
# Debian/Ubuntu
# sudo apt update
# sudo apt install -y nfs-kernel-server
# sudo systemctl enable --now nfs-kernel-server
2) 确认 /sdcard 可用
mount | grep /sdcard
ls -ld /sdcard
如果
/sdcard是外置存储(SD 卡/U 盘),建议先确认它已在系统启动后自动挂载,再做 NFS 导出。
3) 配置 /etc/exports 导出 /sdcard
示例(允许 192.168.2.0/24 网段读写):
echo "/sdcard 192.168.2.0/24(rw,sync,no_subtree_check,no_root_squash)" | sudo tee /etc/exports
sudo exportfs -rav
参数说明(常用):
rw:允许读写sync:同步写入,数据更稳妥no_subtree_check:减少子目录检查开销no_root_squash:客户端 root 保持 root 权限(仅在可信内网使用)
4) 防火墙(可选,按环境)
如果 armv7 启用了 firewalld:
sudo firewall-cmd --add-service=nfs --permanent
sudo firewall-cmd --add-service=mountd --permanent
sudo firewall-cmd --add-service=rpc-bind --permanent
sudo firewall-cmd --reload
如果是 Debian/Ubuntu + UFW,请按实际策略放行 NFS 相关端口/服务。
验证命令
showmount -e localhost
sudo exportfs -v
sudo systemctl status nfs-server --no-pager || sudo systemctl status nfs-kernel-server --no-pager
预期
showmount -e可看到导出目录/sdcard- NFS 服务为运行状态
客户端快速验证(在任一 K3s 节点)
sudo mkdir -p /mnt/nfs-sdcard-test
sudo mount -t nfs <armv7-ip>:/sdcard /mnt/nfs-sdcard-test
df -h | grep nfs-sdcard-test
ls -la /mnt/nfs-sdcard-test
若内网 DNS/主机名不可解析,请直接使用 armv7 的内网 IP(例如
192.168.2.22:/sdcard)。
验证完成后可卸载:
sudo umount /mnt/nfs-sdcard-test
本次实机验证记录(onecloud -> ylc61)
- 服务端(onecloud):
showmount -e localhost返回/sdcard 192.168.2.0/24exportfs -v显示/sdcard已按配置导出
- 客户端(ylc61):
mount -t nfs 192.168.2.22:/sdcard /mnt/nfs-sdcard-test成功- 可写入测试文件
.nfs_write_test umount /mnt/nfs-sdcard-test成功
NFS 安全验证与加固
先明确:默认 NFS 没有“用户名/密码登录”
当前这种 /etc/exports 用法(如 192.168.2.0/24(...))主要基于:
- 客户端来源 IP/网段控制
- UID/GID 映射(
root_squash/all_squash)
它不是“账号密码”或“密钥登录”模型。若需要强身份认证与加密,应使用 NFSv4 + Kerberos(见下文)。
基础安全加固(内网实用版)
先解释你关心的几个参数(核心差异):
no_root_squash:客户端 root 在服务端仍是 root(权限非常大,不推荐默认使用)。root_squash:客户端 root 会被压缩为匿名用户(更安全,推荐默认)。all_squash:不仅 root,连普通用户也统一映射为匿名用户(最“收敛”,但权限控制最粗)。
你说的“通常 NFS 只是数据目录,普通读写就够了”,这个判断是对的。
对大多数家庭实验室,优先root_squash即可,不必一上来no_root_squash。
推荐配置 A(默认推荐:保留普通用户语义,仅压缩 root)
echo "/sdcard 192.168.2.0/24(rw,sync,no_subtree_check,root_squash)" | sudo tee /etc/exports
sudo exportfs -rav
适用:一般数据目录读写场景,既降低 root 风险,又不过度收紧普通用户行为。
若切到 root_squash 后客户端出现 Permission denied,通常是导出目录权限还停留在 root:root。可在服务端先调整目录属主与权限(按你的风险接受度选择更细粒度权限):
sudo chown nobody:nogroup /sdcard
sudo chmod 0777 /sdcard
说明:这是“保证先可写”的快速做法。更严格场景建议用更小权限(例如按业务 UID/GID 精细授权),不要长期依赖
0777。
更小权限的实操示例(推荐)
多容器/多应用共享 NFS 时,不建议只改
/sdcard根目录权限;更推荐“根目录只做入口,每个应用单独子目录分权”。
示例:应用 A 用 UID/GID=1000,应用 B 用 UID/GID=1001。
# 1) 根目录:保守权限(可遍历,不建议直接 0777)
sudo chown root:root /sdcard
sudo chmod 0755 /sdcard
# 2) 应用A子目录
sudo mkdir -p /sdcard/app-a
sudo chown 1000:1000 /sdcard/app-a
sudo chmod 0770 /sdcard/app-a
# 3) 应用B子目录
sudo mkdir -p /sdcard/app-b
sudo chown 1001:1001 /sdcard/app-b
sudo chmod 0770 /sdcard/app-b
如果你选择 all_squash,再配合匿名映射到同一业务账号:
echo "/sdcard 192.168.2.0/24(rw,sync,no_subtree_check,root_squash,all_squash,anonuid=1000,anongid=1000)" | sudo tee /etc/exports
sudo exportfs -rav
验证(服务端):
sudo exportfs -v
ls -ldn /sdcard
ls -ldn /sdcard/app-a /sdcard/app-b
你应能看到:
exportfs -v中导出参数已是目标策略(如root_squash/all_squash,anonuid=1000)- 导出参数符合目标策略
- 各应用子目录的属主属组与业务 UID/GID 一致(如
app-a为1000:1000)
在 K8s Pod 侧,建议与之对应:
- 应用 A:
runAsUser/runAsGroup/fsGroup使用1000 - 应用 B:
runAsUser/runAsGroup/fsGroup使用1001
这样比把 /sdcard 全盘 0777 更可控:权限边界在“每个业务子目录”,不同应用互不踩权限。
推荐配置 B(更严格:所有用户都匿名)
echo "/sdcard 192.168.2.0/24(rw,sync,no_subtree_check,root_squash,all_squash,anonuid=65534,anongid=65534)" | sudo tee /etc/exports
sudo exportfs -rav
“所有用户都匿名”的含义与影响:
- 含义:客户端不论是 root 还是普通用户,服务端都按同一个匿名身份(通常
nobody:nogroup)处理。 - 影响:权限简单统一,但会丢失“按用户区分权限”的能力;某些应用可能因属主/权限不匹配而报错。
- 建议:仅在你明确要“统一身份写入”时启用。
不推荐长期保留(除非明确必须)
echo "/sdcard 192.168.2.0/24(rw,sync,no_subtree_check,no_root_squash)" | sudo tee /etc/exports
sudo exportfs -rav
no_root_squash 只建议临时排障或已做严格网络隔离时短期使用。
配套建议:
- 防火墙只放行必要客户端 IP(不要整段网段)
- NFS 服务只暴露在可信内网/VLAN
- 客户端挂载可加
nosuid,nodev,noexec(按业务兼容性评估)
安全验证命令(基础版)
# 服务端:确认导出参数
sudo exportfs -v
# 客户端:确认挂载参数
mount | grep nfs
核对点:
- 采用推荐配置 A/B 时,
exportfs -v中不应出现no_root_squash - 挂载后普通读写符合预期
- 若启用
all_squash,需额外确认应用对匿名 UID/GID 的权限兼容性
强认证路线(进阶):NFSv4 + Kerberos
如果你需要“身份认证/完整性/加密”而不是仅靠 IP 白名单:
- 使用
sec=krb5(认证) - 或
sec=krb5i(认证 + 完整性) - 或
sec=krb5p(认证 + 完整性 + 加密,安全最高)
这条路线需要额外建设 KDC、principal、keytab、时钟同步,复杂度明显高于内网基础版;家庭实验室通常先做“基础加固版”,再按需要升级。
与 K3s 对接(入口)
在 K3s 里使用 NFS,通常不需要先把 NFS 手工挂到每台节点主机。
详细做法(Pod 直挂 / PV+PVC)请见:03-06-k3s-使用nfs存储.md。
下一步
03-06-k3s-使用nfs存储.md