WordPress 上傳檔案到 Amazon S3 Bucket

為了評估AWS S3是否能取代EFS,曾研究過上傳檔案的一些方法...

1. 目的

Amazon EFS 雖有著較完整的檔案操作性(新增、修改、刪除),但是相較於 Amazon S3,少了 CloudFront(CDN) 的紅利、以及較貴的價格,所以嘗試看看是否能用 S3 來完全替代 EFS。

2. 評估方案

2.1. FUSE-based file system backed by Amazon S3

  • s3fs allows Linux, macOS, and FreeBSD to mount an S3 bucket via FUSE(Filesystem in Userspace).
  • s3fs makes you operate files and directories in S3 bucket like a local file system.
  • s3fs preserves the native object format for files, allowing use of other tools like AWS CLI.

2.2. Amazone S3 Mountpoint

  • Amazon S3 的 Mountpoint 刻意不實作檔案系統的完整 POSIX 標準規格。
  • 補充: 主機 mount 起來的目錄中只允許新增;不允許編輯、刪除。AWS 故意不給完整檔案操作的目的便是希望我們用EFS

2.3. WordPress plugin: WP Offload Media Lite

  • 此為採用 wordpress 外掛來處理的做法,Lite版有支援 IAM Role,但尚未評估限制

決定依據

  • 若只要讀,或者不需要編輯與刪除,Amazone S3 Mountpoint 會是最好的選擇
  • 若同時須要讀與寫,如果能克服安裝問題 s3fs 將會是較適合的解決辦法,否則只能改用 EFS
  • 價格比較
    alt AWS EBS, EFS, S3 的比較

3. 測試通過的環境

後面只會說明成功的安裝方式

EC2:

OS s3fs(IAM Role) s3fs(IAM User) Mountpoint plugin
Ubuntu 22.04 Fail註1 安裝 s3fs 過程失敗註2 Success Success
Amazon Linux 2 Success 註3 pass pass pass
註1: 以 apt-get 安裝的版本是 v1.90版但 mount 時跳出沒有權限的錯誤
註2: 重新打包 v1.85(相容問題失敗), v1.94(make 失敗,但沒有錯誤原因,也許是打包時記憶體不足的問題)
註3: s3fs 包含了新增、修改、刪除,因此,只要可用,其他的就不測試了

4. 建立一個 S3 bucket

aws 控制台 切到 S3 > 按鈕【建立儲存貯體】按下去 > 取好名字後其它都預設然後建立

測試建立的名稱為 toywe-store

5. 建立一個 IAM Role or IAM User?

5.1. 比較 IAM User 與 IAM Role 差異

  • IAM User 是透過 KEY ID 與 密鑰來存取資源的作法,這將使每台EC2 上的 aws configure 裡面都要留存 KEY ID 跟 密鑰
  • IAM Role 是比較新的概念,他可以直接掛在 EC2 上,避免掉其他設定

基於安全性以及設定上的複雜度,這邊採用 IAM Role 的作法,雖然此套件在這種作法上有些BUG,不過後面會說明解決辦法

5.2. 建立 IAM Role

aws 控制台切到 IAM > 角色 >

  • 建立角色
    • 信任的實體類型: 選擇 AWS服務
    • 使用案例: 選擇 EC2
  • 下一步
    • 許可政策: 選擇 AmazonS3FullAccess, mazonSSMManagedInstanceCore
  • 其它預設

    如果要目錄權限設定的更細,可以在這邊著墨

角色名稱 測試時建立的是 EC2-access-S3

6. 將 IAM Role 加入到 EC2

切到 EC2 找到要套用的 instance > 操作(或右鍵) > 安全 – IAM 角色將前面建立的 Role (EC2-access-S3) 加入

6.1. 測試 EC2 是否可連線到 S3

下面透過 EC2 上安裝的 AWS CLI 進行測試
aws s3 ls s://toywe-store

安裝 AWS CLI

sudo apt-get install awscli

7. Amazon S3 bucket 開放公有權限

主要參考這裡

簡要流程

  • 進入建立好的 bucket toywe-store > 許可
    • “封鎖公有存取權” > 編輯 > 取消勾選 “封鎖所有公開存取權”
    • “物件所有權” > 編輯 > 選 “ACL 已啟用” > 勾選 “我確認會還原ACL”
  • 單一檔案: 去指定的檔案 > 許可 > 編輯 > 勾選 每個人(公有存取) 的 讀取
  • 整個目錄: 建立一個目錄 > 在 物件 頁面勾選該目錄 > 動作下拉選 “使用ACL設為公有”

