Linodeで冗長構成のWordPressサーバを構築してみよう

## 本記事の目的
Linodeにて冗長構成されたWordPressのWebサーバーを安価に構築してみます。
・WordPressサーバー（Webサーバー）は2台構成にて単一障害を回避
・OS管理が不要なマネージドデータベースにて容易に冗長性を確保
・OS管理が不要なマネージドロードバランサーにて容易に冗長性を確保
・Cloud Firewallにてインターネットからのアクセスを制御
・短時間で冗長化されたWordPressを動作させる

## Linodeとは
Linode (https://www.linode.com/) は Akamaiが提供するIaaS (Infrastructure as a Service) プラットフォームプロバイダーのサービスです。詳細はリンクをご参考ください。

https://qiita.com/isss802/items/5313c7a6da1d9ed50a38


## WordPressとは
ブログを簡単に作成できる、オープンソースのソフトウェアです。CMSとしてもよく知られています。テンプレートやプラグインなど様々な機能が提供されているため、簡単に動的・静的なページを作成することができます。コンテンツなどの情報はMySQL等のデータベースに保持されます。
https://ja.wordpress.org/


## システム構成及び概算コスト
今回のシステム構成及び想定されるLinodeの概算コストは以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/fae0a4ac-d902-0756-5762-0ba674f2f786.png)





**NodeBalancer**
ロードバランサー機能にてLinode Computeを冗長構成とし可用性を向上させます。今回はNodeBalancerがLinode Computeの死活監視を行いサーバー障害時に切り替えるActive-Standby方式とします。月額固定のシンプルな料金設定となっており、今回の構成では月額10ドルとなります。またLinode Computeと同様に転送量で料金が発生します。
<img width=60% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/6b92d57c-1949-b705-b015-65a6b8932755.png">


**Cloud Firewall**
インターネットからの通信に対してアクセス制御を行うために、Linode Computeにてファイアウォールを構成できます。今回はインターネットからのTCP22(SSH), TCP80(HTTP)を許可し、その他インターネットからのインバウンド接続を遮断しています。
無償で利用することができます。

https://www.linode.com/docs/products/networking/cloud-firewall/#pricing-and-availability
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/f3614e60-c729-d9a6-41ed-bfe5f573a64b.png)


**Linode Compute**
WordPressをインストールするため、Ubuntuでサーバーを2台用意します。データベースへの接続はインターネットを通る必要はないため、プライベートIP同士で行います。
今回は、メモリ4GB CPU2コアのCPUリソース共有サーバーを選択します。Linodeのサーバーは時間単位で課金され、今回のサーバーは1台当たり月額は20ドルです。この20ドルのサーバー費用の中にはSSDが80GB、ネットワーク転送料が8TB（4TB/台）が含まれているので、この範囲内であれば追加費用なしで運用していくことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/2f34633c-cb8f-2421-d682-6aa69d796f79.png)


**マネージドデータベース**
Linodeにより管理されているデータベースサーバーです。インフラストラクチャー、ソフトウェア（更新含む）などが自動で構成されるため容易に展開及び運用が可能です。今回は複数あるデータベースエンジンからWordPress接続のためにMySQLを選択しています。また、合計3Nodesのレプリカ構成にて自動でフェイルオーバーされる高可用性を備えたデータベースとして構成しています。

今回は、メモリ4GBのCPUリソース共有サーバーでMySQLを選択します。
3Nodesの高可用性構成の場合は別の価格体系が定義されており、月額は140ドルです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/7a7f48f4-0e63-b70c-6421-e3c9755b7be4.png)



転送量にもよりますが、合計して月額$190から今回作成するプラットフォームを構成することができます。
なお、料金体系についての最新情報はこちらをご参考ください。

https://www.linode.com/pricing/

https://www.linode.com/docs/guides/network-transfer/


## マネージドデータベースの作成
それでは早速構築を始めてみましょう。
まずはマネージドデータベースから作成します。DatabasesメニューからCreate Database Clusterをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/5c7c3f4a-6c8b-4df6-fc39-06947fb65e93.png)


必要な項目を入力します。Database EngineはMySQLv8系、リージョンはTokyo 2, JPを選択します。PlanはShared CPUのLinode 4GBを選択しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/2843017f-298c-ca72-f6cf-378bedc0a662.png)

