スケーラブルなMoodleの環境を構築する
仕事でLMSの構築が来た。
asw上で、Moodleをオートスケール対応にする。WordPressもそうだがなにげに面倒だったり悩みどころが多かったり、毎度忘れたりするので、作業メモ。
albのリダイレクトループ対策
これもあるあるかと思います。調査不足もさることながら、ヘルスチェックの際にに「303」が返り、設定だけでは回避ができなかったので、ヘルスチェック用のファイルを用意した。
$ touch /bitnami/moodle/healthcheck.php
#=>中身はこれを書いた。
<?php
http_response_code(200);
echo "OK";
ALBのヘルスヘックを、「/」から、「/healthcheck.php」に変更。これで、ちゃんと「200」が返る。
/bitnami/moodle/config.phpの編集。元々設定されていた部分をコメントして、ALBのCNAMEに変更。
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
//$CFG->wwwroot = 'https://' . $_SERVER['HTTP_HOST'];
$CFG->wwwroot = 'https://' . 'ALBにCNAMEしているドメイン';
} else {
//#$CFG->wwwroot = 'http://' . $_SERVER['HTTP_HOST'];
$CFG->wwwroot = 'http://' . 'ALBにCNAMEしているドメイン';
}
RDS
- ec2からアクセスできるように、セキュリティーグループを作成。
- 「ec2-rds-sg」という名前で作成した。このセキュリティーブループは、RDS側のセキュリティーブループのインバウンドのソースとして使うので、ここでは何も設定せずデフォルトのままでいい。デフォルトは以下の内容。
- インバウンド:空
- アウトバウンド:全てに対して許可
- 作成した「ec2-rds-sg」をec2(moodleが動いているやつ)にアタッチ。
- 「ec2-rds-sg」という名前で作成した。このセキュリティーブループは、RDS側のセキュリティーブループのインバウンドのソースとして使うので、ここでは何も設定せずデフォルトのままでいい。デフォルトは以下の内容。
- RDSのセキュリティグループの作成
- 「rds-sg」という名前で作成した。
- インバウンド:「ec2-rds-sg」からの3306を許可。
- アウトバウンド:空
- 「rds-sg」という名前で作成した。
- RDSをプライベートアクセスで作成
- セキュリティーグループには、「rds-sg」を指定。
Moodle側のDB設定
/bitnami/moodle/config.phpを編集。
$CFG->dbtype = 'mysqli'; #RDSのプラットフォームに変更
$CFG->dbhost = 'xxxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com'; # endpoint変更
$CFG->dbname = 'xxxxxxxxxxxx'; # DB名変更
$CFG->dbuser = 'xxxx'; # DBユーザー名変更
$CFG->dbpass = 'xxxx'; # DBパスワード変更
moodledataの共有
moodleはアップロードされたファイルの管理やインストールしたプラグインの管理、サーバーの状態管理などを、moodledataフォルダで管理をしている。このフォルダもスケールアウトした各ec2から共通の場所にしないと、アクセスしたec2毎に異なった挙動になってしまう。
S3FS-Fuse
WordPressの場合は、共有ストレージをS3にすることで回避出来たりするが、Moodleの場合はキャッシュやセッションまでDBではなくこのホルダで管理しているので、S3にするととてもじゃないがスループット、パフォーマンス的に耐えられない。
念の為、S3FS-FuseでS3をローカルドライブにマウントして検証してみたいが、ページが表示されるまでに、10秒近くかかるなどユースケース的にはあっていなかったので、やめる。
EFS
EFSも最善策ではないので、引き続きEBSも検討するがとりあえず今回はこれで進める。
- ec2用のEFSにアクセスするためのセキュリティーグループの作成。
- 「ec2-efs-sg」という名前で作成した。このセキュリティーブループは、EFS側のセキュリティーブループのインバウンドのソースとして使うので、ここでは何も設定せずデフォルトのままでいい。デフォルトは以下の内容。
- インバウンド:空
- アウトバウンド:全てに対して許可
- 「ec2-efs-sg」という名前で作成した。このセキュリティーブループは、EFS側のセキュリティーブループのインバウンドのソースとして使うので、ここでは何も設定せずデフォルトのままでいい。デフォルトは以下の内容。
- EFSのターゲットマウント用のセキュリティグループの作成
- 「ec2-efs」という名前で作成した。
- インバウンド:「ec2-efs-sg」からのNFS(2049)を許可。
- アウトバウンド:空
- 「ec2-efs」という名前で作成した。
- マネジメントコンソールから、EFSを作成。
- ターゲットマウントを、オートスケールで作成されるec2のサブネット分全て作成。
- ターゲットマウントのセキュリティグループに、「ec2-efs」を設定。
ec2にnfsクライアントをインストール
インストール。
$ sudo apt-get install -y nfs-common
$ mkdir /mnt/efs
手動で、NFSをマウント。
$ sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport <作成したEFSのドメイン>:/ /mnt/efs
しばらく待つと、プロンプトが戻ってきて、mountコマンドで確認ができる。
$ mount
<作成したEFSのドメイン>:/ on /mnt/efs type nfs4 (rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,noresvport,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=172.31.44.185,local_lock=none,addr=172.31.41.71)
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=402516k,nr_inodes=100629,mode=700,uid=1000,gid=1000)
永続化は、/etc/fstabに以下の行を追加する。
<作成したEFSのドメイン>:/ /mnt/efs nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport 0 0
PHPとMoodleのログについて
デプロイ直後なので何が出来るかわからないので、多めに出す設定。
「/bitnami/moodle/config.php」に以下の列を追記する。また、複数のec2がログを一箇所に出せるように、ログファイルのパスは、efsに指定した。
//Moodleのデバッグ
$CFG->debug = (E_ALL | E_STRICT); // エラーと警告をすべて表示
$CFG->debugdisplay = 0; // エラー情報を画面に表示? 0=しない、1=する
$CFG->debugstringids = 1; // エラーメッセージの文字列識別子を表示
$CFG->showcrondebugging = 1; // cron ジョブのデバッグ情報を表示
//PHPのデバッグ
ini_set('display_errors', '0'); // エラー情報を画面に表示?0=しない、1=する
ini_set('log_errors', '1'); // エラーをログに記録
ini_set('error_log', '/mnt/efs/moodle_error.log'); // エラーログのファイルパスを指定(適切なパスに変更してください)
AMIの作成
この状態で、AMIを「再起動する」で、イメージを作成する。再起動しないと、「/opt/bitnami/apache/var/run/httpd.pid」が残ったまま、AMIが作成されてしまい、新しく作成されたインスタンスのapacheの起動でコケるので要注意。
この、AMIを使用して起動テンプレートを作成し、オートスケーリンググループを作成して、既存のターゲットグループにアタッチする。
課題
やはり、EFSでもパフォーマンスは良くない。EBS等を検討する。
(2023.09.09:追記)
- EBSでも、複数PCからの書き込みはそもそもできない。素直にキャッシュサーバーを検討中。