Edited at

KubernetesでWordPress構築をやってみた。運用費は月額4000円ほど。

More than 1 year has passed since last update.


WordPressをリーズナブルに使いたい

WordPressでブログサイトを作りたく、リーズナブルに運用できる方法を探していたのですが、GCEでWordPressがほぼ無料運用できるようになったので改めてまとめるの記事を読んで、GCPを使えば安そうなので試してみました。

公式ドキュメントにも


WordPress ホスティング料金

WordPress は Compute Engine の無料階層で実行できます(f1-micro、0.2 CPU)


と確かにGoogle Compute Engineを使えば無料枠でWordPressが作れそうですね。


GCEにWordPressを構築する方法

公式ドキュメントによると、3通りWordPressを構築する方法があるようです。



  • Cloud Launcher で WordPress の単一インスタンスをデプロイ


    • トラフィックが少ない場合や中程度の場合に最適




  • Kubernetes Engineに WordPress をデプロイ


    • トラフィック量が多い場合に、自動スケーリングなどできる




  • App Engine に WordPress をデプロイ


    • トラフィック量が変動し、ピーク時の値が高くなる場合にのみおすすめ



今回は、リーズナブルに済ませたいと思う気持ちがありつつも、

Kubernetes触ってみたかったのでKubernetesでやりたいと思います。


Kubernetesとは

Linux コンテナの操作を自動化するオープンソース・プラットフォームのことです。

詳細はこちらの記事に(Kubernetes とは)詳しく書かれていますが、今回この記事で使う用語をメモっておきます。

用語
説明

クラスタマスター
Kubernetes ノードを制御するマシン。すべてのタスクの割り当て元となります。

ノード
リクエストされ、割り当てられたタスクを実行するマシン。Kubernetes マスターはこれらのノードを制御します。

Pod
1 つのノードにデプロイされた、1 つ以上のコンテナからなるグループ。Pod に入っているすべてのコンテナは、同じ IP アドレス、IPC、ホスト名、その他のリソースを共有します。

サービス
Pod から作業の定義を分離します。Kubernetes サービスプロキシは適切な Pod に自動的にサービスリクエストを提供します。

kubectl
Kubernetes のコマンドライン設定ツールです。


gcloudをインストール

公式ドキュメントによると、GCPSDKが必要なのでGoogle Cloud SDKを入れます。

参考:Cloud SDK のインストール

パッケージをダウンロードしてきてから、インストールを実行。

$ ./install.sh 

Welcome to the Google Cloud SDK!

・・・

==> Source [/Users/hoge/Downloads/google-cloud-sdk/completion.bash.inc] in your profile to enable shell command completion for gcloud.
==> Source [/Users/hoge/Downloads/google-cloud-sdk/path.bash.inc] in your profile to add the Google Cloud SDK command line tools to your $PATH.

For more information on how to get started, please visit:
https://cloud.google.com/sdk/docs/quickstarts

PATHを通してgcloudコマンドが使えるようにします。

$ vi ~/.bash_profile

#パス追加
export PATH=$PATH:/Users/hoge/src/google-cloud-sdk/completion.bash.inc
export PATH=$PATH:/Users/hoge/src/google-cloud-sdk/path.bash.inc
export PATH=$PATH:/Users/hoge/src/google-cloud-sdk/bin/

$ source ~/.bash_profile

また、gcloudコマンドが使えるようになったところで、Kubernetesのコマンドラインツールkubectlもインストールします。

$ gcloud components install kubectl

事前準備が整いました。


WordPress と MySQL での永続ディスクの使用

以下を参考に行います。

WordPress と MySQL での永続ディスクの使用

永続ディスクとは、高性能のブロック ストレージです。コンテナは使い捨てがセオリーなので、永続的なファイルシステムの格納には向いていませんが、この永続ディスクを使用するとアプリケーションのデータ(WordPress、MySQL)をコンテナの外部に保存できます。そのためたとえコンテナを削除しても、データは消えないのです。