可用性を高めるために3Nodes構成とします。Allow IP AddessについてはLinodeで使われるプライベートIPサブネット（192.168.128.0/17）を入力しています。Allow IP Addressは最終的にはLinodeに適用されている個別のPrivate IPに変更しておいてください。最後にCreate Database Clusterをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/4761f06c-c544-db4d-a4aa-4910673c523f.png)


プロビジョニングが開始されます。30～40分程度かかるため、その間に次の作業に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/06816930-cbaa-3c8b-a83e-b4d7d70a5abd.png)







## WordPress用サーバーの作成 (Linode Compute)
続いて、フロントエンドのWordPress用サーバーを作成します。
まずは1台作成し、設定完了後にクローンして2台目を作成します。

Linodeメニューより、Create Linodeをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/a8c7a520-58a1-335a-67fa-5affafc14999.png)


各項目を入力します。Linode PlanはShared CPUで Linode4GBのプランを選択しました。
データベースと接続するためにPrivate IPにチェックを入れます。これによりプライベートIPアドレスも付与されます。最後にCreate Linodeをクリックし作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/9695f58e-baa1-e68d-1a9d-3e3eae6c4140.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/84aa3f66-3dfd-6874-e698-4a92fa8ff528.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/7c6be97b-cb9a-5a16-d319-ec28bf341eb3.png)

プロビジョニングが開始されます。2～3分程度かかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/83af0a2e-486d-4d2f-4f27-d4b55d2c2a9f.png)

なお、今回のようにデータベースを別で構成するのではなく、Linode Compute 1台ですべてを構成する場合は、Linode Marketplaceにて非常に簡単に構築することも可能です。

https://www.linode.com/ja/marketplace/apps/linode/wordpress/


## Cloud Firewallの作成
Cloud Firewallを作成し、WordPress用サーバーに適用します。Firewallsメニューより、Create Firewallをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/eb95c6af-4415-e2ad-3903-9a62274cae70.png)

作成するCloud Firewallの名前を入力し、Create Firewallをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/5a832ca0-adc6-750b-05ce-bac8ac6f7ca0.png)

作成されたCloud Firewallをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/d10de4d4-2517-66cd-88bb-dad82acbefbd.png)

Add an Inboud Ruleをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/0c25c16c-452d-e61c-c932-5c51274007c8.png)

まずはSSHを許可するルールを作成します。ルールのプリセットでSSHを選択すると自動的に値が入力されますので、そのままAdd Ruleをクリックします。HTTPも同様に設定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/8ec4c546-c60e-246b-5a04-6cfeb54eed8e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/b007382a-a3a8-c8fe-7056-b00e4ff1a1ce.png)


accept-inboundprivate-tcpの行については手動で値を入力しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/28868f12-2501-5bfa-72be-2e102ba87709.png)


以下のように設定できました。確認出来たら、Save Changesをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/8d9f5215-4cad-2538-cd60-1ea53db2eee9.png)





続いて適用するLinodeを選択します。LinodesタブからAdd Linodes to Firewallをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/776b2d4f-92fe-2561-66f6-7ada08b9c0b6.png)

作成したLinode Computeを選択しAddをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/ba6def9b-010c-42f8-1c17-2887024e7e34.png)

<img width=60% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/48127b8d-0969-064c-d1db-5bb5621ae7e4.png">


Cloud Firewallへ、1台目のLinode Compute適用が完了しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/649f0eab-9f59-b40a-461c-3777bc996ce9.png)


## OSの初期設定
作成したLinode Computeに戻ります。OS上で初期設定を行います。
Linodeメニューから作成したLinode Computeを確認するとRunningになっています。
SSHで接続するためにグローバルIPアドレスを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/c068896c-ba29-c9a3-bf59-b1d5d66d6a0a.png)



SSHクライアントを用いてrootユーザーに接続します。
<img width=60% src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/c7555419-7148-4b69-844d-5ef3444f9edd.png>


