特に必要に迫られたわけではないが、53ningen.com をさくら VPS から AWS 環境へお引越ししてみる。
現状 nginx, MariaDB が稼働する gomi-web 系と zabbix, elasticsearch, kibana, その他諸々をぶん回している gomi-back 系がある。これを ELB + EC2 2 台 + RDS という構成に変更する。
構成の変更
- お金もないので、ひとつのサーバーに色々乗っけて遊んでました
- 財布を灰にする代わりにもう少しまともな構成にする
ウェブサーバ
主に nginx, php-fpm, MariaDB が稼働していたさくら VPS の gomi-web 系統から MariaDB を分離し RDS にお引越し
- 【変更前】 さくら VPS: 2 コア/1GB/SSD30GB (現状余裕がある)
- 【変更後】 t2.nano 1vCPU/0.5GiB/SSD8GB + RDS db.t2.micro 1vCPU/1GiB
バックエンド系
zabbix, elasticsearch, kibana, influxdb, graphana など色々てんこ盛りで動いてたバックエンド系 + 実験用サーバだが、カオスだったり、環境をぶっ壊しがちだったので、定常的に動かすものとそうでないものを分離しておく
- 【変更前】 さくら VPS: 3 コア/2GB/SSD50GB
- 【変更後】 t2.medium 2vCPU/2GiB/SSD10GB
ウェブサーバの構成変更点は以下のようなもの
前段への ALB 設定によるアプリケーション構成変更
nginx で直接 SSL を解いていたが、前段の ALB によって SSL オフロードする
- nginx 443 ssl で受けているものを全て 8443 で受けるように変更
- nginx の conf から証明書まわりの記述を削除
- Wordpress が http に対してのリクエストに対して、依存リソースを http で返さないよう wp-config.php に以下を追加
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
$_SERVER['HTTPS']='on';
}
作業手順
1. ウェブサーバ用の EC2 インスタンス + ALB を作成し、証明書などをセットしておく
- VPC, Subnet, Security Group, NACLs, Routing Table などを適切に切って、EC2 インスタンスをポコっとたてる
- Target Group, ALB を作成して HTTPS リスナーに ACM で作成した SSL 証明書を設定しておく
- いままでは nginx + let's encrypt でやっていたので、 nginx conf 修正、 Wordpress の wp-config.php 修正が必要
2. playbook を修正し、EC2 インスタンスに流す
- なんやかんやでむかし使えていたはずの playbook が途中でとまったりすることはよくある
- まずは使用する AMI に対して、すんなり ansible を流し終えられるように修正をいれていく
- 案の定 java のインストールにコケたり
- inventory にホスト追加したり
- あとは nginx の設定変更
- SSL を nginx で解いていたが、これからは ALB で解くため、443 ssl で linsten していたものを 8443 に変えたり、証明書に関する記述を削除したりする
- listen 443 ssl;
+ listen 8443;
3. Wordpress のデプロイ
- rsync で旧サーバーからごそっと持ってくるだけで基本的に OK (な作りにしてある)
- 静的コンテンツは S3 plugin を使って、もともと S3 に置いてあったので、ほぼ php コードの sync
rsync -av ./wordpress/ remote_ip:/path/to/wordpress/ --dry-run
rsync -av ./wordpress/ remote_ip:/path/to/wordpress/
- wp-config.php から DB の向き先だけ、インターネット越しにさくら VPS の MariaDB を見に行くように修正
- あわせてさくら VPS 側の FW を該当 EIP tcp 3306 への通信を accept するように修正
sudo firewall-cmd --zone=external --add-rich-rule='rule family="ipv4" source address="xx.xx.xx.xx/32" service name="mysql" accept'
sudo firewall-cmd --zone=external --add-rich-rule='rule family="ipv4" source address="xx.xx.xx.xx/32" service name="mysql" accept' --permanent
- MariaDB に該当 EIP から接続するユーザーをいい感じに作る
$ strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 30 | tr -d '
'; echo;
...........
$ mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 23627
Server version: 10.2.15-MariaDB-log MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> CREATE USER 'hoge'@"xx.xx.xx.xx" IDENTIFIED BY '...........';
MariaDB [(none)]> GRANT ......... ON ........ TO 'hoge'@"xx.xx.xx.xx";
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SHOW GRANTS for 'hoge'@"xx.xx.xx.xx";
+-----------------------------------------------------------------------------------------------------------------+
| Grants for 'hoge'@"xx.xx.xx.xx" |
+-----------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON ....... TO ..... IDENTIFIED BY PASSWORD ........................... |
+-----------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
4. ひとまず動作確認
-
ALB の FQDN から動作確認
- HTTP 80 OK (304 redirect to https)
- HTTPS 443 あれ、504 Gateway Timeout だ... と思ったら vpc 内からの 8443 をあけてなかった
-
ウェブサーバの移行残タスクは以下
- データベース/そのほかバックエンド系の移行
- DNS レコードの更新(向き先を ELB に変更)
5. データベース移行
続いてデータベースの RDS 移行
- ひとまず旧 DB を master、 RDS MariaDB を slave とする構成を作る
- ウェブサーバ EC2 移行時に RDS MariaDB を master 昇格させる
AWS のドキュメントによると、MariaDB 10.0.24 以降を利用している場合で RDS MariaDB をレプリケーションスレーブにしたい場合、GTID ベースレプリケーションの設定が必要となる。
(もし既存のレプリケーションがなければ) DB の conf を修正し、restart
[mysqld]
server-id={{ mysql_server_id }}
{% if mysql_server_state == 'master' %}
log-bin=mysql-bin
expire_logs_days=3
{% else %}
read_only
{% endif %}
(もし既存のレプリケーションがなければ)現行系 DB にレプリケーション用ユーザーを作成
# create replication user
$ strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 30 | tr -d '
'; echo;
...............
$ mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 23627
Server version: 10.2.15-MariaDB-log MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> CREATE USER ......... IDENTIFIED BY ...............;
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> SELECT user, host FROM mysql.user;
+------------------+-----------------+
| user | host |
+------------------+-----------------+
.........
+------------------+-----------------+
10 rows in set (0.00 sec)
MariaDB [(none)]> GRANT CLIENT, REPLICATION SLAVE ON *.* TO ........... IDENTIFIED BY '........';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SHOW GRANTS for '.....'@'........';
+-----------------------------------------------------------------------------------------------------------------+
| Grants for .................. |
+-----------------------------------------------------------------------------------------------------------------+
........
+-----------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
現行 DB をダンプし、移行先 DB にインポート
MariaDB [(none)]> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SET GLOBAL read_only = ON;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SELECT @@gtid_current_pos;
+--------------------+
| @@gtid_current_pos |
+--------------------+
| 0-1001-20104 |
+--------------------+
1 row in set (0.00 sec)
MariaDB [(none)]> exit
Bye
$ mysqldump \
> --databases hogehoge \
> --single-transaction \
> --compress \
> --order-by-primary | mysql \
> --host=dbname.********.ap-northeast-1.rds.amazonaws.com \
> --port=**** \
> -u ***** \
> -p
Enter password:
slave の設定を行いレプリケーションを開始する
MariaDB [(none)]> CALL mysql.rds_set_external_master_gtid ('*************', *****, 'repl', '***************', '0-1001-20104', 0);
Query OK, 0 rows affected (0.03 sec)
MariaDB [(none)]> CALL mysql.rds_start_replication;
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> UPDATE mysql.rds_replication_status SET action='start slave';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [(none)]> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
Seconds_Behind_Master: 0
...
Using_Gtid: Slave_Pos
...
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
1 row in set (0.01 sec)
6. 動作確認/DNS 切り替え
新系を数日寝かせて動作確認後、DNS 変更で新系の ELB を向くように Route 53 を設定する
7. DB 切り替え
RDS で稼働する DB を新 master に切り替える
Pinned Articles
About
ウェブ界隈でエンジニアとして労働活動に励んでいる @gomi_ningen 個人のブログです
Tags
JavaScript
PowerShell
kibana
elasticsearch
fluentd
nginx
イベント
五十嵐裕美
村川梨衣
logrotate
IoT
Scala
Java
C言語
iputils
ICMP
WUG
mastodon
Swift
AWS
Clock
Windows
アーキテクチャ
PoEAA
iOS
DeviceFarm
プログラミング言語
OS
StepFunctions
Lambda
Serverless
terraform
ポエム
RHEL
ネットワーク
GraphQL
CloudWatch
Linux
Coreutils
network
nc
telnet
LinuxKernel
fpinscala
ELB
IAM
AppSync
EFS
Gradle
english