rakumoコンサルティング部 Tech Blog

GCPの構築ノウハウをそろりと公開 コンサル部によるテックブログ

Google Cloud Storage (GCS)にIAMカスタムロールを設定する

rakumoコンサルティング部の小山(@koyhoge)です。

しばらくブログの投稿が滞ってしまいすいません。今回は Google Cloud Storage (GCS) で IAM によるアクセス制限をかけようとした際にハマったことを書きます。

GCS のアクセス制限には2種類ある

GCS にはバケット単位やオブジェクト単位でアクセス制限をかける機能があります。

https://cloud.google.com/storage/docs/access-control/iamcloud.google.com

Cloud IAM (Identity and Access Management) と呼ばれる、GCP 上で統一的にアクセス管理をする仕組みを利用するのが現在は通常です。

ただ、かつては GCP に IAM がまだ存在しなかったので、そのために GCS が独自にアクセス制限機能をもっていました。これはレガシー ACL (Access Control Lists) と呼ばれ、現在でも有効になっています。ACL と IAM は同時に使用することが可能ですが、ACL は過去の互換性のためにのみ有効になっているので、現在では IAM のみを使用してアクセス制限を実現することが推奨されています。

複数の権限をグルーピングする「ロール(役割)」

Cloud IAM は特定のアカウントやアカウントのグループに対して、機能ごとにアクセス許可を追加していく形で設定します。

https://cloud.google.com/iam/docs/overviewcloud.google.com

GCP の各サービスに関して、細かく権限を設定することができますが、それらを毎回ひとつずつ設定するのは大変なので、よく使われる基本的な権限をひとまとめにした「ロール(役割)」というものが定義されています。

(GCP のドキュメントでは「役割」という用語に統一されて翻訳されていますが、一般的にはロールと呼ばれることの方が多いように感じるので、この記事では「ロール」を採用します。)

https://cloud.google.com/iam/docs/understanding-rolescloud.google.com

Cloud IAM 以前に存在していた「オーナー」「編集者」「閲覧者」という区分は、現在はロールとして実現されています。他にもサービスによっては、あらかじめ設定されているロールが存在しています。

ユーザが任意の権限を組み合わせてロールを作ることもできます。これは「カスタムロール」と呼ばれます。自分の組織やプロジェクトに特有の、特定の権限のみをピックアップしてカスタムロールを作成することで、権限管理の設定をより楽にすることができます。

ロールを GCS バケットに設定する

ここからようやく本題に入ります。

最初に書いたように、GCS には Cloud IAM によるアクセス管理を設定できるのですが、そこでカスタムロールを指定しようとするとちょっとおかしなことになります。

その前に、まずはプリセットされたロールをを指定する方法を見てみましょう。ロールをセットするのに Web コンソールから行うことは現状ではできなくて、そのかわりに gsutil コマンドを使用する必要があります。

設定するには、以下のコマンドを発行します。

$ gsutil iam ch user:hoge@example.com:objectCreator gs://bucket-name 

ここでセットされる「objectCreator」というロール名は GCP 側ですでに用意されているものです。

gsutil iam ch ではカスタムロールを設定できない

それでは同じ方法でカスタムロールを設定してみましょう。

GCP コンソールの IAM 設定画面 → 役割からカスタムロールを作成すると、ID が

projects/<project_name>/roles/<数字>

というフォーマットで作成されます。

この ID を指定して、gsutil iam ch を実行してみると

$ gsutil iam ch user:hoge@example.com:projects/some_project/roles/99 gs://bucket-name 
BadRequestException: 400 Invalid argument

と Invalid argument エラーになってしまいました。いろいろ試してみましたが、gsutil iam ch コマンドでカスタムロールを設定することは、どうやらできないようでした。

JSONを用いてカスタムロールを設定する

一瞬あきらめかけていたのですが、ふと思いついて gsutil iam get/set で JSON ファイル経由でロールを設定してみたらうまくいきました。

まずは gsuilt iam get で権限情報を JSON で取得します。

$ gsutil iam get gs://bucket-name > iam.json

中身は以下のような JSON になっています。

{
  "bindings": [
    {
      "members": [
        "projectEditor:some-project",
        "projectOwner:some-project"
      ],
      "role": "roles/storage.legacyBucketOwner"
    },
    {
      "members": [
        "projectViewer:some-project"
      ],
      "role": "roles/storage.legacyBucketReader"
    }
  ],
  "etag": "CAg="
}

ここにカスタムロールを用いた権限を追加します。

{
  "bindings": [
    {
      "members": [
        "projectEditor:some-project",
        "projectOwner:some-project"
      ],
      "role": "roles/storage.legacyBucketOwner"
    },
    {
      "members": [
        "projectViewer:some-project"
      ],
      "role": "roles/storage.legacyBucketReader"
    },
    {
      "members": [
        "user:hoge@example.com"
      ],
      "role": "projects/some-project/roles/99"
    }
  ],
  "etag": "CAg="
}

「"role": "projects/some-project/roles/99"」の部分が今回追加したカスタムロールですね。