いくつかの初期設定を行います。
```bash
ユーザーの作成
# adduser -a [ユーザー名]
# gpasswd -a [ユーザー名] sudo

タイムゾーンの設定
# timedatectl set-timezone Asia/Tokyo

必要パッケージのインストール
# apt update
# apt install apache2 -y && systemctl enable apache2 && systemctl status apache2
# apt install php php-mysql -y
# apt install mysql-client -y

# vi /etc/ssh/sshd_config
```
```bash:/etc/ssh/sshd_config
#PermitRootLogin yes
PermitRootLogin no
```
sshdの再起動。以後は作成したユーザーにてログインし、sudoもしくはsu -にて進めます。
```
# systemctl rstart sshd
```

WordPressのインストールを行います。
```bash
# cd /var/www/html
# wget https://ja.wordpress.org/latest-ja.tar.gz && tar xvf latest-ja.tar.gz
# chown -R www-data:www-data .   
（最後にドットがあります）
```

ブラウザでSSHログインで接続した1台目のLinode ComputeのグローバルIPにアクセスして、WordPressへようこそ画面が表示されたらインストール完了です。なお、マネージドデータベースへの接続はSSLで行う必要があり、このWordPressの初期セットアップはSSL接続に対応していないため、今回は利用しません。 

http:\/\/Linode ComputeのグローバルIP\/wordpress\/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/631ee24b-6e69-1648-f256-5b90ad53d9d9.png)







## マネージドデータベース初期設定

MySQLのマネージドデータベースはSSL接続が必須ですが、WordPressの初期セットアップはSSL接続でのデータ作成（データベースの作成）に対応しておりません。
そのため、mysqlコマンドにてWordPress用のデータ作成を行います。

まずはマネージドデータベースの接続先を確認します。LinodeメニューのDatabasesから作成したDatabaseがActiveになっていることを確認してクリックします。ここまで設定が順調に進み、まだプロビジョニング中の場合はしばらく待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/70268fb4-e287-fb3d-2dd5-046f9d977e7f.png)

Connection Detailsの中身を準備しておきます。接続するホストはhostとprivate network hostの2つの値がありますが今回は後者を用います。passwordもShowをクリックして確認しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/eba19202-8a7d-999c-3cc1-7cd1352a676f.png)




本作業は１台目のLinode Computeから実施します。mysqlコマンドにてMySQL上のデータベースを作成します。
mysql> プロンプトが返ってきたら成功です。
```bash
# mysql --host=[private network hostの値] --user=[usernameの値]  --password --ssl-mode=required

Enter password: passwordの値を入力します
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 272
Server version: 8.0.26 MySQL Community Server - GPL

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

続いてデータベースを作成します。今回はwordpressdbという名前のデータベースを作成します。後ほどWordPress設定にて用いるためメモをしておいてください。
```bash
mysql> create database wordpressdb;

Query OK, 1 row affected (0.00 sec)
```

続いてWordPressがMySQL上のデータベースに接続するためのユーザーを作成します。ユーザー名は今回はdbuserとしています。
passwordは任意の値を決めます。MySQLのデフォルトポリシーが厳しいためご注意ください。
後ほどWordPress設定にて用いるためメモをしておいてください。

::: note info
デフォルトのMEDIUM: 1 つの数字、1 つの小文字、1 つの大文字、および 1 つの特殊文字 (英数字以外) を含める必要があります https://dev.mysql.com/doc/refman/8.0/en/validate-password.html
:::

```bash
mysql>  create user 'dbuser'@'192.168.%' identified by 'passowrd';

Query OK, 0 rows affected (0.00 sec)
```
作成したユーザーに権限を付与します。
```bash
mysql>  grant all on wordpressdb.* to 'dbuser'@'192.168.%';

Query OK, 0 rows affected (0.00 sec)
```

作成したデータベースおよびユーザーを確認したうえで、mysqlコマンドによる接続を終了します。
```bash
> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| wordpressdb        |
+--------------------+
5 rows in set (0.01 sec)

mysql> select user,host from mysql.user;
+------------------+-----------+
| user             | host      |
+------------------+-----------+
| linroot          | %         |
| repl_user        | %         |
| dbuser           | 192.168.% |
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| prm_user         | localhost |
+------------------+-----------+
7 rows in set (0.00 sec)

