広告

GKEとcloudSQLでWordPressを構築してみた

GCP

今回は実際にKubernetesを使って、何かを作ろうと思って、シナリオを考えました。
手頃なオープンソースソフトウエアでいいかなと思って、WordPress(ブログサイトを作るもの)にしました。

構成

構成としては、以下のように考えています。

  • GCP(Google Cloud Platform)のマネジッドサービスのGKE(Kubernetes)を使用
  • WordPressはPodとして稼働(3レプリカ)
  • DatabaseはGCPのマネジッドサービスのcloudSQLを使用
  • WordPressとcloudSQLはGCP内部ネットワーク(VPC)を通じて通信

構成図:

WordPressOnGKE

前提条件

今回管理を作るための前提としては、以下のものを事前に用意する必要があります。

  • GCPの環境
  • GCPでGKEとcloudSQLの管理者権限
  • GCPの下記API有効化されていること
    • Service Networking API:プライベートIP使用のため

リソースの作成

GCPで以下のリソースを作成する必要があります。

  • GKE
  • cloudSQL

以下で作成方法について、説明していきます。

GKEの作成

今回WordpressとcloudSQLの通信は内部ネットワークを使用することを前提としているので、GKEはVPCネイティブで作成する必要があります。
VPCネイティブでGKEを作成する時に、--enable-ip-aliasオプションを付けて作成すればいいです。

下記作成コマンド例を適切に修正し、GCPのcloudshellで実行すればいいです。
※cloudshellの起動はこちらをご確認ください。

作成コマンド例:

# GKE cluster名:demo-cluster
# enable-ip-alias:VPCネイティブ
# create-subnetwork:サブネット作成
# サブネットのプライマリIP範囲(Node用):"10.0.0.0/20"
# サブネットのセカンダリIP範囲(Pod用):"10.1.0.0/16"
# サブネットのセカンダリIP範囲(Service用):"10.2.0.0/20"
gcloud container clusters create demo-cluster \
        --no-enable-autoupgrade \
        --zone="asia-northeast1-a" \
        --enable-ip-alias \
        --create-subnetwork name="gke-subnet",range="10.0.0.0/20" \
        --cluster-ipv4-cidr="10.1.0.0/16" \
        --services-ipv4-cidr="10.2.0.0/20"

... 5分ほどで作成可能です。

cloudSQLの作成

cloudSQLの作成はコマンドでプライベートIPのみ持っているcloudSQLを作成します。
※プライベートIPを持たせるための設定は、現時点beta版のコマンドしかできないので、gcloud beta sql instances createを使用しております。

参考情報

下記作成コマンド例を適切に修正し、GCPのcloudshellで実行すればいいです。

作成コマンド例:

# cloudSQLリソース名:demo-db
# tier:sql用仮想マシンのタイプ(スペック)
# region:リソースのリージョン
# database-version:データベースの種類とバージョン
# root-password:mysqlのrootユーザーパスワード
# network:プライベートIPのVPCはdefaultを使用する
# no-assign-ip:global ip割り振らない
gcloud beta sql instances create demo-db \
        --tier="db-n1-standard-1" \
        --region="asia-northeast1" \
        --database-version="MYSQL_5_7" \
        --root-password="t0Dq9rkNIro" \
        --network="default" \
        --no-assign-ip

...5分ほどかかります

これで作成されたら、cloudSQLはプライベートIP持ちの形式で作成されます。
作成後、cloudshellコンソールに結果が表示されます。そのうちのPRIVATE_ADDRESSに表示されたIPをメモしておきましょう。
これは、wordpressのDB接続に使用されます。

以下のコマンドで直接IP取得できます。(スクリプトとかには使えるかと)

gcloud sql instances list --filter="name=demo-db" | awk '{print $6}' | sed -e '1d' | head -n 1

wordpress用のDBとユーザーの作成