変更した JSON を再びバケットにセットします。

$ gsutil iam set iam.json gs://bucket-name

今度はエラー表示もなく、無事に設定されました。 もう一度 gsutil iam get しても、正しく更新されていることが分かります。

ということで、GCS バケットへのカスタムロールのセットには JSON を使うことで解決できます。

gcs-fuseでマウントしたディレクトリをWebDAVで公開しようとしてハマった話

rakumoコンサルティング部の小山(@koyhoge)です。

弊社のお客様で、WebDAV サーバのバックエンドとしてGoogle Cloud Storage(GCS)を検討したいという方がいて、こちらでもいろいろ調査を行ったのですが、その時にハマった事を書いておきます。

GCSをファイルシステムとしてマウントするgcs-fuse

GCSのバケット通常のファイルシステムとしてマウントするにはgcs-fuse というツールを使います。ユーザ空間で動作するファイルシステム FUSE の上で GCS APIを呼び出して、あたかも GCS バケットがローカルシステムにマウントされているかのように見せかけるわけですね。

Cloud Storage FUSE  |  Cloud Storage ドキュメント  |  Google Cloud

gcs-fuse のインストールは詳しく書きませんが、上記の記事を参照して下さい。

このブログでも以前に id:ksueki が解説とベンチマークの記事を書いています。

gcsfuse をインストールしたら、/etc/fstab に以下のようなエントリを追加して

gcs-backet /mnt/gcsfuse gcsfuse rw,allow_other,file_mode=777,dir_mode=777,key_file=/root/credentials/gcs-access-key.json

以下のコマンドを実行すれば、無事に /mnt/gcsfuse に目的のバケットがマウントされるわけです。

$ sudo mount /mnt/gcsfuse

SELinux の制限でハマる

さて上でマウントされた /mnt/gcsfuse を WebDAV で公開しようと Apache httpd の設定ファイルとして /etc/httpd/conf.d/gcsfuse.conf を追加しました。

Alias /dav/ "/mnt/gcsfuse/"
<IfModule mod_dav.c> 
  DAVMinTimeout 600
  <Location /dav>
    DAV On
    EnableSendfile off
    AuthType Basic
    AuthName "Login WebDAV"
    AuthUserFile "/etc/httpd/conf/.htpasswd"
    Require valid-user
  </Location>
</IfModule>

ところが httpd を再起動して WebDAV クライアントでつないでみてもアクセスできません。httpd は応答を返しているのでDAVの設定が間違っているように思われました。

結論から言えば、これは SELinux の制限によるものでした。fuse でマウントしたディレクトリをhttpd で公開するなんてことは通常あまり行われないので、標準状態では対応していないわけですね。

SELinux が有効なままなんとかする

そこで SELinux を Permissive モードにしたり Disable したりするのは簡単ですが、正しいやり方を探ってみたくなりました。

まずは httpd からアクセス制限かけられているファイルがどういう状態になっているか確認します。

$ cd /mnt/gcsfuse
$ ls -Z
drwxrwxrwx. root root system_u:object_r:fusefs_t:s0    coldline-folder
drwxrwxrwx. root root system_u:object_r:fusefs_t:s0    nearline-folder
drwxrwxrwx. root root system_u:object_r:fusefs_t:s0    tmp1
drwxrwxrwx. root root system_u:object_r:fusefs_t:s0    tmp2

fuse でマウントしたファイルは fusefs_t というタイプを持っているようです。

SELinux のポリシーを調べるには sepolicy コマンドを使います。環境にインストールされていなかったので yum でインストールします。

$ sudo yum install selinux-policy-devel selinux-policy-doc

httpd に関する設定がスイッチでまとめられているようなので、それをリストアップします。

$ sepolicy booleans -a | grep httpd
<>
httpd_use_fusefs=_("Allow httpd to access FUSE file systems")
<>

httpd_use_fusefs というそのものズバリそうな設定が見つかりました。

現在値を確認すると案の定 off になっています。

$ getsebool httpd_use_fusefs
httpd_use_fusefs --> off

これを on にしてやればよさそうです。それには setsebool コマンドを使いますが -P をつけて再起動しても有効にしましょう。

$ sudo setsebool -P httpd_use_fusefs on

値を再度確認するときちんと on になっていました。

$ getsebool httpd_use_fusefs
httpd_use_fusefs --> on

これで SELinux が有効なまま、WebDAV で無事にアクセスできるようになりました。

GCSクライアントとしてMountain Duckを試す

Mountain Duck

rakumoコンサルティング部の小山(@koyhoge)です。

Google Cloud Storage(GCS)は、GCPにおけるオブジェクトストレージサービスです。AWS でいうところの S3、Azure でいうところの Blob Storage に相当します。

基本はAPIを使ってデータを読み書きしますが、FTP や sFTP のようにリモートディスクとしてアクセスするクライアントアプリが存在します。それを使うことでクラウドの詳しいことは知らなくても、単なるネットワーク外部ディスクのように扱えるわけです。