Tip

只對外開放讀取,修改刪除權限還是要有 IAM ROLE 的EC2 才能執行

8. 安裝 s3fs

8.1. On Ubuntu 環境

注意

截至目前 s3fs 在 Ubuntu 上的研究都失敗:

  1. 直接 apt-get 安裝 s3fs (v1.90) => mount 失敗(IAM ROLE 一直說沒權限)
  2. 透過 s3fs git 下載最新版 1.94 安裝 => mount 失敗(IAM ROLE 一直說沒權限)
  3. 透過 s3fs git 下載出問題前的版本 1.85 => 一堆相容問題,連 make 都完成不了(也可能是前面先裝新版導致降版遇到問題)

其他嘗試方向:

  • s3fs 改用 IAM USER 測試(IAM ROLE 安全性較高,所以非不得已,不用IAM USER)

測試當下,github s3fs-fuse v1.94 版,提供的 Ubuntu 安裝方式 sudo apt-get install s3fs 安裝後(版本為 v1.90)對於 IAM Role 支援度有問題,目前不確定是 Ubuntu 版本的安裝有問題,還是該版本有問題

依據網路上討論,認為 v1.85 後的版本 IAM Role有問題,所以下面會嘗試安裝 v1.85 的版本

8.1. On Amazon Linux 2 環境

安裝步驟

sudo su
amazon-linux-extras install epel
yum install s3fs-fuse
mkdir /mnt/s3
s3fs toywe-store /mnt/s3/ -o iam_role=auto,allow_other
df -h

參數

  • allow_other: 開放權限給除了 root 以外的帳號

9. 適用於 Amazone S3 的 Mountpoint【無法編輯、刪除】

9.1. 安裝 Mountpoint

限制

這樣 mount 進來的空間只能新增檔案、不能修改以及刪除檔案

建議直接參考參考 aws 文件若不行再看下面紀錄

9.1.1. 這邊是 Ubuntu (x86) 的安裝作法

下載 wget https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.rpm
Ubuntu 無法直接用 yum 安裝所以要用 alien
sudo apt install alien
將 rpm 轉為 deb
sudo alien -i mount-s3.rpm
原本還有下面這一道動作,但似乎自行完成了!?
sudo dpkg -i mount-s3.deb
驗證
mount-s3 --version

9.2. 將 S3 bucket mount 起來

sudo mount-s3 toywe-store /mnt/aws-s3

9.3. 修改目錄權限

這邊會有權限問題 要設成讓 nginx wordpress 可以用

10. 採用 WordPress 外掛 WP Offload Media Lite 的作法

參考教學課程:將 Lightsail 中的 WordPress 網站連接至 Amazon S3 儲存貯體

  • 安裝好後在左側導覽功能表中 , 選擇 Settings (設定),然後選擇 Offload Media (卸載媒體)。

  • 選擇 Amazon S3 作為供應商,選擇 My server is on Amazon Services and I’d like to use IAM Roles.(wp-config.php 裡面都不用改,因為 IAM Role 讓整台 EC2 已經有權限操作 S3)

  • Stograge Settings:

    • Offload Media: 勾選
    • Remove Local Media: 勾選,我們都保存在 S3裡,所以上傳成功後刪除主機上的檔案
    • Add Prefix to Bucket Path: 勾選,保持預設 wp-content/uploads/ 則會在 toywe-store 底下建立出 wp-content/uploads/
    • Add Year & Month Bucket Path: 勾選,避免檔案數量爆掉
    • Add Object Version to Bucket Path: 勾選,讓同檔名的檔案前面多一層時間戳的目錄

    提醒

    完成後去 S3 將 wp-content 或是 wp-content/uploads/ 目錄設為 “使用ACL設為公有” 將目錄開放出去,上傳的檔案,外面才看的到

結論

  • 如果要使用 AWS 的服務 EC2 選擇 Amazon linux 2,相容性相對較高,可以避免掉其他作業系統支援度不足的問題。
  • 在可以使用 s3fs 的前提下,或許可以考慮完全用 EFS 取代 S3,但實際運用是否會有其他問題仍需觀察。
  • WordPress 目前作法有二
    • 官方: EFS 用來存放 wordpress 整個目錄,配合外掛將上傳檔案放到S3上
    • 我的想法: 直接將 wordpress 放 S3,上傳就在 S3 中,連外掛都省了,但對於目錄檔案權限的設定需要研究一下

11. Reference

12. 延伸