2014-05-19

静的ファイルの配信を Google Cloud Storage に移行しました

ブログの静的ファイルの配信を Amazon S3 + CloudFront の構成から、Google Cloud Storage へ移行してみました。Google Cloud Storage の方は単体で CDN 付なのでオブジェクトの ACL を一般公開設定にするだけで CDN 部分の設定が不要なのが便利です。

具体的には、Cloud Storage のコンソールで配信したいドメイン名でバケットを作成し、CNAME を c.storage.googleapis.com に向ければよいです。ドットを含む名前でバケットを作成する際は、それがドメインの所有権の確認が済んでいるドメイン以下である必要があるみたいです。
Bucket and Object Naming Guidelines - Google Cloud Storage

準備
Web UI はありますが細かい設定をしようとすると現時点では1ファイルずつしか設定できないので、速やかにCLIツールをインストールすることをお勧めします。

使用するコマンドは gsutil (Google Storage Util?) で、これのみインストールする方法もありますが gcloud コマンドからインストールすると自動更新対象になって良いと思います。gcloud コマンドのインストールは、Google Cloud SDK Quick Start で、インストール中にお勧めされるがままに進めると自動で gsutil も使用可能になると思います。

コマンド集

# バケット一覧
gsutil ls

# ヘルプ
gsutil help cp

# ファイルをアップロード
gsutil cp SRC DEST

# ディレクトリをアップロード
gsutil cp -r SRC_DIR DEST

# 今回アップロード時に使ったコマンド
gsutil -h "Cache-Control: public,max-age=31536000" cp -a public-read -z js,css,txt,html -r SRC_DIR gs://static.hidekiy.com/1/

setmeta が遅い
オブジェクトの新規作成 cp に比べてメタデータ (HTTP ヘッダー) の設定 setmeta は2倍~3倍ほど遅いように思ったので、配信を中断してよいのであればいったん削除してアップロードすると良いと思います。

遅い理由は、現在の ACL を読み取り、書き込みの2操作が余計に必要だからのようで、あらかじめバケットのデフォルト ACL を defacl で設定しておき、その設定のままで良いのであれば -n オプションを使って高速にメタデータを設定できるみたいです。

# gsutil help setmeta

-n          Causes the operations for reading and writing the ACL to be
             skipped. This halves the number of operations performed per
             request, improving the speed and reducing the cost of performing
             the operations. This option makes sense for cases where you want
             all objects to have the same ACL, for which you have set a default
             ACL on the bucket(s) containing the objects. See "help gsutil
             defacl".

gzip 済みで配信する方法
gsutil cp -z <ext,...> を使うと良いです。

デフォルト1時間になっている max-age を長くしたい
gsutil -h "Cache-Control: public,max-age=31536000" cp
で OK でした。cp の前に書くのがポイント。

全エッジサーバーからキャッシュを削除したい
オブジェクトを削除するとエッジサーバーにも伝搬するような挙動があるみたいです。これが公式仕様なのかは良く分かりません。

S3 との相違点
S3 では存在したアップロード先リージョンの指定がないので、その辺は Google が責任をもってデータを配置してくれるのだろうと思います。

追記 (2014/12/10)
データの保管されるリージョンはバケットの作成時に CLI で指定することが出来て、作成時に指定しなかった場合のデフォルトは US でした。+Shingo Ishimura さんご指摘ありがとうございます。
mb - Make buckets - Google Cloud Storage — Google Cloud Platform

また、S3 には存在したデータ喪失の可能性が上がるのを認めることでコストを下げるストレージタイプ (Reduced Redundancy Storage) の代わりに、耐久性ではなく可用性 (Availability) を下げるストレージタイプが Google Cloud Storage にはあるみたいです (Durable Reduced Availability Storage)。

QUIC 対応
とくに頼んでないですが Alternate-Protocol:80:quic になっているので可能な場合は QUIC で配信してくれるみたいです。


リンク
Concepts and Techniques - Google Cloud Storage — Google Cloud Platform
GoogleAppEngine - GCP エッジキャッシュ - Qiita

2014-05-11

Google Cloud DNS を使ってみました

Google が 2014/3/25 発表した Google Cloud DNS を個人用ドメイン hidekiy.com で使い始めてみました。値段も AWS に比べて少し安く設定されているみたいです。

2014/5/11 時点