大抵は Amazon S3対応のものが多く、GCS対応を謳うものはさほど多くありません。今回 Mountain Duckというクライアントアプリを試したので、その使用感を書いてみます。

Mountain Duckとは

Mountain Duckは、スイスの iterate GmbH が開発している有料のネットワークディスククライアントアプリです。1ユーザー $39.00 からで、ユーザー数が増えるとボリュームディスカウントがあります。

mountainduck.io

Mountain Duckが特徴的なのは、アクセスするための独自ウィンドウを表示してそこで作業を行う多くのクライアントアプリと異なり、Windows の場合はエクスプローラーの、MacOSの場合は Finder の機能拡張として動作し、作業はエクスプローラー/Finderそのものを用いる点です。アクセスできる外部のファイルサーバの種類がぐっと増えた感じと書けば分かりやすいでしょうか。

対応しているプロトコル・サービスは現時点で15です。WebDAV, FTP, SFTP などメジャーなファイル転送プロトコルはもちろん、AWS S3、Azure Storage、Rackspace Cloud Files など多くのクラウドサービスにも対応しています。

ちなみに、iterate GmbH では通常のウィンドウ型のクライアントアプリも Cyberduck としてOSSで開発、公開しています。

https://cyberduck.io/cyberduck.io

無料試用版を試す

Mountain Duck は無料試用版があるので、早速試していきます。上記 Moutain DuckのWebページのダウンロードリンクからソフトをダウンロードします。今回は MacOS 版を試します。

MacOS版のダウンロード

ダウンロードが完了して dmg を展開すると、Mountain Duck.app が現れるので、アプリケーションフォルダーにコピーします。

Mountain Duck.app

Mountain Duck.app をダブルクリックで起動すると、まずはログイン時に自動起動するかどうかを尋ねるダイアログが表示されます。

自動起動確認ダイアログ

「続ける」を選択すると、次に接続設定のダイアログが表示されます。

接続設定ダイアログ

最上部のセレクトリストから「Google Cloud Storage」を選択します。

GCSを選択

Username の欄にアクセスしたいGCPプロジェクトの「プロジェクトID」を入力して、「Connect」をクリックします。

プロジェクトIDを入力

するとブラウザでGoogleアカウントの選択画面が表示され、目的のアカウントをクリックして、アプリの権限承認画面になります。

アカウントの選択

「許可」ボタンをクリックすると、認証コードが表示されます。

認証コードの表示

この認証コードをコピーして、Mountain Duckの「OAuth2 Authentication」ダイアログの「Authentication Code」欄にペーストします。

認証ダイアログ

「Login」ボタンをクリックすると、無事にプロジェクトが保持する GCS バケットがマウントされます。

マウントされたGCSバケット

ファイル転送をテスト

さてマウントもできたとことだし、Mountain Duck で実際にファイル転送をやってみます。とは言っても普通に Finder でコピーするだけですけどね。

まずは10.5MBの画像一枚をマウントされているフォルダーにコピーすると、数秒で完了しました。よしよし。

GCSにコピーされたファイル

GCP の管理コンソールで見ても無事に格納されています。

GCSコンソールでも確認

次に 25MBのファイルを10個まとめてコピーしてみたところ、30秒程度で終了したので、パフォーマンスも悪くないようです。

最後に 3300 個の小さいファイルがあるソースコードリポジトリのフォルダーをコピーするという意地悪をしてみたところ、途中でステータスバーが全く進まなくなってしまいました。やはり細かいファイルを大量にコピーするのはちょっとやり過ぎだったようです。

まとめ

Mountain Duck は、OS 標準のツールで様々なネットワークストレージをマウントできるソフトウェアです。アプリ独自の使い方を学習しなくて良い点が素晴らしいです。

GCP にカスタムドメインを登録する

rakumoコンサルティング部の小山(@koyhoge)です。

以前に掲載した「構築済のWordPressをGoogle App Engineに移行する(4)」で、GAE 上で動作する WordPress にカスタムドメインを設定する方法を解説しましたが、ドメインを登録する手順は記事中では省略していました。

今回は、その「カスタムドメインの登録」にフォーカスして解説したいと思います。

なぜドメイン確認が必要か

GCP や G Suite でカスタムドメインを使用するには、そのドメインが本当にそのアカウントが管理しているものかどうかを確認する必要があります。他人が自分のドメインを勝手に登録できてしまっては大変ですから、何らかの確認の仕組みは必須といえます。

GCP にも Cloud DNS というDNSマネージドサービスがありますので、これに使いたいドメインの管理を移管してしまえば、Google アカウントとドメインの紐付けは可能です。しかしドメイン管理は過去のしがらみから移管できないケースも多く想定され、ドメイン管理方法は従来のままで、その所有者を確認できる方法が求められました。

GCP、G Suite では、そのドメインの TXT レコードに確認コードを設定することで、所有者確認をする手法を取っています。ではそのやり方を順を追って見ていきましょう。

確認コードの取得

今回は GAE でカスタムドメイン使用したいので、GAE の管理メニューから「設定」を選びます。

