Phase 0 — Biến môi trường + kiểm tra SSH
cat > /root/lab.env <<'EOF'
export MDS=10.237.7.31
export OSS1=10.237.7.32
export OSS2=10.237.7.33
export CA=10.237.7.34
export CB=10.237.7.35
export SERVERS="10.237.7.31 10.237.7.32 10.237.7.33"
export CLIENTS="10.237.7.34 10.237.7.35"
export ALL="10.237.7.31 10.237.7.32 10.237.7.33 10.237.7.34 10.237.7.35"
export PROXY=http://10.237.7.250:3128
EOF
source /root/lab.env
for n in $ALL; do ssh -o StrictHostKeyChecking=accept-new root@$n hostname; done
5 hostname hiện ra là SSH ok. (Mỗi lần mở session mới, nhớ source /root/lab.env trước.)
Phase 1 — Cấu hình nền cho cả 5 node (hosts, proxy, firewall, SELinux)
source /root/lab.env
for n in $ALL; do ssh root@$n "bash -s" <<EOF
grep -q lustre-lab /etc/hosts || cat >> /etc/hosts <<HOSTS
# lustre-lab
10.237.7.31 mds01
10.237.7.32 oss01
10.237.7.33 oss02
10.237.7.34 client-a1
10.237.7.35 client-b1
HOSTS
grep -q '^proxy=' /etc/dnf/dnf.conf || echo "proxy=$PROXY" >> /etc/dnf/dnf.conf
systemctl disable --now firewalld 2>/dev/null || true
setenforce 0 2>/dev/null || true
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
echo "== \$(hostname) OK =="
EOF
done
Phase 2 — Repo Whamcloud trên 3 node server
for n in $SERVERS; do ssh root@$n "bash -s" <<'EOF'
cat > /etc/yum.repos.d/lustre.repo <<'REPO'
[lustre-server]
name=lustre-server
baseurl=https://downloads.whamcloud.com/public/lustre/lustre-2.15.8/el9.7/server
exclude=*debuginfo*
gpgcheck=0
enabled=1
[e2fsprogs-wc]
name=e2fsprogs-wc
baseurl=https://downloads.whamcloud.com/public/e2fsprogs/latest/el9
gpgcheck=0
enabled=1
REPO
dnf clean all -q && dnf makecache -q && echo "== $(hostname) repo OK =="
EOF
done
Nếu makecache lỗi ở đây là do proxy — kiểm tra lại dòng proxy= trong /etc/dnf/dnf.conf trước khi đi tiếp.
Phase 3 — Cài e2fsprogs + kernel Lustre trên 3 server, rồi reboot
for n in $SERVERS; do ssh root@$n "bash -s" <<'EOF'
dnf -y upgrade e2fsprogs
LK=$(dnf -q repoquery kernel --disablerepo='*' --enablerepo=lustre-server --qf '%{version}-%{release}' | sort -V | tail -1)
echo "== $(hostname): cai kernel $LK =="
dnf -y install --enablerepo=lustre-server kernel-$LK kernel-core-$LK kernel-modules-$LK kernel-modules-core-$LK
grubby --set-default /boot/vmlinuz-${LK}.x86_64
EOF
done
for n in $SERVERS; do ssh root@$n reboot; done
Đợi 1–2 phút cho 3 node lên lại, rồi xác nhận kernel — cả 3 dòng phải có chữ _lustre, chưa có thì đừng đi tiếp:
for n in $SERVERS; do echo -n "$n: "; ssh root@$n uname -r; done
Phase 4 — Cài gói Lustre server + khóa kernel
for n in $SERVERS; do ssh root@$n "bash -s" <<'EOF'
uname -r | grep -q _lustre || { echo "!! $(hostname) SAI KERNEL, DUNG LAI"; exit 1; }
dnf -y install kmod-lustre kmod-lustre-osd-ldiskfs lustre-osd-ldiskfs-mount lustre
grep -q '^exclude=kernel' /etc/dnf/dnf.conf || echo 'exclude=kernel*' >> /etc/dnf/dnf.conf
echo "== $(hostname) lustre server OK =="
EOF
done
Phase 5 — Cấu hình LNet trên 3 server
for n in $SERVERS; do ssh root@$n "bash -s" <<'EOF'
IFACE=$(ip -o route get 10.237.7.250 | sed -n 's/.* dev \([^ ]*\).*/\1/p')
echo "options lnet networks=tcp0($IFACE)" > /etc/modprobe.d/lustre.conf
modprobe lustre
lctl network up >/dev/null
echo -n "$(hostname) NID: "; lctl list_nids
EOF
done
Kết quả mong đợi: mỗi node in ra NID dạng 10.237.7.3x@tcp — đây chính là "danh tính" mà phần multi-tenant sẽ dùng.
Phase 6 — Format và mount MGT/MDT/OST
Kiểm tra tên disk trước (block dưới đang giả định OS là disk đầu, 2 disk thêm là sdb/sdc — nếu môi trường bạn là vdb/vdc thì sửa 2 biến đầu mỗi block):
for n in $SERVERS; do echo "== $n =="; ssh root@$n "lsblk -dno NAME,SIZE,TYPE"; done
Format + mount (filesystem tên lab):
ssh root@$MDS "bash -s" <<'EOF'
MGT=/dev/sdb; MDT=/dev/sdc
mkfs.lustre --mgs --reformat $MGT
mkfs.lustre --fsname=lab --mgsnode=10.237.7.31@tcp0 --mdt --index=0 --reformat $MDT
mkdir -p /mnt/mgt /mnt/mdt0
mount -t lustre $MGT /mnt/mgt
mount -t lustre $MDT /mnt/mdt0
df -hT | grep lustre
EOF
ssh root@$OSS1 "bash -s" <<'EOF'
D1=/dev/sdb; D2=/dev/sdc
mkfs.lustre --fsname=lab --mgsnode=10.237.7.31@tcp0 --ost --index=0 --reformat $D1
mkfs.lustre --fsname=lab --mgsnode=10.237.7.31@tcp0 --ost --index=1 --reformat $D2
mkdir -p /mnt/ost0 /mnt/ost1
mount -t lustre $D1 /mnt/ost0
mount -t lustre $D2 /mnt/ost1
df -hT | grep lustre
EOF
ssh root@$OSS2 "bash -s" <<'EOF'
D1=/dev/sdb; D2=/dev/sdc
mkfs.lustre --fsname=lab --mgsnode=10.237.7.31@tcp0 --ost --index=2 --reformat $D1
mkfs.lustre --fsname=lab --mgsnode=10.237.7.31@tcp0 --ost --index=3 --reformat $D2
mkdir -p /mnt/ost2 /mnt/ost3
mount -t lustre $D1 /mnt/ost2
mount -t lustre $D2 /mnt/ost3
df -hT | grep lustre
EOF
Phase 7 — Cài client (DKMS, không cần đổi kernel)
Bước này build module theo kernel 9.8 đang chạy nên mất vài phút mỗi node, đừng sốt ruột:
for n in $CLIENTS; do ssh root@$n "bash -s" <<'EOF'
dnf -y install epel-release
dnf -y install "kernel-devel-$(uname -r)" gcc make automake autoconf libtool flex bison dkms keyutils libyaml libmount elfutils-libelf-devel
cat > /etc/yum.repos.d/lustre-client.repo <<'REPO'
[lustre-client]
name=lustre-client
baseurl=https://downloads.whamcloud.com/public/lustre/lustre-2.15.8/el9.7/client
exclude=*debuginfo*
gpgcheck=0
enabled=1
REPO
dnf -y install lustre-client-dkms lustre-client
IFACE=$(ip -o route get 10.237.7.31 | sed -n 's/.* dev \([^ ]*\).*/\1/p')
echo "options lnet networks=tcp0($IFACE)" > /etc/modprobe.d/lustre.conf
modprobe lustre && echo -n "$(hostname) NID: " && lctl list_nids
EOF
done
Nếu DKMS build fail trên kernel 9.8 (hiếm nhưng có thể do kernel mới hơn bản Lustre hỗ trợ), gửi tôi log /var/lib/dkms/lustre-client/*/build/make.log — có phương án fallback, đừng tự sửa.
Phase 8 — Mount client + smoke test stripe
for n in $CLIENTS; do ssh root@$n "mkdir -p /lab && mount -t lustre 10.237.7.31@tcp0:/lab /lab && df -h /lab"; done
ssh root@$CA "bash -s" <<'EOF'
lfs df -h
dd if=/dev/zero of=/lab/smoke.bin bs=1M count=256 oflag=direct
lfs getstripe /lab/smoke.bin
rm -f /lab/smoke.bin
EOF
lfs df -h phải liệt kê đủ 4 OST. Đến đây filesystem đã sống.
Phase 9 — Multi-tenant: fileset + nodemap + root squash + project quota
Bật quota và chuẩn bị thư mục tenant (làm trước khi kích hoạt nodemap, vì lúc này client còn full quyền):
ssh root@$MDS "lctl conf_param lab.quota.mdt=ugp && lctl conf_param lab.quota.ost=ugp"
ssh root@$CA "bash -s" <<'EOF'
mkdir -p /lab/tenant-a /lab/tenant-b
chown 1000:1000 /lab/tenant-a
chown 2000:2000 /lab/tenant-b
lfs project -s -p 101 -r /lab/tenant-a
lfs project -s -p 102 -r /lab/tenant-b
lfs setquota -p 101 -B 20G -I 100000 /lab
lfs setquota -p 102 -B 20G -I 100000 /lab
EOF
Tạo nodemap trên MGS (mds01) — tenant nhận diện theo NID, root bị squash, mỗi tenant bị nhốt vào fileset của mình:
lctl nodemap_add tenant-a
lctl nodemap_add_range --name tenant-a --range 10.237.7.34@tcp
lctl nodemap_modify --name tenant-a --property admin --value 0
lctl nodemap_modify --name tenant-a --property trusted --value 1
lctl nodemap_set_fileset --name tenant-a --fileset /tenant-a
lctl nodemap_add tenant-b
lctl nodemap_add_range --name tenant-b --range 10.237.7.35@tcp
lctl nodemap_modify --name tenant-b --property admin --value 0
lctl nodemap_modify --name tenant-b --property trusted --value 1
lctl nodemap_set_fileset --name tenant-b --fileset /tenant-b
lctl nodemap_activate 1
sleep 20
lctl get_param nodemap.tenant-a.* nodemap.tenant-b.* | head -40
(sleep 20 để config đồng bộ từ MGS xuống MDS/OSS.) Remount client để ăn fileset:
for n in $CLIENTS; do ssh root@$n "umount /lab && mount -t lustre 10.237.7.31@tcp0:/lab /lab"; done
Kiểm chứng cách ly:
ssh root@$CA "ls -la /lab; touch /lab/hello-from-a; ls -ln /lab/hello-from-a"
ssh root@$CB "ls -la /lab; touch /lab/hello-from-b; ls -ln /lab/hello-from-b"
Kết quả đúng phải là: client-a1 mount /lab nhưng thực chất chỉ thấy nội dung tenant-a (không hề thấy tenant-b tồn tại), client-b1 ngược lại; và file do root client tạo ra hiện owner UID 99 (nobody) — chứng minh root squash hoạt động. Quota xem bằng lfs quota -p 101 /lab (chạy từ node có quyền, ví dụ mount tạm trên mds01 hoặc trước khi squash).
Hai lưu ý vận hành: sau này nếu reboot cả cụm, thứ tự mount là MGT → MDT → OST → client; và các mount hiện là thủ công (chưa ghi fstab) — cố ý để bạn tập thao tác, khi nào ổn tôi đưa systemd mount unit sau. Chạy đến đâu vướng ở phase nào, paste nguyên output lỗi cho tôi.