mountpoint-s3とは、S3バケットをローカルのファイルシステムとしてマウントすることができる、ファイルクライアントです。
今回は、mountpoint-s3の使い方や挙動を、Wordpressの静的コンテンツの同期で確認していみたいと思います。

WordPressの冗長化問題

WordPressをALBで冗長化する場合、画像などの静的コンテツが正しく表示されない問題が発生します。
複数のEC2インスタンスでWordpressを構築すると、ALBでリクエストが複数のEC2へ分散されます。
記事情報はRDS等の外部DBに保存されるため、正しく表示されますが、静的コンテンツは記事の編集を行ったEC2内部に保存されるため、残りのEC2では正しく静的コンテンツが表示されません。
この問題を解決するために、外部ストレージへ静的コンテンツを保存するプラグインや、rsyncなどでEC2間のファイル同期が必要になります。

WordPressの構築

WordPressの冗長化問題を解決するために、mountpoint-s3を使ってファイル同期を行います。

S3バケットとIAMロールの作成

mountpoint-s3 で接続するS3バケットを作成します。
パブリック公開設定等はせず、デフォルトの状態です。

EC2からアクセスできるよう、下記IAMロールを作成しアタッチします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "MountpointFullBucketAccess",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::nakatani-wp-test"
            ]
        },
        {
            "Sid": "MountpointFullObjectAccess",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:AbortMultipartUpload",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::nakatani-wp-test/*"
            ]
        }
    ]
}

WordPressのセットアップ

冗長化のため、EC2とRDSを作成します。
標準的なWordpressのセットアップのため、本手順では割愛します。
Wordpressのセットアップが終わった後、AMIからEC2インスタンスを複製します。

ALBの作成

wordpressの設定画面へのリクエストを特定のEC2インスタンスのみにするため、n-nakatani-adminn-nakataniの2つのターゲットグループを作成します。
n-nakatani-adminにはEC2を1台のみアタッチし、n-nakataniには全てのEC2インスタンスをアタッチします。

ALBのリスナールールを、下記のように設定します。

  • パスパターンが「/wp-admin/」と「/wp-login.php」の時
    • n-nakatani-admin ターゲットグループへ転送
  • デフォルト
    • n-nakatani ターゲットグループへ転送

これで、wordpressの設定画面は1つのEC2へリクエストされるようになりました。

WordPress冗長化問題の検証

現在の構成では静的コンテンツが同期されないため、画像などが正しく表示されない現象が発生します。

画像を付けた記事を投稿を投稿するが、

ALBの接続先によって画像が表示されない。

画像が1号機のみ保存されている。

# 1号機
[root@ip-10-0-4-199 uploads]# pwd
/var/www/wordpress/wp-content/uploads
[root@ip-10-0-4-199 uploads]# ll
total 0
drwxr-xr-x. 3 apache apache 16 Aug 18 06:08 2023
[root@ip-10-0-4-199 uploads]#

# 2号機
[root@ip-10-0-17-31 uploads]# pwd
/var/www/wordpress/wp-content/uploads
[root@ip-10-0-17-31 uploads]# ll
total 0

S3マウントを設定

上記問題を解決するため、S3マウントを設定します。
公式のgithubの手順でmountpoint-s3をインストールします。

[root@ip-10-0-4-199 ~]# wget https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.rpm
(省略)
Saving to: ‘mount-s3.rpm’

mount-s3.rpm                                    100%[====================================================================================================>]   9.95M  5.42MB/s    in 1.8s

2023-08-18 06:19:38 (5.42 MB/s) - ‘mount-s3.rpm’ saved [10432224/10432224]

[root@ip-10-0-4-199 ~]# ll
total 10188
-rw-r--r--. 1 root root 10432224 Aug  8 15:41 mount-s3.rpm
[root@ip-10-0-4-199 ~]# yum install -y ./mount-s3.rpm
(省略)

Installed:
  fuse-2.9.9-13.amzn2023.0.2.x86_64                              fuse-common-3.10.4-1.amzn2023.0.2.x86_64                              mount-s3-1.0.0-1.x86_64

Complete!
[root@ip-10-0-4-199 ~]#

インストールが完了したら、S3バケットをマウントします。
マウント先は、Wordpressの静的コンテンツが保存されるディレクトリにします。