App Engineメニュー

上部のナビゲーションから「カスタムドメイン」を選択し、その下の「カスタムドメインを追加」ボタンを押す。

GAEカスタムドメインの追加

「使用するドメインを選択する」に現在登録されているドメインのプルダウンメニューが表示されます。この例では前回登録した hoge.org が表示されています。

登録済みドメイン

今回は新しく koyhoge.org を登録したいと思いますので、プルダウンメニューを開いて「新しいドメインを確認…」を選択します。

新しいドメインを確認

するとすぐ下にテキスト入力が現れますので、追加したいドメイン koyhoge.org を入力して「確認」ボタンを押します。

ドメイン名の入力

するとブラウザの別ウィンドウ(タブ)で「ウェブマスターセントラル」が開きます。「ドメインレジストラまたはプロバイダを選択」をクリックすると多数のドメインサービス名が表示されます。

ウェブマスターセントラル

表示されるサービスは海外のドメインサービスが多いので、ご自身の使用しているものはないかもしれません。私の持っている  koyhoge.org は dotster.com で取得し、AWS Route 53 で管理をしているので「その他」を選びます。TXT レコードの登録の仕方は各ドメイン業者によって異なりますが、とりあえずは確認コードを取得できれば良いので、迷ったら「その他」を選択しておけば良いでしょう。

その他を選択

するとそのドメインの TXT レコードに登録する確認コードが表示されます。

ドメイン確認コード

ドメインのTXTレコードに追加

無事にドメイン確認コードが取得できましたので、今度はそれを DNS に登録していきます。

この作業は使用しているドメイン管理業者によって微妙に異なります。今回は koyhoge.org の管理をしている AWS Route 53 の例を出しますが、TXT レコードに先ほど取得した「ドメイン確認コード」を登録するという基本は変わりません。

まずは AWS のウェブコンソールにログインして、Route 53 の管理画面を開きます。koyhoge.org を選び、上部のメニューから「Create Record Set」ボタンを押します。

AWS Route 53

右部分の設定パネルで以下を行います。

TXTレコードの登録

Value 部分は

"google-site-verification=hZjnujnyfBJ2VOjwviu6Zamo8FcQD25UcvctMpYi1tg"

のようにダブルクォートで括ります。すでに SPF 用のレコード等が登録されている場合は、

"v=spf1 ip4:54.238.55.33 include:_spf.google.com ~all"
"google-site-verification=hZjnujnyfBJ2VOjwviu6Zamo8FcQD25UcvctMpYi1tg"

とダブルクォートで括ったものを、複数行で記述します。

最後に下部の「Save Record Set」ボタンを押して保存します。

確認完了

DNS の変更が反映されたら、先ほどのウェブマスターセントラル の画面に戻って「確認」ボタンを押します。Route 53 はほぼタイムラグなしに登録データが更新されますが、サービスによっては時間がかかるので注意して下さい。

DNSレコードの確認

無事に TXT レコードが登録されていれば、以下の画面が表示されてドメイン所有者の確認ができたことが分かります。

ドメイン所有者の確認

再び GCP の GAE 管理画面に戻って「続行」ボタンを押すと、ドメイン候補の中に登録した「koyhoge.org」が表示されています。

ドメイン追加完了

以上で、カスタムドメインを新たに登録する手順はおしまいです。GAE や Cloud CDN などカスタムドメインを使用できる場面では、登録されたドメインが候補として表示されるようになります。

参考

構築済のWordPressをGoogle App Engineに移行する(費用編)

rakumoコンサルティング部の小山(@koyhoge)です。

既存のWordPressGCPに移行する解説記事を投稿したところ、費用面での質問をいくつかはてブでいただいたので、今回の構成での費用面を解説した番外編をお送りします。

今回の例では月額およそ4,000円

クラウドにアプリケーションをデプロイするということは、使った分だけ支払う従量課金に移行するということですから、例えばブログにアクスセスが死ぬほど殺到すると、もちろんその分金額は上がるわけです。とはいえ、そんなにアクセスのない状態での大体の金額を知りたいという疑問が浮かぶのも理解できます。ということでとりあえず始めてみるにはこのくらいという概算を紹介してみましょう。

今回の構成で、アクセス数によらずどうしても費用がかかるのは Cloud SQL です。東京リージョンで g1-small インスタンスを常時立ち上げた際の費用は、継続利用割引が適用されて $0.0455/時間 x 24 時間 x 30日として $32.76、現在の円ドル換算レートだとおよそ 3,700 円程度になります。

その他のサービスの分、Google Cloud Storage (GCS)Google App Engine (GAE) の部分は使い方によって値段が変わってくるので一概には言えませんが、通常のブログの使用やアクセス数ならおそらく全部で数百円程度でしょう。ということで今回の GAE + GCS + Cloud SQLの例だと、月額 4,000 円程度でそこそこ負荷に耐えられる WordPress 環境を構築できることが分かりました。