mysql> quit
Bye
```

続いてWordPressのDB接続設定を行います。こちらが先ほど初期セットアップにて行わなかった設定になります。
```bash
wp-config.phpをサンプルのコピーから作成します。
# cd /var/www/html/wordpress
# cp wp-config-sample.php wp-config.php
# chown www-data. wp-config.php
```

wp-config.phpを修正します。先ほどMySQL接続にて作成したそれぞれの値を適用します。
例としては以下の通りです。
| 設定項目 | 設定サンプル値 | 今回の設定値 | 
|:-----------|:-----------|:------------|
| DB_NAME| database_name_here:| wordpressdb | 
| DB_USER| username_here:     | dbuser   | 
| DB_PASSWORD| password_here: | dbuser作成時に指定したパスワード    | 
| DB_HOST| localhost:         | Linode マネージドデータベースのprivate network host名     | 


さらにSSL接続を行うため、設定値を以下のように追加します。
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT);

```bash
# vi wp-config.php
```
```bash:wp-config.php
/** WordPress のためのデータベース名 */
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);             # Add
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT);  # Add

define( 'DB_NAME', 'database_name_here' );

/** データベースのユーザー名 */
define( 'DB_USER', 'username_here' );

/** データベースのパスワード */
define( 'DB_PASSWORD', 'password_here' );

/** データベースのホスト名 */
define( 'DB_HOST', 'localhost' );
---------------------------------------------

```




改めてブラウザにてWordPressにアクセスします。今度は先ほどと異なる画面になりました。それぞれの値を入力し、WordPressをインストールをクリックします。

http:\/\/Linode ComputeのグローバルIP\/wordpress\/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/4c7dbfd5-daaf-a921-64f9-992ba6eab961.png)


WordPressのインストールと初期設定が完了しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/8d8733b5-335b-f83c-b6b2-ad39ce4a28ca.png)




## 2台目のWordPressサーバー作成
2台目はLinode ComputeのClone機能を用いて作成します。
まずは1台目のLinode Computeをシャットダウンします。
```bash
# shutdown -h now
```

Linodesメニューより1台目のLinode Computeをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/7cbbf39c-725d-deb4-d4da-9644a0fe77d6.png)

Cloneをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/eb5738a5-04de-05f2-28bf-ac6bf6ed02e8.png)


クローン元として1台目を選択し、Tokyoリージョンを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/49c5860e-ee6c-e11a-f8ef-49b2075b26aa.png)

Linode Planは同じとしたうえで、Linode labelは適切な名前（ここではka-wordpress02）を入力します。最後にClone Linodeをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/84e410ba-ba5d-6429-d366-b68f834ef6b9.png)

クローンが開始されます。
クローンではプライベートIPの割り当てが行われないため、Add an IP Addressをクリックし、プライベートIPを割り当てます。（クローン中でも割り当て可能です）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/d2bed975-874a-4ec0-9440-a0078a63ba49.png)

Privateを選択し、Allocateをクリックします。
<img width="40%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/fbc29e74-18df-a076-db12-e13d3c07bbd1.png">

IP Addressesメニューに IPv4 - Privateが割り当てられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/fc4d939b-f22e-346c-47a9-a9c9f35ae165.png)

しばらく待つとクローンが完了します。この後2台目をCloud Firewallに割り当てたら起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/46644d9e-576b-8a4c-2817-f67d818edbb4.png)




## 2台目のサーバーへCloud Firewallの適用

再度Cloud Firewallを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/4fcda7bf-b1e4-fad3-db48-52b7b9389f71.png)

LinodesタブからAdd Linodes to Firewallをクリックして、2台目のLinode Computeを割り当てます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/3116b7a7-6d4b-3dbc-1f94-2d52c26ae6ec.png)

2台目を割り当てました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/b92ef701-f517-5c4c-9f17-9e68fd64ae19.png)

2台目を起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/24eb6b3f-c184-4381-6848-af3937ecceea.png)



## WordPressサーバーの接続確認
どちらのIPでも接続できることを確認します。
http:\/\/1台目のLinodeのグローバルIP\/wordpress\/
http:\/\/2台目のLinodeのグローバルIP\/wordpress\/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/20ad0971-0fc5-088f-d974-725867a35fcc.png)


## Wordpressサーバー内のデータ同期
データベースについてはマネージドデータベースにより2台のWordPressサーバーが同じ内容を参照できますが、WordPressはサーバー内ディスクにも画像データなどを保持していますので、以下手順にて該当ディレクトリーを同期します。今回は簡易的な同期としてlsyncdにて構成していますが、GlusterFSファイルシステムや、Linode対応WordPressプラグイン（3rd party製/有償）を行うことでより厳密な同期による冗長化や負荷分散も可能なため検討してみください。

https://www.linode.com/docs/guides/host-a-website-with-high-availability/

https://www.joomunited.com/ja/%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9/wordpress-%E3%83%A1%E3%83%87%E3%82%A3%E3%82%A2-%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%82%92-linode-%E3%81%AB%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95


まずは公開鍵を用いてSSHのログインが行えるようにします。
Linode ComputeのプライベートIPを2台とも確認しておきます。Linodeメニューから各Linode Computeをクリックし、Networkタブにて確認可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/a9fc2c48-1a27-da92-fbe9-2cf44ba3b98b.png)


1台目のサーバーで公開鍵及び秘密鍵を作成します。
```bash
# cd /root/
# ssh-keygen -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):  #何も入れない
Enter same passphrase again:  #何も入れない
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is: 
SHA256:xxxx root@localhost
The keys randomart image is:
+---[RSA 3072]----+
|         .+*.o.  |
|  .. ..*Bo       |
+----[SHA256]-----+

