Logo

Personal Ops Runbook

Personal runbook covering infrastructure operations for Cloud, Kubernetes, OpenStack, and Ceph environments. Includes deployment and teardown procedures, node management, cluster monitoring setup, and incident response workflows compiled from day-to-day operational work. Intended strictly for personal reference — configurations and scripts are environment-specific and not guaranteed to work as-is elsewhere.

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.