もちろん更なるアクセスに耐えられるようにしたければ、いくつかやりかたがあります。

  • DBアクセスがボトルネックならば Cloud SQLインスタンスタイプを上位モデルにする
  • ものすごくアクセスが来て GAE の料金が跳ね上がるようなら GCS や GAE で Cloud CDN を利用する

課金額にキャップを設定する

アクセスが来すぎて課金がものすごいことになるのを心配する声も聞かれます。GAE では一日の使用量の上限をドル建てで制限できる機能がありますので、サービスが止まってよいのであればクラウド破産は避けることができます。

月額 4,000 円というのは他社の VPS サービスに比べるとちょっと高めですが、負荷対策に悩む必要がない安心料と考えれば、さほど高くないのではないかと思います。

構築済のWordPressをGoogle App Engineに移行する(4)

rakumoコンサルティング部の小山(@koyhoge)です。

既存のWordPressGCPに移行する解説記事の4回目(最終回)です。

前回で Google App Engine (GAE) 上に WordPress をデプロイできましたので、今回はその設定と既存データのインポートを行っていきます。

WordPress のインストール

前回は WordPress のインストール画面で終わっていたと思いますので、インストール作業を続けましょう。ここでいう「インストール」の意味は、ファイルの配置ではなくデータベースに対する各種テーブルの初期化になります。

サイトのタイトルやユーザ名などを入力するのは、通常の WordPress のインストールと同様です。

WordPressインストール画面

ページ下部の「WordPress をインストール」ボタンを押すと、インストール作業が完了しログイン画面になります。先ほど入力したユーザ名/パスワードでログインします。

WordPressログイン

プラグインの有効化

DB がまだ初期状態なので、WPonGAE をはじめとする各種プラグインはまだ有効になっていません。管理画面のプラグインページからそれらを有効化します。

まず WordPress の管理画面から「プラグイン」を選びます。

プラグインメニュー

以前の環境でインストールされていたプラグインが無効の状態でリストアップされていますので、すべて有効にします。今回「Batcache Manager」と「Google App Engine for WordPress」という2つのプラグインが新たに追加されているので、これも忘れずに有効化しておきます。

プラグインページ

データのインポート

いよいよ第1回でエクスポートしたバックアップデータを、新しく設置した WordPress にインポートします。

Google Cloud Storage にデータを置く

GAEプラグインでは、インポートデータを Google Cloud Storage (GCS) から読み込むようになっているので、まずは GCS にファイルをアップロードします。

GCP コンソールの左側メニューから「Storage」を選びます。

Storageメニュー

プロジェクトが管理している GCS バケットがリストで表示されます。その中に xxx.appspot.com という GAE プラグインが自動で作成したバケットがあるはずなので、そこをクリックします。

GCSバケットリスト

バケットブラウザが表示されるので、上部の「ファイルをアップロード」ボタンを押します。

バケットブラウザ

ファイル選択ダイアログが表示されるので、第1回でエクスポートしたXMLファイルを選択し、GCSにアップロードします。

アップロードの完了

インポートの実行

準備は整ったのでインポート作業を行いましょう。WordPress 管理画面の「ツール」から「インポート」を選びます。

インポートメニュー

Import WordPress という画面が表示されます。下部にXMLファイルの場所を入力するフォームがありますので、そこにさきほど GCS にアップロードしたファイル名を入力します。

インポート画面

GCS のデフォルトのバケット名まではすでに入っているので、それに追加する形でファイル名を入れます。

例)

gs://wp-on-gae-187408.appspot.com/

gs://wp-on-gae-187408.appspot.com/wordpresssample.wordpress.2017-11-20.xml

ファイル名を入力したら「Import from specified file」ボタンを押します。

すると既存の WordPress アカウントの移行をどうするかという確認画面が表示されます。デフォルトではアカウント情報もそのままインポートしてくれますので、そのままでかまわないでしょう。

アカウントの移行設定

下部に「Import Attachments」というセクションがあります。これは既存の WordPress にアップロードしているメディアファイルもインポートするかという設定になります。チェックを入れると、既存の WordPress からメディアファイルを GCS 上にコピーして、記事中のリンクをそちらに入れ替えてくれます。

Import Attachments

最後に「Submit」ボタンを押します。作業が進むと無事にインポートが終了し、記事が入った WordPress を確認できると思います。

DNS の切り替え

既存コンテンツの移行漏れがないか十分に確認を行った後、公開サイトを既存のものから GAE に切り替えます。 GAE でカスタムドメインを使用するには、まずそのドメインGCP に登録の後、GAE の管理画面で設定を行います。

ここではデプロイしたGAEインスタンスに「wpsample.hoge.org」を割り当てる作業を行ってみます。

まず GAE のメニューから「設定」→「カスタムドメイン」を選択し、

GAEのカスタムドメイン設定

「使用するドメイン」に、登録されているドメインが表示されていることを確認して下さい。まだドメインが登録されていない場合は、表示されるガイドに従ってTXTレコードを追加して、ドメインを登録する手順になりますが、ここでは省略します。

使用するドメインの選択