[root@ip-10-0-4-199 ~]# mount-s3 --uid 48 --gid 48 --allow-delete --allow-other nakatani-wp-test /var/www/wordpress/wp-content/uploads/
bucket nakatani-wp-test is mounted at /var/www/wordpress/wp-content/uploads/
[root@ip-10-0-4-199 ~]#

デフォルトでは、マウントをしたユーザのみが読み書き可能ですが、オプションで任意のパーミッションを設定することが可能です。
オプションを指定しないと、下記のようにエラーが発生します。

[Fri Aug 18 04:53:51.270869 2023] [core:notice] [pid 26134:tid 26134] AH00094: Command line: '/usr/sbin/httpd -D FOREGROUND'
[Fri Aug 18 06:56:11.829411 2023] [core:error] [pid 26469:tid 26517] (13)Permission denied: [client 10.0.31.179:17650] AH00035: access to /wp-content/uploads/2023/08/computer_tokui_boy.pngdenied (filesystem path '/var/www/wordpress/wp-content/uploads') because search permissions are missing on a component of the path, referer: http://n-nakatani-539518340.ap-northeast-1.elb.amazonaws.com/wp-admin/post.php?post=18&action=edit
[Fri Aug 18 06:56:16.509352 2023] [core:error] [pid 26469:tid 26513] (13)Permission denied: [client 10.0.31.179:17650] AH00035: access to /wp-content/uploads/2023/08/computer_tokui_boy.pngdenied (filesystem path '/var/www/wordpress/wp-content/uploads') because search permissions are missing on a component of the path, referer: http://n-nakatani-539518340.ap-northeast-1.elb.amazonaws.com/wp-admin/post.php?post=18&action=edit
[Fri Aug 18 06:56:17.845997 2023] [core:error] [pid 26469:tid 26511] (13)Permission denied: [client 10.0.31.179:17650] AH00035: access to /wp-content/uploads/2023/08/computer_tokui_boy.pngdenied (filesystem path '/var/www/wordpress/wp-content/uploads') because search permissions are missing on a component of the path, referer: http://n-nakatani-539518340.ap-northeast-1.elb.amazonaws.com/wp-admin/post.php?post=18&action=edit
[Fri Aug 18 06:56:24.345234 2023] [core:error] [pid 26139:tid 26296] (13)Permission denied: [client 10.0.31.179:31856] AH00035: access to /wp-content/uploads/2023/08/computer_tokui_boy.pngdenied (filesystem path '/var/www/wordpress/wp-content/uploads') because search permissions are missing on a component of the path, referer: http://n-nakatani-539518340.ap-northeast-1.elb.amazonaws.com/wp-admin/post.php?post=18&action=edit

マウントコマンドの説明

mount-s3 S3バケット ローカルのマウント先

オプション
--uid {オーナユーザのUID}
--gid {オーナグループののGID}
--allow-delete //ファイルの削除を有効にする
--allow-other //他のユーザの読み書きを許可する

詳しいコマンドのオプションや挙動については、公式のGithubを参照してください。

冗長化の動作確認

再度画像付きの記事を投稿し、動作を確認します。
今回は、静的コンテンツが動同期されているため、正しく画像が表示されます。

S3でもディレクトリ(キー)とオブジェクトが作成されています。

自動マウント

mount-s3は再起動時にマウントが解除されてしまいます。

[root@ip-10-0-17-31 uploads]# ll
total 0
[root@ip-10-0-17-31 uploads]#

自動でマウントを行う場合は、Unit定義ファイルを作成し、systemdで自動マウントを行います。

[Unit]
After=network-online.target

[Service]
Type=forking
ExecStart=mount-s3 --uid 48 --gid 48 --allow-delete --allow-other nakatani-wp-test /var/www/wordpress/wp-content/uploads/

[Install]
WantedBy=multi-user.target

終わりに

mountpoint-s3を用いて、簡単にWordpressのファイル同期を実装することができました。
小規模な構成であれば、mountpoint-s3経由でファイル同期することも可能と思います。
本運用する際は、同期速度やEC2への負荷などと相談して実装することをおすすめします。

参考

Mountpoint for Amazon S3 の使用 – AWS公式リファレンス
公式Github
コマンドについての説明 – Github