Google Kubernetes Engine API を有効にする

まずはGCPのコンソールより、Kubernetes Engine のページにアクセスし、プロジェクトを作成します。

スクリーンショット 2018-01-10 1.51.33.png

プロジェクト作成後、プロジェクトの課金を有効にします。


gcloud コマンドライン ツールのデフォルトの設定

gcloudを使う上で、

先ほど作成したプロジェクトのプロジェクトIDと、Compute Engine ゾーンのデフォルト設定にします。

$ gcloud config set project (PROJECT_ID)

Updated property [core/project].
$ gcloud config set compute/zone asia-northeast1-b
Updated property [compute/zone].

Compute Engine ゾーンによってインスタンスの機能と通信速度が異なります。例えば2018年1月現在、東京リージョンでは、GPU搭載のインスタンスが使えません。

ただ日本からアクセスされるブログサイトであれば、東京リージョンの方が通信速度が早く適しています。

参考:東京 GCP リージョン の正式運用を開始しました


アプリケーション マニフェストのダウンロード

GitHub レポジトリより、WordPress環境に必要なマニフェスト ファイルをダウンロードします。

$ git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples

Cloning into 'kubernetes-engine-samples'...
remote: Counting objects: 207, done.
remote: Total 207 (delta 0), reused 0 (delta 0), pack-reused 207
Receiving objects: 100% (207/207), 56.65 KiB | 0 bytes/s, done.
Resolving deltas: 100% (77/77), done.
Checking connectivity... done.

ダウンロードしたファイルは、WordPressとMySQLのデプロイ設定ファイル、サービス設定ファイルです。

$ ls -1

README.md
mysql-service.yaml
mysql.yaml
wordpress-service.yaml
wordpress.yaml


Kubernetes Engine クラスタ マスターを作成する

クラスタ マスターはノードを制御するマシンです。

以下のコマンドで、blogという名前で3つのノードを制御するクラスタを作成しています。ノードは、タスクを実行するマシンです。

$ gcloud container clusters create blog --num-nodes=3 

WARNING: Accessing a Container Engine cluster requires the kubernetes commandline
client [kubectl]. To install, run
$ gcloud components install kubectl