「続行」ボタンを押すと、「hoge.org」と「www.hoge.org」の2つの候補が表れます。今回はこれらには割り当てないので、右端の「☓」を押して削除します。

ホスト名の選択

割り当てたいホスト名「wpsample.hoge.org」を入力して、「マッピングを保存」ボタンを押します。

マッピングの追加

確認画面に変わるので「続行」ボタンを押します。

マッピングの確認

次のフェーズに移り、DNSに登録する内容が表示されます。いくつも表示されていますが、基本的には一番下の CNAME だけ設定すれば良いです。(DNS情報を登録するWeb管理画面によっては、A/AAAAとCNAMEは共存できないものもあります)

DNSの設定

そこで以下の内容に相当する DNS レコードを登録します。これはDNSの管理をどのように行っているかによって違うので省略します。

wpsample.hoge.org IN CNAME ghs.googlehosted.com.

しばらくすると CNAME 設定を GCP 側が認識して、GAEのカスタムドメインとして表示されます。

カスタムドメイン登録完了

GAE の注意点

WordPress 本体やプラグインの更新について

WordPress 本体、テーマやプラグインはけっこう頻繁に更新が行われます。WordPress の管理画面を見ると更新通知が目立つところに表示されので、どうしても更新しなきゃという圧が強まりますね。

ところが GAE ではデプロイした環境に対してファイルの追加や変更はできないので、WordPress 管理画面からの本体やプラグインのバージョンアップは行ってはいけません。というかできません。

ではどうするかというと、第3回で用意した GAE のデプロイ元のファイルを変更して、再度デプロイという流れになります。デプロイ元の WordPress を動作可能にしておいて、そちらの管理画面から本体、テーマ、プラグインの更新を行い、更新が完了したファイルツリーに対して再び

$ glcoud app deploy

を行えば良いわけです。

まとめ

4回にわたって、既存の WordPress を GAE に移行する作業を詳しく解説しました。GAE に環境を移行することには以下のメリットがあります。

VPS仮想マシン1台で運用している場合には、どちらが運用効率が良いかは判断が難しいところですが、アクセスの規模が大きかったり複数台で運用している場合ほど、GAE のメリットが大きくなってくると思います。

構築済のWordPressをGoogle App Engineに移行する(3)

rakumoコンサルティング部の小山(@koyhoge)です。

既存のWordPressGCPに移行する解説記事の3回目です。

前回の作業で GCP 環境のセットアップが終わりましたので、次に Google App Engine (GAE) 上に構築する WordPress の準備をしていきます。

WPonGAE のセットアップ

第1回で紹介した「WordPress on App Engine Starter Project (WPonGAE) 」を使って GAE 上に WordPress を構築していきます。

ここで一つ注意点があって、GAE の PHP は通常の環境 (Standard Environment) では PHP 5.5 で動作します。PHP 5.6 以上が必要な WordPress プラグインを使用している場合はこのやり方ではうまくいきません。その場合は Flexible Environment を用いてカスタムランタイムを利用することになりますが、この記事ではそのやり方については取り上げません。

GitHub から取得

まずは WPonGAE のソース一式を GitHub より取得します。これには git コマンドを使います。コマンドラインが苦手な方は GitHub Desktop などのGUI環境でも良いでしょう。

 git clone --recursive https://github.com/googlearchive/appengine-php-wordpress-starter-project.git

すると「appengine-php-wordpress-starter-project」という名前のディレクトリができます。以下にはいくつかのファイルとディレクトリがあります。

appengine-php-wordpress-starter-project_build_linux_mac.zip
appengine-php-wordpress-starter-project_windows.zip
appengine-wordpress-plugin/
app.yaml
batcache/
cron.yaml
databasesetup.sql
move_files_after_editing.bat
move_files_after_editing.sh
php.ini
README.md
wordpress/
wp-config.php
wp-memcache/

このディレクトリをGAEへの配布元として作業していきます。

$ cd appengine-php-wordpress-starter-project

WordPress の置き換え

まずは現在動作している WordPressディレクトリをコピーしてきて、WPonGAE の wordpress と入れ替えます。こうすることで既存環境にインストールされている各種プラグインも、そのまま GAE 上で動作するようになります。

$ rm -rf wordpress
$ cp -r original_wordpress ./wordpress

設定ファイルの変更

app.yaml の変更

まずは GAE の設定ファイルである app.yaml を変更します。先頭の application と version 行を削除します。

-application: your-project-id
-version: wpfromstarterproject
  runtime: php55
 api_version: 1

参考diff

これは WPonGAE が作られた後で、GAE 側の仕様が変わったことによります。現在では application と version は環境から渡すことになっており、app.yaml に記述することは推奨されません。

あと git clone した環境だと、.git/ ディレクトリに不要な大きいファイルがあるので、これを無視するように skip_files に追加します。

skip_files:
- ^(.*/)?\.zip$
- ^(.*/)?\.bat$
- ^(.*/)?\.sh$
- ^(.*/)?\.md$
- \.git/

wp-config.php の変更

