ลดความยุ่งยากในการใช้คลาวด์ พูดคุยกับเจ้าหน้าที่

แชร์ไฟล์ระหว่างเซิร์ฟเวอร์ Linux ด้วย NFS
Home แชร์ไฟล์ระหว่างเซิร์ฟเวอร์ Linux ด้วย NFS

แชร์ไฟล์ระหว่างเซิร์ฟเวอร์ Linux ด้วย NFS

เมื่อมีเว็บเซิร์ฟเวอร์หลายเครื่องให้บริการเว็บเดียวกัน ไฟล์ที่ผู้ใช้อัปโหลดต้องอยู่ที่เดียวและทุกเครื่องเห็นเหมือนกัน ไม่เช่นนั้นผู้ใช้จะเห็นรูปบ้างไม่เห็นบ้างขึ้นอยู่กับว่าถูกส่งไปเครื่องไหน NFS คือวิธีมาตรฐานของ Linux สำหรับงานนี้

คู่มือนี้ตั้ง NFS Server หนึ่งเครื่องและเมานต์จากเครื่องอื่น พร้อมอธิบายตัวเลือกที่มีผลจริงต่อความเร็วและความปลอดภัย และวิธีเมานต์ที่ไม่ทำให้เครื่องบูตค้างเมื่อ NFS Server ไม่อยู่

สิ่งที่ต้องเตรียม

  • เซิร์ฟเวอร์สองเครื่องขึ้นไปที่อยู่ในเครือข่ายภายในเดียวกัน
  • สิทธิ์ sudo ทั้งสองฝั่ง

ข้อควรรู้ก่อนเริ่ม NFS ไม่มีการเข้ารหัสและยืนยันตัวตนด้วย IP เป็นหลัก จึงต้องใช้เฉพาะในเครือข่ายภายในที่ควบคุมได้เท่านั้น อย่าเปิดสู่อินเทอร์เน็ตเด็ดขาด

ขั้นตอนที่ 1: ติดตั้งฝั่ง Server

# Ubuntu / Debian
sudo apt install -y nfs-kernel-server

# AlmaLinux / Rocky Linux
sudo dnf install -y nfs-utils
sudo systemctl enable --now nfs-server

สร้างโฟลเดอร์ที่จะแชร์

sudo mkdir -p /srv/shared/uploads
sudo chown www-data:www-data /srv/shared/uploads
sudo chmod 2775 /srv/shared/uploads

บิต 2 ข้างหน้าคือ setgid ทำให้ไฟล์ที่สร้างใหม่ในโฟลเดอร์นี้สืบทอดกลุ่มเดียวกัน ซึ่งช่วยลดปัญหาสิทธิ์เมื่อมีหลายเครื่องเขียนพร้อมกัน

ขั้นตอนที่ 2: ประกาศว่าจะแชร์ให้ใคร

sudo nano /etc/exports
/srv/shared/uploads  10.0.0.11(rw,sync,no_subtree_check)
/srv/shared/uploads  10.0.0.12(rw,sync,no_subtree_check)

# หรือทั้งวง
# /srv/shared/uploads  10.0.0.0/24(rw,sync,no_subtree_check)

ความหมายของตัวเลือกที่สำคัญ

  • rw ให้เขียนได้ ใช้ ro หากต้องการให้อ่านอย่างเดียว
  • sync ยืนยันการเขียนลงดิสก์จริงก่อนตอบกลับ ช้ากว่า async แต่ปลอดภัยกว่ามากเมื่อไฟดับ อย่าใช้ async กับข้อมูลสำคัญ
  • no_subtree_check ลดปัญหาความน่าเชื่อถือเมื่อไฟล์ถูกเปลี่ยนชื่อ และเป็นค่าที่แนะนำในปัจจุบัน
  • root_squash เป็นค่าเริ่มต้นที่ไม่ต้องใส่ มันแปลง root ของเครื่องลูกให้กลายเป็นผู้ใช้ไร้สิทธิ์ ป้องกันไม่ให้ root จากเครื่องอื่นมีอำนาจเต็มบนไฟล์ที่แชร์ อย่าปิดด้วย no_root_squash เว้นแต่จำเป็นจริง ๆ
sudo exportfs -ra
sudo exportfs -v

ขั้นตอนที่ 3: เปิด Firewall เฉพาะวงภายใน

# Ubuntu
sudo ufw allow from 10.0.0.0/24 to any port nfs

# AlmaLinux / Rocky
sudo firewall-cmd --permanent --add-service=nfs
sudo firewall-cmd --permanent --add-service=rpc-bind
sudo firewall-cmd --permanent --add-service=mountd
sudo firewall-cmd --reload

ขั้นตอนที่ 4: เมานต์จากเครื่องลูก

# Ubuntu / Debian
sudo apt install -y nfs-common

# AlmaLinux / Rocky Linux
sudo dnf install -y nfs-utils

ดูว่าเซิร์ฟเวอร์แชร์อะไรไว้บ้าง

showmount -e 10.0.0.9

ทดลองเมานต์

sudo mkdir -p /mnt/uploads
sudo mount -t nfs 10.0.0.9:/srv/shared/uploads /mnt/uploads
df -hT | grep nfs
touch /mnt/uploads/test.txt && ls -l /mnt/uploads/