# chmod 600 .ssh/id_rsa
```

作成した公開鍵を2台目に転送します。 先ほど確認した2台目Linode ComputeのIPアドレスを入力します。
```bash
# scp .ssh/id_rsa.pub root@[2台目のプライベートIP]:/root/.ssh/
root@[2台目のプライベートIP]s password: #ログインパスワードを入力します
id_rsa.pub                                                        100%  568   636.9KB/s   00:00
```

2台目のサーバーでSSHのログイン許可をします。 先ほど確認した1台目Linode ComputeのIPアドレスを入力します。

```
# vi /etc/ssh/sshd_config
```

```bash:/etc/ssh/sshd_config
  # 最下行に追記します
Match Address [1台目のプライベートIP]
  PermitRootLogin yes
```

sshdを再起動します。
```bash
# sshd -t  #コンフィグチェック。何も出なければOK
# systemctl restart sshd
```

2台目のサーバーにSSHでログインし、公開鍵の配置を調整します。
```bash
# chmod 600 .ssh/authorized_keys
# cat .ssh/id_rsa.pub >>  .ssh/authorized_keys
# rm .ssh/id_rsa.pub
```

1台目のサーバーに戻りlsyncdをインストールします。
```bash
# apt install lsyncd
# mkdir /etc/lsyncd/
```

lsyncdの設定ファイルを作成します。 先ほど確認した2台目Linode ComputeのIPアドレスを入力します。
```bash
# vi /etc/lsyncd/lsyncd.conf.lua
```
```bash:/etc/lsyncd/lsyncd.conf.lua
settings{
    logfile = "/var/log/lsyncd.log",
    statusFile = "/tmp/lsyncd.pid",
    insist = 1
}