次に WordPress の実行設定である wp-config.php を変更します。

WPonGAE に用意されている wp-config.php をベースにしても良いですが、これは WordPress 3.X のものであまりに古いので、既存環境の wp-config.php に変更を追加していくことにします。そのためまずは WPonGAE の wp-config.php を wp-config-gae.php にリネームして、既存の wp-config.php をカレントディレクトリにコピーします。

$ mv wp-config.php wp-config-gae.php
$ cp wordpress/wp-config.php .

wp-config.php をエディタで開いて修正を加えていきます。

まずはデータベースの設定から。現在の設定はおそらく以下のようになっていると思います。(4.9.1-ja)

/** WordPress のためのデータベース名 */
define('DB_NAME', 'my_wordpress_db');

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

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

/** MySQL のホスト名 */
define('DB_HOST', 'localhost');

その部分をこうします。

if (isset($_SERVER['SERVER_SOFTWARE']) &&
    strpos($_SERVER['SERVER_SOFTWARE'],'Google App Engine') !== false) {
    /** The name of the Cloud SQL database for WordPress */
    define('DB_NAME', 'my_wordpress_db');
    /** Live environment Cloud SQL login and SITE_URL info */
    /** Note that from App Engine, the password is not required, so leave i\
        t blank here */
    define('DB_HOST', 'localhost:/cloudsql/wp-on-gae-187408:asia-northeast1:wp-on-gae-mysql');
    define('DB_USER', 'my_wordpress_user');
    define('DB_PASSWORD', 'xxxxxxxx');
} else {
    /** The name of the local database for WordPress */
    define('DB_NAME', 'my_wordpress_db');
    /** Local environment MySQL login info */
    define('DB_HOST', 'localhost:/cloudsql/wp-on-gae-187408:asia-northeast1:wp-on-gae-mysql');
    define('DB_USER', 'my_wordpress_user');
    define('DB_PASSWORD', 'xxxxxxxx');
}

if 文の最初のブロックが GAE で動作する場合の設定で、else 以降のブロックがそれ以外の設定になっています。上記の例では、この後の都合で両者とも同じ設定値になっていますが、ローカルで動かしたときだけ DB 設定を変えたい等の場合は、下のブロックを変更して下さい。

DB_NAME, DB_USER, DB_PASSWORD は、それぞれご自身の環境のものに書き換えます。

GAE の場合の設定の以下の記述ですが、

    define('DB_HOST', 'localhost:/cloudsql/wp-on-gae-187408:asia-northeast1:wp-on-gae-mysql');

これは * 実行マシンの * /cloudsql ディレクトリに存在する * 「wp-on-gae-187408:asia-northeast1:wp-on-gae-mysql」 という名前のUNIXドメインソケット に接続するという意味になります。第1回目で作成した Cloud SQLの「インスタンス接続名」をここで使用します。

次に WordPress のサイト URLを、アクセスされた URL から自動設定するために以下を挿入します。

// Determine HTTP or HTTPS, then set WP_SITEURL and WP_HOME
if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVE\
R_PORT'] == 443) {
    $protocol_to_use = 'https://';
} else {
    $protocol_to_use = 'http://';
}
define( 'WP_SITEURL', $protocol_to_use . $_SERVER['HTTP_HOST']);
define( 'WP_HOME', $protocol_to_use . $_SERVER['HTTP_HOST']);

GAEには処理の定期実行の仕組みがありますので、WordPressによる cron の疑似実行は無効にします。

/**
 * Disable default wp-cron in favor of a real cron job
 */
define('DISABLE_WP_CRON', true);

WPonGAE に含まれる batcache プラグインのための設定を追加します。

// Required for batcache use
define('WP_CACHE', true);
// configures batcache
$batcache = [
    'seconds' => 0,
    'max_age' => 30 * 60, // 30 minutes
    'debug' => false
];

以上で wp-config.php の編集はおしまいです。

インストールスクリプトの実行

WPonGAE 用意されているスクリプト "move_files_after_editing.sh" を実行します。これは各種プラグインを ./wordpress 以下に移動します。

$ sh move_files_after_editing.sh

WordPress 側の準備はこれにて完了です。

Cloud SQL Proxy のインストール

Cloud SQLのデータベースに接続するには、以下の2つの方法があります。

  • 送信元IPアドレスによって承認する
  • cloud_sql_proxy コマンドを用いてトンネルを作成する

GAEの環境では、後者の cloud_sql_proxy 経由になりますので、手元でも同じ環境を作っておくほうが何かと便利でしょう。ということでローカルに Cloud SQL Proxy をインストールします。

Cloud SQL Proxy については以下の Google のページを参考にします。

https://cloud.google.com/sql/docs/mysql/connect-admin-proxy?hl=jacloud.google.com

Cloud SQL Administration APIを有効にする

以下のURLの管理画面から Cloud SQL Administration APIをプロジェクトに対して有効にします。

Cloud SQL Administration APIの有効化

プロキシをインストールする