ขั้นตอนที่ 5: เมานต์ถาวรโดยไม่ทำให้บูตค้าง

นี่คือจุดที่พลาดกันบ่อย ถ้าใส่ใน /etc/fstab แบบธรรมดา แล้ววันหนึ่ง NFS Server ไม่อยู่ เครื่องลูกจะบูตค้างรอจนหมดเวลา

sudo nano /etc/fstab
10.0.0.9:/srv/shared/uploads  /mnt/uploads  nfs  defaults,_netdev,nofail,soft,timeo=30,retrans=3,noatime  0  0

ตัวเลือกที่ป้องกันปัญหา

  • _netdev บอกว่าต้องรอเครือข่ายพร้อมก่อน
  • nofail ถ้าเมานต์ไม่สำเร็จให้บูตต่อไป ไม่ต้องหยุดรอ
  • soft ถ้าเซิร์ฟเวอร์ไม่ตอบ ให้คืนค่าผิดพลาดแทนที่จะค้างตลอดไป เหมาะกับงานเว็บ ส่วน hard เหมาะกับข้อมูลที่ห้ามสูญหาย
  • noatime ไม่ต้องเขียนเวลาที่เข้าถึงไฟล์กลับไป ลดทราฟฟิกได้มาก
sudo mount -a
mount | grep nfs

ขั้นตอนที่ 6: ทางเลือกที่ยืดหยุ่นกว่าด้วย autofs

autofs เมานต์ให้เมื่อมีการเข้าใช้จริง และถอดออกเองเมื่อไม่ได้ใช้ เหมาะเมื่อเครื่องลูกไม่จำเป็นต้องต่ออยู่ตลอด

sudo apt install -y autofs
sudo nano /etc/auto.master.d/nfs.autofs
/mnt/nfs  /etc/auto.nfs  --timeout=60
sudo nano /etc/auto.nfs
uploads  -fstype=nfs,rw,soft,timeo=30  10.0.0.9:/srv/shared/uploads
sudo systemctl restart autofs
ls /mnt/nfs/uploads

ขั้นตอนที่ 7: แก้เรื่องสิทธิ์ให้ตรงกันทุกเครื่อง

NFS ส่งสิทธิ์เป็นตัวเลข UID และ GID ไม่ใช่ชื่อผู้ใช้ ถ้าผู้ใช้ www-data มี UID 33 บนเครื่องหนึ่งแต่เป็น 1001 บนอีกเครื่อง ไฟล์จะแสดงเจ้าของผิดและเขียนไม่ได้

id www-data

ถ้าไม่ตรงกัน แก้ให้ตรงบนเครื่องที่ยังไม่มีข้อมูลสำคัญ

sudo usermod -u 33 www-data
sudo groupmod -g 33 www-data
sudo find /var/www -user 1001 -exec chown 33 {} \;

อีกทางคือบังคับ UID จากฝั่ง Server ด้วยตัวเลือกใน exports

/srv/shared/uploads  10.0.0.0/24(rw,sync,no_subtree_check,all_squash,anonuid=33,anongid=33)

วิธีนี้ทำให้ทุกคนที่เขียนเข้ามากลายเป็น UID 33 เสมอ เรียบง่ายและตัดปัญหาเรื่อง UID ไม่ตรงได้ทั้งหมด

ปัญหาที่พบบ่อย

mount ขึ้น access denied by server

IP ของเครื่องลูกไม่ตรงกับที่ประกาศใน /etc/exports ตรวจด้วย sudo exportfs -v บนเซิร์ฟเวอร์ และอย่าลืมสั่ง sudo exportfs -ra หลังแก้ไฟล์

เขียนไฟล์ไม่ได้ทั้งที่ประกาศ rw

ตรวจสองชั้น ชั้นแรกคือสิทธิ์ของโฟลเดอร์บนเครื่อง Server เอง ชั้นที่สองคือ UID ที่ไม่ตรงกันตามขั้นตอนที่ 7 และตรวจว่า root_squash กำลังแปลง root ของคุณเป็นผู้ใช้ไร้สิทธิ์อยู่

เครื่องลูกค้างเมื่อ NFS Server ดับ

ใช้ตัวเลือก soft ร่วมกับ timeo และ nofail หากค้างอยู่แล้วให้ถอดแบบบังคับด้วย sudo umount -f -l /mnt/uploads

ช้ากว่าที่คาด

ตรวจว่าใช้ NFSv4 อยู่ด้วย mount | grep nfs และเพิ่มขนาดบล็อกด้วย rsize=1048576,wsize=1048576 สำหรับไฟล์ขนาดเล็กจำนวนมาก NFS จะช้าโดยธรรมชาติ พิจารณาใช้ Object Storage แทนหากเป็นไฟล์ที่ผู้ใช้อัปโหลด

ต้องการวางโครงสร้างจัดเก็บไฟล์ร่วมกันหลายเครื่อง ติดต่อ THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/

ผู้ให้บริการคลาวด์ไทย
เพื่อธุรกิจของคนไทย

"มุ่งมั่น" และ "มั่นคง"
พร้อมรับมือทุกการเติบโต
Trust Cloud
คลาว์ที่ปลอดภัย
คือรากฐานที่มั่นคง
cloud security