sync{
  default.rsync,
  source = "/var/www/html/wordpress/wp-content",
  target = "root@[2台目のプライベートIP]:/var/www/html/wordpress/wp-content",
  rsync = {
    archive = true,
    update = true,
    rsh="/usr/bin/ssh -i/root/.ssh/id_rsa"
  }
}
```

lsyncdを起動します。
```
# systemctl start lsyncd
# systemctl enable lsyncd
```

wordpress/wp-content/uploadsフォルダにはWordPressのメディアライブラリにアップロードした画像などが置かれます。1台目からメディアライブラリに置いたり、以下のようにファイルを作成すると、しばらくして2台目に同期されることが確認できます。うまくいかない場合は、/var/log/lsyncd.logを確認してみてください。　
なお、本手順は1台目から2台目への片方向構成となっていますので逆の同期は行いません。
```
# cd /var/www/html/wordpress/wp-content/uploads
# touch test
```



## ロードバランサーの作成
いよいよ最後の工程になります。NodeBalancer（ロードバランサー）にてWordPressの冗長設定を行います。
LinodeメニューのNodeBalancersから、Create NodeBalancerをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/f14f3663-f47b-8c3e-e9e4-35e3e3f6fffe.png)

それぞれ入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/99a00ac8-c71e-862f-6eac-27868be82e4b.png)

続きとして、NodeBalancer Settingsを記入します。
今回はHTTPでNodeBalancerがリクエストを受けて振り分けますので、Portは80とします。
Active Health Checksは、今回はHTTPS Statusを選択し値はデフォルトのまま、チェック対象のパスを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/667db11f-dddf-e31f-b9af-4dd212756365.png)


最後に接続するLinodeを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/586e1bcb-a2a4-632f-bf76-039ed8c95430.png)

画面右上に戻りCreate Nodebalancerで作成が行われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/097c71ac-400e-1d6f-63a3-d01bf18c2877.png)

再度Configurationを開き、2台目をBackupにしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/01ca57e8-607a-6c54-9435-9b896ae6fc82.png)


WordPressにアクセスした際に1台目のIPがサイトアドレスとして登録されているため、2台目やロードバランサー経由でアクセスすると1台目にリダイレクトされていまいます。そのためサイトアドレスを変更しておきます。
WordPressのようこそ画面にて登録したWordPress管理者のユーザー名とパスワードを用いてログインします。
http:\/\/[1台目のグローバルIP]\/wordpress\/wp-login.php
<img width=40% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/2f44b693-803e-d419-1874-23268e0d02ac.png">

設定からWordPressアドレスとサイトアドレスを変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/2d4149ad-e24b-d417-884e-390c09880ebb.png)


ロードバランサーに戻り、作成後しばらく待つと、Linode Computeが2台upしていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/2406500f-113f-a340-d670-0b5cfdb374a5.png)

Host Name もしくは IP Addressがロードバランサーを経由した接続先の情報となります。なおFQDNはLinodeのドメインになっていますが、CNAMEすることで自社ドメインを利用可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/51e7eb69-f279-888a-4a38-90cf72899faa.png)

http:\/\/NodeBalancerのFQDN\/wordpress\/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/286cc7d0-b698-248a-8dc9-60caaa39bf26.png)


片方のWordPressサーバーを意図的にシャットダウンした場合でも、もう片方でアクセスができます。NodeBalancerによって検知されていることも確認ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/0166c5f4-19e5-e153-0e63-b1db18f71f42.png)


しばらく待つと、ConnectionやTrafficの情報が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/fa910d34-2db8-3a7d-a3b0-6a1d1efb8cbd.png)



## 補足：WordPressのHTTPS化
WordPressのHTTPS化は、DNSレコードの登録、サーバー証明書の取得、サーバー証明書の適用及び更新などが必要です。証明書取得だけでも複数の方法がありますが、ここでは一例を紹介します。

#### DNSサーバーへCNAMEレコードの追加
公開するFQDNのDNSサーバーにレコードを追加します。もしDNSサーバーがない場合はグローバルにスケールされた高可用性を備えたAkamai Edge DNSも検討ください。LinodeにもDNS manager（Domainsメニュー）が提供されているためそちらを使うのも一つの方法です。

https://www.akamai.com/ja/resources/product-brief/edge-dns-product-brief

https://www.linode.com/docs/guides/dns-manager/

DNSサーバーが準備できたら、NodeBalancer作成時に提供された、"[IPアドレス].ip.linodeusercontent.com"に対してCNAMEを行います。
```bash
www.example.com  IN  CNAME  [IPアドレス].ip.linodeusercontent.com
```

#### サーバ証明書の取得
ここではLet's Encryptを用いてサーバー証明書を取得してみます。ここではLinode Computeの2台目にCertbotをインストールして行いました。

```bash
# apt install certbot
```
Certbotを実行しサーバー証明書を申請します。www.example.comは実際のFQDNに置き換えてください。ここではDNS認証によって取得を行います。チャレンジが表示されたタイミングで、Press Enter to Continueが表示されますので、コンソールを止めておきます。
```bash
# certbot certonly --manual -d www.example.com --preferred-challenges dns

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): YOUR@mail.address

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: 内容を確認してYを入力します

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: 内容を確認してY/Nを入力します
Account registered.
Requesting a certificate for www.example.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name:

_acme-challenge.www.example.com.      # 作成するTXTレコード名

with the following value:

fGFzA6LKBf3r3r3roIeop-dummy-3kYvox9Ki-tzjOo　　　# DNS認証用のチャレンジ