wordpress用のDBとユーザーを事前に用意する必要があります。
今回作成したcloudSQLの実質はMySQLなので、mysqlクライアントから接続して作成してもいいですが、gcloudコマンドも簡単に作成できます。

データベース作成

# データベース名:wp-database
# instance:対象cloudSQLを指定
# charset:データベースの文字コード種類
gcloud sql databases create wp-database --instance=demo-db --charset=utf8

ユーザー作成

# username:demouser
# instance:対象cloudSQLを指定
# password:パスワード指定
# host:接続元許可リスト、"%"はすべて許可
gcloud sql users create demouser --instance=demo-db --password=demouserpass --host="%"

※今回作成したcloudSQLはプライベートIPしか持たないので、--host%に設定しても、プライベートネットワークしか接続できないので、セキュリティは担保できるかと思います。

公開用global IPの作成

次は、kubernetesのloadbalancer用のglobal ipを用意します。

作成コマンド例:

# globalIPリソース名:wordpress-ip
# リソースのリージョン:asia-northease1(東京)
gcloud compute addresses create wordpress-ip --region="asia-northeast1"

このIPは後で作成するKubernetesのLoadbalancerに使うので、抑える必要があります。
以下のコマンドで、作成したIPを取得できます

# wordpress-ipのIPを取得する
gcloud compute addresses list --filter="name=wordpress-ip" | awk '{print $2}' | sed -e '1d' | head -n 1

ここまで、GCPリソースの準備は整えました。
次から、いよいよKubernetesのリソース作成に取り掛かります。

manifestの用意

今回の構成は、以下のものが必要です。

  • wordpressの設定情報を保持するためのsecret
  • wordpressデプロイするためのdeployment workload
  • wordpressへ接続&ロードバランシングするためのLoadbalancer Service

では、順番に例を挙げていきます。

secret

secretの作成は設定ファイルを用いて作ったほうが簡単なので、ここでは設定ファイルの方を用意します。
このsecretは、wordpressのDB接続設定の内容が書かれています。
ファイル名は任意なんですが、この例でwp-db-env.confをファイル名とします。
また、設定値はcloudSQL作成と設定した内容を書き換えればいいです。

WORDPRESS_DB_HOST=<cloudSQL privateIP>
WORDPRESS_DB_USER=demouser
WORDPRESS_DB_PASSWORD=demouserpass
WORDPRESS_DB_NAME=wp-database
WORDPRESS_TABLE_PREFIX=wp_

設定内容説明:

  • WORDPRESS_DB_HOST:cloudSQLのプライベートIP
  • WORDPRESS_DB_USER:wordpressデータベース接続用ユーザー
  • WORDPRESS_DB_PASSWORD:wordpressデータベース接続用ユーザーのパスワード
  • WORDPRESS_DB_NAME:wordpressデータベース
  • WORDPRESS_TABLE_PREFIX:wordpressのテーブルのプレフィックス(wp_そのままでいいです)

※WordPressの設定について、Dockerイメージの説明をご参照ください。

loadbalancer

Loadbalancerを作成する時に、先ほど作成したglobal IPを用意する必要があります。

ファイル名をwp-loadbalancer.yamlとします。

apiVersion: v1
kind: Service
metadata:
  name: my-nlb-service
  labels:
    app: wordpress
spec:
  selector:
    app: wordpress
  type: LoadBalancer
  loadBalancerIP: "<global ipのアドレス>"  # 先ほど作成したGCPのグローバルIPのアドレス
  ports:
  - port: 8080  # 受付ポート
    targetPort: 80  # Podへ転送するポート

deployment

WordPressのdeploymentを作成するためのmanifest

ファイル名をwp-deployment.yamlとします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wp-deployment
  labels:
    app: wordpress
spec:
  replicas: 3
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      containers:
      - name: wp-container
        image: wordpress:latest
        ports:
        - containerPort: 80
        lifecycle:
          postStart:
            exec:
              command: ["/bin/sh", "-c", "echo $(hostname) > /var/www/html/test.php"]  # wpのホームディレクトリにページファイルを作成する
        envFrom:  # wpがDBへ接続に使う環境変数
        - secretRef:
            name: wp-db-env  # 作成されたsecret名

