การ Mount S3 บนเซิฟเวอร์ Ubuntu EC2 ด้วย s3fs-fuse

การ Mount S3 บนเซิฟเวอร์นี้เป็นการทำให้ Bucket บน Amazon S3 สามารถเข้าถึงได้เสมือนหนึ่งเป็นไดรฟ์หรือโฟลเดอร์หนึ่งในเครื่อง มีประโยชน์หลายอย่าง เช่น หากมีโปรแกรมที่ต้องใช้ไฟล์จาก filesystem ก็จะสามารถเรียกใช้ไฟล์ได้เลยโดยไม่ต้องเขียนโปรแกรมเพื่อไปเชื่อมต่อกับ S3 โดยเฉพาะ หรือใช้ในการรันสคริปเพื่อเก็บข้อมูลไฟล์แบ็คอัพแบบง่ายๆ เป็นต้น

ลงโปรแกรมบนเซิฟเวอร์

เริ่มต้นจากการเตรียมความพร้อมของเซิฟเวอร์ ด้วยการลง s3fs และ aws cli ดังนี้

sudo apt-get update
sudo apt install s3fs awscli -y

เมื่อลงแล้วให้ลองรันคำสั่ง which ดูว่า s3fs ลงเรียบร้อยดีไหม

which s3fs

# หากเรียบร้อยจะแสดงผลว่า path ของ s3f3 อยู่ที่
# /usr/bin/s3fs

ตั้งค่า IAM User และอนุญาตให้เข้าถึง S3 Bucket ได้

การจะเข้าถึงข้อมูลใน S3 Bucket ได้นั้น จะต้องมี IAM user ที่ได้รับอนุญาตให้เข้าถึง bucket ดังกล่าวได้ก่อน จึงต้องเตรียม user ดังนี้

1. ไปที่ https://console.aws.amazon.com/iam/home?#/users แล้วกดปุ่ม Add User

2. กำหนดชื่อผู้ใช้งาน และ access type เป็น “Programmatic access”

3. กำหนด Permission เป็น S3FullAccess

4. กำหนด tag เพื่อให้สามารถดูได้ง่ายกว่า user นี้สำหรับใช้ทำอะไร และรีวิวดูข้อมูลอีกครั้ง ก่อนทำการ Create user

5. เมื่อสร้างผู้ใช้งานเรียบร้อยแล้ว จะปรากฎข้อมูล access key และ secret ขึ้นมา สำหรับนำไปใช้งานต่อไป

สร้างไฟล์ Credentials สำหรับ s3fs บนเซิฟเวอร์

เมื่อเรามี user credential แล้ว ก็จะนำ Access Key ID และ Secret access key มาบันทึกเป็นไฟล์ไว้บนเซิฟเวอร์ เพื่อให้ s3fs เรียกใช้ต่อไป โดยสร้างไฟล์ credential โดยมีข้อมูล access key และ secret ที่ได้จากการสร้าง user ก่อนหน้านี้ โดยรันคำสั่งดังนี้

echo ACCESS_KEY_ID:SECRET_ACCESS_KEY > /home/ubuntu/.s3fs-creds

chmod 600 /home/ubuntu/.s3fs-creds

ทำการ Mount bucket ไปยัง File system

ในขั้นนี้ หากยังไม่มี Bucket ที่ต้องการใช้งาน จะต้องไปทำการสร้าง s3 bucket ใหม่ขึ้นมาก่อน ที่ https://s3.console.aws.amazon.com/s3/home

สร้างโฟลเดอร์ที่ต้องการ mount โดยรัน

mkdir /home/ubuntu/s3-demo-bucket-2021

จากนั้นทำการ mount โดยใช้คำสั่ง

s3fs S3_BUCKET_NAME /home/ubuntu/s3-demo-bucket-2021 \
  -o use_path_request_style  \
  -o passwd_file=/home/ubuntu/.s3fs-creds,nonempty \
  -o url=http://s3-ap-southeast-1.amazonaws.com \
  -o endpoint=ap-southeast-1  

* หากใช้ AWS region อื่นนอกเหนือจาก ap-southeast-1 จะต้องเปลี่ยน region url และ endpoint ทั้งหมดให้เป็นตาม region ที่ใช้จริงด้วย

จากนั้นสามารถลองทดสองโดยการเพิ่มไฟล์ลงไปยังโฟลเดอร์ที่ mount แล้วรีเฟรชดูใน Amazon s3 console ว่ามีไฟล์เพิ่มมาหรือไม่ หรือลองอัพโหลดไฟล์ไปยัง bucket จากหน้า console แล้วลองเรียกดูจากในเซิฟเวอร์ว่ามีไฟล์ดังกล่าวปรากฎหรือไม่

หากต้องการยกเลิกการ mount สามารถทำได้ด้วยคำสั่ง

sudo umount s3-demo-bucket-2021

ตั้งให้ทำการ Mount ทุกครั้งที่รีสตาร์ทเครื่อง

การ mount นี้จะยังอยู่เมื่อเปิดเครื่องอยู่เท่านั้น หากมีการปิดเครื่องหรือรีสตาร์ท โฟลเดอร์ที่ทำการ mount ไว้นี้จะหายไป หากต้องการให้เซิฟเวอร์ทำการ mount อัตโนมัติเมื่อเปิดเครื่องนั้นสามารถทำได้หลายวิธี แต่ในที่นี้จะทำโดยการสร้างให้เป็น systemd service ซึ่งนอกเหนือจะทำให้ mount อัตโนมัติเมื่อเปิดเครื่องแล้ว ยังสามารถสั่ง start, stop ได้ด้วย ดังนี้

สร้างไฟล์ bucket-mount.service ไปยังโฟลเดอร์ /usr/lib/systemd/system โดยรันคำสั่ง

sudo vi /usr/lib/systemd/system/bucket-mount.service

และตั้งค่าในไฟล์ โดยมีข้อสังเกตคือ

  • เราสั่งให้รันหลังจากที่ Network ทำงานได้เรียบร้อยแล้ว (After=network-online.target)
  • User หากต้องการรันด้วย user อื่นต้องเปลี่ยนเป็น user ที่จะใช้งานจริง
  • คำสั่งในหัวข้อ ExecStart เป็นคำสั่งเดียวกับที่เราใช้รันเทส (เปลี่ยน s3fs ให้เป็น Fullpath)
  • คำสั่ง ExecStop ต้องกำหนดชื่อโฟลเดอร์ที่ mount ให้ถูกต้อง
[Unit]
Description = Mount S3 Bucket
Wants=network-online.target
After=network.target network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
User=ubuntu
ExecStart =/usr/bin/s3fs s3-demo-bucket-2021 /home/ubuntu/s3-demo-bucket-2021 -o use_path_request_style  -o passwd_file=/home/ubuntu/.s3fs-creds,nonempty -o url=http://s3-ap-southeast-1.amazonaws.com -o endpoint=ap-southeast-1  
ExecStop=/bin/umount /home/ubuntu/s3-demo-bucket-2021

[Install]
WantedBy = multi-user.target

เมื่อสร้างและบันทึกไฟล์แล้ว สามารถเปิดการใช้งาน service ที่เราสร้างขึ้นมาได้โดยรันคำสั่ง

sudo systemctl enable bucket-mount

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

sudo systemctl status bucket-mount

นอกจากนี้ เรายังสามารถสั่ง mount/unmount ได้ด้วยการรัน systemctl ดังนี้

sudo systemctl start bucket-mount

sudo systemctl stop bucket-mount

sudo systemctl restart bucket-mount