Before continuing, verify the TXT record has been deployed. Depending on the DNS
provider, this may take some time, from a few seconds to multiple minutes. You can
check if it has finished deploying with aid of online tools, such as the Google
Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.wwwexample.com.
Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
value(s) you've just added.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue   #ここで止めておく
```

DNX TXTによる認証チャレンジが表示されたため、DNSサーバーへTXTレコードを登録します。DNSレコード及びチャレンジは実際に表示された内容をもとに適用してください。
```
_acme-challenge.www  IN  TXT fGFzA6LKBf3r3r3roIeop-dummy-3kYvox9Ki-tzjOo
```

DNSサーバーへ登録ができたら反映までに時間がかかることもあるため、digコマンドなどでTXTレコードが反映されているか確認します。
```
# dig _acme-challenge.www.example.com txt

;; ANSWER SECTION:
_acme-challenge.www.example.com. 120 IN TXT "fGFzA6LKBf3r3r3roIeop-dummy-3kYvox9Ki-tzjOo"
```

先ほど止めたコンソールに戻ってきます。Prese Enter to ContinueでEnterを押すとDNS認証が行われ、Successfully received certificate.と表示されれば証明書が発行されます。表示されたメッセージの通り、サーバー証明書及び秘密鍵は/etc/letsencrypt/live/ドメイン名/に保存されます。
```bash
～続き～
Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
value(s) you've just added.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue   ## ここから続きます。

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/www.example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/www.example.com/privkey.pem
This certificate expires on 2023-01-18.
These files will be updated when the certificate renews.

NEXT STEPS:
- This certificate will not be renewed automatically. Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided. To renew this certificate, repeat this same certbot command before the certificate's expiry date.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
```

証明書の内容を確認します。後ほどNodeBalancerに貼り付けますのでメモしておきます。
```bash
# cat /etc/letsencrypt/live/www.example.com/fullchain.pem
```
```:fullchain.pem
-----BEGIN CERTIFICATE-----
MIIFRTCCBC2gAwIBAgIMxKTAnBgNVBAoTIEludG
MxKTAnBgNVBAoTIEludGAwIBAgIMxKTAAwIBAgI
＜省略＞Bvcq
-----END CERTIFICATE-----
```

```bash
# cat /etc/letsencrypt/live/www.example.com/privkey.pem
```
```:privkey.pem
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcw
ot0xYV4nEpmm2ygkqAGRHakHZdG1P1gU4Tf/
＜省略＞eFff
-----END PRIVATE KEY-----
```


#### NodeBalancerへサーバー証明書の適用
続いてNodeBalancerに発行したサーバー証明書を適用します。なお今回は、NodeBalancerがHTTPS(443)でリクエストを受けた後に、NodeBalancerはWordPressにHTTP(80)でリクエストする構成としていますので、WordPressサーバーにはサーバー証明書は不要です。

NodeBalancerの設定を行います。NodeBalancersメニューのConfigurationsタブからAdd Another Configurationをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/ed242b77-2954-7540-c51b-035f603333d4.png)

HTTPS向けの設定を行います。Portは443、ProtocolはHTTPSとして、SSL Certificate、Private Keyについては先ほど発行された証明書と秘密鍵の文字列を貼ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/964a3589-1f7a-69e5-9982-3a33d429be27.png)

HTTPの時と同様に設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/2e426bc2-3081-fda7-3125-5a29d6c2b2a1.png)

HTTPの時と同様に設定します。WordPressへはHTTP(80)でリクエストされるように、Portについては80を入力します。入力が完了したらSaveをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/13c3820c-dc23-7a89-7978-dab4e42426ee.png)

ページの上側を確認すると作成が完了したメッセージが表示されます。
<img width=60% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/3e592f1b-5a29-ede2-2b8f-63799d7990a7.png">


#### wp-config.phpの修正

WordPressはHTTPでの接続となりますので、最終的に正しく接続できるようにwp-config.phpに以下を追加します。こちらはWordPressサーバーのLinode Compute2台とも実施します。

```bash
# vi /var/www/html/wordpress/wp-config.php
```

```bash:wp-config.php
/** データベースのテーブルを作成する際のデータベースの文字セット */
define( 'DB_CHARSET', 'utf8' );