cloud_sql_proxy のソースコードGitHub で公開されていますが、各種プラットフォーム毎のバイナリも用意されていますので、そちらを用います。今回は Linux 64ビット環境で用いますので以下のコマンドでダウンロードします。

$ wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
$ chmod +x cloud_sql_proxy

アプリケーション認証情報を取得

Cloud SQL Proxyは Cloud SQLに接続する際にGCPの認証を必要とします。このために専用のサービスアカウントを作成する方法もあります(上記Googleの解説ではそのやり方について説明しています)。今回は Cloud SDK の認証情報を使用する簡易な方法でいきます。

まずは gcloud コマンドで application-default の認証を行います。

$ gcloud auth application-default login
Go to the following link in your browser:

    https://accounts.google.com/o/oauth2/auth?<後略>

Enter verification code:

ブラウザが開く環境ならおそらく自動で認証画面が表示されるでしょう。リモートログインしている環境などブラウザを開けない状況では、上記のように認証用の URL が表示されるので、それをブラウザで開いて許可を行った結果、表示される認証コードを入力します。

認証許可ダイアログ 認証コードの表示

Enter verification code: XXXXXXXXXX

Credentials saved to file: [/home/koyama/.config/gcloud/application_default_credentials.json]

These credentials will be used by any library that requests
Application Default Credentials.

これにより割り当てられた認証情報用いて cloud_sql_proxy コマンドは Cloud SQL に接続できるようになります。

プロキシを起動

cloud_sql_proxy コマンドは、オプションにより TCP ソケットと UNIX ドメインソケットのどちらかを使用して接続を受け付けます。ここでは GAE の実行環境と同様に UNIX ドメインソケットを用います。

まずはソケットが置かれるディレクトリを作成します。これは GAE の環境に合わせて「/cloudsql」固定です。

$ sudo mkdir /cloudsql
$ sudo chmod 777 /cloudsql

作成したディレクトリを指定して cloud_sql_proxy コマンドを起動します。

$ cloud_sql_proxy -dir=/cloudsql &

現在有効な Cloud SQL インスタンスを調べて、そこに接続するソケットを自動的に /cloudsql に作成してくれます。

Cloud SQLにデータベースインスタンスを作成

第2回目で Cloud SQL の設定を行いましたが、ここにはまだ DB インスタンスが何もない状態ですので、これを作っていきます。

以下の設定で DB インスタンスを作成します。

  • ユーザ: my_wordpress_user
  • パスワード: xxxxxxxx
  • データベース名: my_wordpress_db

まずは cloud_sql_proxy 経由で Cloud SQLMySQL に接続します。<ROOT_PASSWORD> の部分は第2回の「Cloud SQLの設定」の時に生成したパスワードを使います。

$ mysql -u root -p<ROOT_PASSWORD> -S /cloudsql/wp-on-gae-187408:asia-northeast1:wp-on-gae-mysql

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 144326
Server version: 5.7.14-google-log (Google)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

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>

無事に接続でき、mysql> プロンプトが表示されました。

まずは DB インスタンスを作成します。

mysql> create database my_wordpress_db;

次にユーザーを作成します。

mysql> create user my_wordpress_user;

作成したユーザに DB へのアクセス権限を与えます。

mysql> grant all on my_wordpress_db.* to my_wordpress_user@'%' identified by 'xxxxxxxx';

これで wp-config.php に記述した情報で、データベースにアクセスできるようになりました。

GAE へデプロイ

さて長くなりましたが、いよいよ GAE に WordPress をデプロイします。

$ gcloud app deploy
Services to deploy:

descriptor:      [/home/koyama/work/appengine-php-wordpress-starter-project/app.yaml]
source:          [/home/koyama/work/appengine-php-wordpress-starter-project]
target project:  [wp-on-gae-187408]
target service:  [default]
target version:  [20171212t084527]
target url:      [https://wp-on-gae-187408.appspot.com]


Do you want to continue (Y/n)?

プロンプトに「y」と入力すると、作業中のプログレスバーが徐々に伸びていき、問題がなければ無事にデプロイが完了します。

Do you want to continue (Y/n)?  y

Beginning deployment of service [default]...
Some files were skipped. Pass `--verbosity=info` to see which ones.
You may also view the gcloud log file, found at
[/home/koyama/.config/gcloud/logs/2017.12.12/08.45.25.627575.log].
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 1732 files to Google Cloud Storage             ═╣
╚════════════════════════════════════════════════════════════File upload done.
Updating service [default]...done.
Updating service [default]...Waiting for operation [apps/wp-on-gae-187408/operations/9b5abc74-6bda-4c10-aae8
-2c6c00b6497f] to complete...done.
Updating service [default]...done.
Deployed service [default] to [https://wp-on-gae-187408.appspot.com]

You can stream logs from the command line by running:
  $ gcloud app logs tail -s default

To view your application in the web browser run:
  $ gcloud app browse

表示されている URL にアクセスすると、無事に WordPress のインストール画面が出てくることを確認できます。

WordPressインストール画面

次回はデプロイされた WordPress の設定と既存のデータのインポートを行います。