Creating cluster blog...done.
Created [https://container.googleapis.com/v1/projects/wordpress/zones/asia-northeast1-b/clusters/blog].
kubeconfig entry generated for blog.
NAME ZONE MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
blog asia-northeast1-b 1.7.11-gke.1 35.193.159.110 n1-standard-1 1.7.11-gke.1 3 RUNNING


永続ディスクを作成する

ポッドが再起動されても、WordPress、MySQLのデータが消えないように永続ディスクを使用します。

$ gcloud compute disks create --size 200GB mysql-disk

Created [https://www.googleapis.com/compute/v1/projects/wordpress-for-beauty/zones/us-central1-b/disks/mysql-disk].
NAME ZONE SIZE_GB TYPE STATUS
mysql-disk us-central1-b 200 pd-standard READY

New disks are unformatted. You must format and mount a disk before it
can be used. You can find instructions on how to do this at:

https://cloud.google.com/compute/docs/disks/add-persistent-disk#formatting

$ gcloud compute disks create --size 200GB wordpress-disk
Created [https://www.googleapis.com/compute/v1/projects/wordpress/zones/asia-northeast1-b/disks/wordpress-disk].
NAME ZONE SIZE_GB TYPE STATUS
wordpress-disk asia-northeast1-b 200 pd-standard READY

New disks are unformatted. You must format and mount a disk before it
can be used. You can find instructions on how to do this at:

https://cloud.google.com/compute/docs/disks/add-persistent-disk#formatting

mysql-diskwordpress-diskの2つの永続ディスクを用意しました。

※永続ディスクは料金が発生します。詳細は最後に記載。


MySQL をセットアップする

まずはデータベースのパスワードを格納する Kubernetes シークレットを作成。

$  kubectl create secret generic mysql --from-literal=password=(YOUR_PASSWORD)

secret "mysql" created

mysql.yaml マニフェスト ファイルを使用して、ポート 3306 で動作する単一インスタンスの MySQL アプリケーションをデプロイします。

先ほど作成した永続ディスクmysql-diskもこちらで指定します。


mysql.yaml


apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mysql
labels:
app: mysql
spec:
# レプリカ数の指定
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
gcePersistentDisk:
      //先ほど作成した永続ディスクを指定
pdName: mysql-disk
fsType: ext4


マニフェスト ファイルをデプロイする

$ kubectl create -f mysql.yaml

deployment "mysql" created


ポッドが実行されているかどうかを確認

$ kubectl get pod -l app=mysql

NAME READY STATUS RESTARTS AGE
mysql-3368603707-327j1 1/1 Running 0 44s


MySQL サービスを作成する

Kubernetesのサービスは、論理的なポッドのセットと、それにアクセスするポリシーを定義する抽象的なものです。


mysql-service.yaml

apiVersion: v1

kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
type: ClusterIP
ports:
- port: 3306
selector:
app: mysql

マニフェスト ファイルをデプロイ

$ kubectl create -f mysql-service.yaml

service "mysql" created

確認

$ kubectl get service mysql

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysql ClusterIP 10.27.248.78 <none> 3306/TCP 10m

ちゃんと動いていますね。


WordPress をセットアップする


wordpress.yaml

apiVersion: extensions/v1beta1

kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
replicas: 1
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- image: wordpress
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: mysql:3306
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
gcePersistentDisk:
pdName: wordpress-disk
fsType: ext4

デプロイする

$ kubectl create -f wordpress.yaml

deployment "wordpress" created

確認

$ kubectl get pod -l app=wordpress

NAME READY STATUS RESTARTS AGE
wordpress-3479901767-gz54d 1/1 Running 0 10m


WordPress サービスを公開する

ここまでで、クラスター内にWordPressを構築しましたが、まだコンテナを外部から見れるようにする必要があります。

公式ドキュメントより


WordPress コンテナは、外部 IP アドレスを持たないため、現在はクラスタ外からアクセスできません

ロードバランサ(課金対象)を使用して WordPress アプリケーションをインターネットからのトラフィックに公開するには、type:LoadBalancer のサービスが必要です。


外部に見せるための課金対象のロードバランサを設定する必要がありました。


wordpress-service.yaml

apiVersion: v1

kind: Service
metadata:
labels:
app: wordpress
name: wordpress
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: wordpress

マニフェストをデプロイすると、ロードバランサが作成されます。

$ kubectl get svc -l app=wordpress

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
wordpress LoadBalancer 10.27.241.164 35.225.XXX.XXX 80:30370/TCP 2m

このEXTERNAL-IPがパブリック IP アドレスになります。


外部からアクセス

スクリーンショット 2018-01-08 23.31.37.png

成功です。


料金について

WordPressをリーズナブルに使いたいというモチベーションでやってきたのですが、このチュートリアルを元に作った場合、永続ディスク、ロードバランサ共にお金が発生します。

現在のレート(1USD=112.56JPY)に換算すると

200GBの永続ディスク:一ヶ月あたり約1,172円 

(2個用意しているので、約2,334円)

ロードバランサ:一ヶ月あたり約2000円

合計一ヶ月あたり約4,300円です。

さくらのレンタルサーバと比較すると高いですね。


Kubernetesでブログを運用するタイミング

公式ドキュメントにも書いてあるように、そもそもKubernetes Engineは、トラフィック量が多いサイトで、コンテナによる自動スケーリングとパフォーマンスのメリットを活用したい場合に最適なので、ブログのアクセスが増えてパフォーマンスが気になる時にKubernetesを使うのがいいですね。