/** データベースの照合順序 (ほとんどの場合変更する必要はありません) */
define( 'DB_COLLATE', '' );

#ここに以下4行を追記します
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) {
    $_SERVER['HTTPS']='on';
}

```

#### WordPressのURL設定変更
WordPressの初期設定時と同様に、WordPressの管理画面にログインし、設定メニューから、WordPresアドレス、サイトアドレスを変更します。

ここでは、https:\/\/ではなくhttp:\/\/で設定します。
そのためFQDNの部分のみを自社ドメインのFQDNに変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/860464d4-72d1-d04c-cc28-7fd0186ce424.png)

今回はWordPressのプラグインであるReally Simple SSLを用いてHTTPS化を行います。WordPressメニューのプラグインを開き、Really Simple SSLで検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/39adf666-186c-1c72-b123-f61e96f2e154.png)

検索結果が表示されますので、今すぐインストールをクリックします。
<img width=60% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/b5a9d5a7-9bd7-0243-d96a-c8a1c1016b0f.png">

Really Simple SSLプラグインを有効化します。
<img width=60% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/1095dca2-8cdb-616d-db09-d058cc672a7f.png">

SSLを有効化（HTTPSを有効化）します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/a302d0dd-ba3d-538d-54b8-a55f43261b3b.png)

すぐに設定が完了します。必要に応じて追加作業もありますがここではスキップします。
<img width=60% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/6f547f37-ead7-3d23-7e03-99540d80f661.png">

改めて設定のWordPressアドレス、サイトアドレスを確認すると、https:\/\/に変更されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/618bfbb4-1510-3ef4-e311-0283ea45763c.png)


#### HTTPSでのWordPressアクセス
HTTPS化の準備ができましたので、実際にブラウザを用いてHTTPSでアクセスすると、無事HTTPS化が完了していることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/fcbaf4fb-c9eb-0c3d-bc26-ee97569ea1d8.png)


#### サーバー証明書の更新
Let'sEncrtptの場合は90日でサーバー証明書の更新が必要です。今回はCertbotにて実施します。
事前に作業のためのスクリプトを準備します。
$CERTBOT_VALIDATIONの変数から/root/token.txtにTXTレコードに登録するDNS認証の新しいトークンが/root/token.txtに保存されるようにします。例ではDNS更新の待ち時間を600秒としています。 
```bash
# vi /root/export-token.sh
# chmod 755 /root/export-token.sh
```
```bash"export-token.sh
#!/bin/bash
echo "$CERTBOT_VALIDATION" > /root/token.txt
sleep 600
```

Certbotにて更新を行います。　Renewing an existing certificateの箇所で、600秒のDNS再認証待ち時間が発生します。実際に更新せずにテストを行う場合は、--dry-runを引数に追加します。
```bash
# certbot renew --preferred-challenges=dns --manual --manual-auth-hook /root/export-token.sh

Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/www.example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Renewing an existing certificate for www.example.com
```

TXTレコードに登録する新しいトークンが出力されていますので、待ち時間の間に新規作成時と同様にDNSレコードを更新します。
```bash
# cat /root/token.txt
jGXfewaGfav504ThHHfhGHHB3UV8
```

```
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/www.example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Renewing an existing certificate for www.example.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all renewals succeeded:
  /etc/letsencrypt/live/www.example.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
```

作成時と同様にNodeBalancerにサーバー証明書適用して完了です。
<img width=60% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/01bc5368-d465-ca03-5236-b4592e80e33b.png">



## まとめ
Linodeを用いると、複数のコンポーネントからなる構成でも短時間で構築することができます。また各種マネージドサービスにより可用性の高いサービスを運用することも可能となります。Webサイトとして実際に公開するには、コンテンツの作成以外にもOSの詳細設定、CDN適用、WAF/WAAPなどのセキュリティ対策など他にも必要な項目はありますが、基本的な部分は構成できたと思います。ぜひLinodeにてWordPressなどの安価なLinuxインターネットサービスを構築してみてください。


## 参考情報

https://qiita.com/isss802/items/5313c7a6da1d9ed50a38

https://qiita.com/isss802/items/c53315615a7e087cc41a

https://qiita.com/isss802/items/20906f2bbf8c6a433d5a