Amazon Web Services
0.50 USD(ホストゾーンごと)/月 – 最初の25のホストゾーン
0.10 USD(ホストゾーンごと)/月 – それ以上のホストゾーン
0.500 USD(100万クエリごと)-最初の10億クエリ/月
0.250 USD(100万クエリごと)-10億クエリ以上/月

Google Cloud Platform
Managed Zones: 0-25  $0.20 per managed zone per month
Managed Zones: 25+  $0.10 per managed zone per month for each additional zone after 25.
Queries: 0-1 billion  $0.40 per million queries.
Queries: over 1 billion  $0.20 per million queries per month.

AWS Route 53 の SLA (Service Level Agreement) は 100% Available なことで有名ですが、先日の以下の件について、何ら公式発表はなく、何も起こっていないかのように処理されているようなので、個人的に AWS の極東地域用の IP エニーキャストの運用についてちょっとした疑問が生じています。


手順
公式ドキュメント Getting started with Google Cloud DNS の通りで問題なく使えたので是非チェックしてみてください。gcloud コマンドも大変良くできていて、ログインはブラウザで認可ボタンを押すだけで済みます。

コマンド集

# コマンドを忘れていても適当に叩くとコマンド一覧が出るので安心
gcloud
gcloud dns

# きちんとヘルプ付いてる
gcloud dns managed-zone create -h

# managed-zone を作成
gcloud dns managed-zone create --description DESCRIPTION --dns_name DNS_NAME

# managed-zone 一覧
gcloud dns managed-zone list

# 現在のレコード内容を表示
gcloud dns records -z ZONE list

# レコードを編集
gcloud dns records -z ZONE edit

# 編集結果が反映されているかを確認
gcloud dns changes -z ZONE list

# 念のため自分でも確認
nslookup -debug -type=SOA example.com ns-cloud1.googledomains.com

Route 53 と異なる点
現在のところ Web 上の管理画面は無く、設定内容の確認にも CUI もしくは JSON API を使う必要があります。

Managed Zone 作成に先立ってドメインの所有権確認を TXT レコードか CNAME レコードを追加することで行う必要があります (Route 53 では無審査で作成できました)。

Managed Zone 料金は日割り計算されるようです (Route 53 では作成から24時間経過後から1か月分単位の請求になります)。Managed Zone の値段がちょっと違う気がします ($0.10 / month になってる?) が請求額が確定するまで様子見します。


Route 53 と違って Cloud DNS は IPv6 対応

C:\Users\Hideki>nslookup -type=aaaa ns-419.awsdns-52.com 8.8.8.8
サーバー:  google-public-dns-a.google.com
Address:  8.8.8.8

名前:    ns-419.awsdns-52.com


C:\Users\Hideki>nslookup -type=aaaa ns-cloud1.googledomains.com 8.8.8.8
サーバー:  google-public-dns-a.google.com
Address:  8.8.8.8

権限のない回答:
名前:    ns-cloud1.googledomains.com
Address:  2001:4860:4802:32::6a

メモ
SOA Serial は自動設定ではなく、変更したいのであれば明示的に変更する必要があり、そのためには、gcloud dns records edit 時の初期入力されている SOA レコードについての内容をそのまま使えば良さそうです。

お勧めする理由はありませんが SOA Serial を変更せずにレコードを変更することも出来ました。

自分の引っかかった点をメモしておくと、TXT, SPF レコードの値にスペースを含む場合は、ダブルクォートで囲む必要があります。正しい例:

{
   "kind": "dns#resourceRecordSet",
   "name": "hidekiy.com.",
   "rrdatas": [
       "\"v=spf1 +a +include:_spf.google.com ~all\""
   ],
   "ttl": 86400,
   "type": "TXT"
}

gcloud dns records edit の時のエディタの決定方法は、Windows の場合は .txt に対する関連付けにより、それ以外の OS では環境変数 EDITOR を参照するみたいです。

# google-cloud-sdk/lib/googlecloudsdk/core/util/edit.py

  if os.name == 'nt':
    subprocess.check_call([fname], shell=True)
  else:
    editor = os.getenv('EDITOR', 'vi')
    # We use shell=True and manual smashing of the args to permit users to set
    # EDITOR="emacs -nw", or similar things.
    subprocess.check_call('{editor} {file}'.format(editor=editor, file=fname),
                          shell=True)

gcloud dns records edit で保存する JSON ファイルで文法エラーが起こった時は、%TEMP% ディレクトリや /tmp を見に行くと最近作られた *.txt のファイルが残っているはずなのでそれで編集内容を救出できると思います。

リンク
Google Cloud DNS
Amazon Route 53