kubernetesリソースの作成

GCPのcloudshellでは、kubectlのSDKはデフォルトで入っていますので、そのままで使用可能です。
しかも、ローカルのファイルはドラッグアンドドロップするだけで、cloudshellの~ディレクトリにアップロードできます。

そのため、以下のことをすれば、マニフェストの適用ができます。

  1. manifestファイルをcloudshellにアップロード
    2.GKEへ接続
  2. kubectl apply -f を実行する
    • secret作成
    • deployment作成
    • loadbalancer作成

manifestファイルのアップロード

先ほど作成した以下のファイルをドラッグアンドドロップでcloudshellへアップロードします。

  • wp-db-env.conf
  • wp-deployment.yaml
  • wp-loadbalancer.yaml

アップロード後、以下のコマンドで、ファイルがアップロードされていることを確認します。

cd ~
ls

GKEへの接続

cloudshellからGKEへ接続するために、以下のコマンドを実行します。

# 接続先:demo-cluster
# zone:GKEクラスタのzone
gcloud container clusters get-credentials demo-cluster --zone asia-northeast1-a

以下の内容が表示されたら、接続成功です。

Fetching cluster endpoint and auth data.
kubeconfig entry generated for <cluster name>.

リソース作成

順番に以下のコマンドを実行して、リソースを作成していきます。

# secret名はwp-db-envでsecretを作成
kubectl create secret generic wp-db-env --save-config --from-env-file=wp-db-env.conf

# deploymentとLoadbalancerを作成
kubectl apply -f ./wp-deployment.yaml -f ./wp-loadbalancer.yaml

リソースの確認

以下のコマンドで、リソースが作成されたことを確認します。

kubectl get pods  # podsがすべてrunning状態であることを確認
kubectl get secrets
kubectl get loadbalancer

以上で、環境の構築と設定がすべて完了です。

環境の確認

http://<loadbalancerのIP>:8080 でwordpressのサイトへアクセスしてみよう。
最初設定画面が表示されるはずです、画面に従って、設定を完成させてたら、wordpressのホームページが表示されます。

今回の例では、loadbalancerがロードバランシングしていることを確認するため、<ホームページ>/test.phpページを用意しています。
このペースにアクセスすると、pod名が表示されますので、アクセスごとに時間をちょっと置いてからアクセスすると、変わったことでロードバランシングされていることがわかります。

以上で完了です。

最後

今回の構成はシンプルだけど、汎用的なWebサイト公開の構成かと思います。
WordPressをWEBサーバに入れ替えれば、大量アクセスに耐えられるサイトが作ることが可能かと思います。

wordpressでは、基本管理者の操作はログインしてからになるので、ロードバランシングで他のpodに行くと、ログイン状態が変わります。
これの対処方法は一応以下の2つを考えています。

  • 管理者専用のGCEか、StatefulSetを作って、管理者専用のエンドポイントを用意して対応(管理者しかログインしない場合)
  • Loadbalancerに同じソース端末からの接続を維持する設定をする(誰でもログインできる場合)
    + ※設定自体は可能ってことは知っていますが、設定方法は筆者も調べないといけないので、また今後機会あれば書こうと思います

    • 2020/6/25更新:cloud LoadBalancerに「セッション アフィニティ」の設定で、セッションを維持することが可能ということがわかったのですが、作成済みのLoadBalancerは変更できないぽいです。継続調査中...
    • 2020/07/07更新:cloud LoadBalancerの「セッション アフィニティ」設定はインスタンスへのセッション維持らしいです。Podのセッション維持ではありませんでした。

いかがでしたでしょうか。

ここまで読んでいただいて、お疲れ様でした。

コメント

  1. Art より:

    看着好难。

タイトルとURLをコピーしました