無料で使うDocker PaaS ~Google Container Engine~
Docker使ったサービスを公開したい!けどお金はかけたくない!HerokuやOpenShift Onlineのような6時間sleepも嫌だ! そんな贅沢な人のために、Google Container Engine(GKE)を無料で使う方法を検証しました。
初のGoogle Cloud Platform(GCP)、初めてのKubernetes利用だったため、プロジェクトの作成から、コンテナのデプロイまで全部書いてます。
全体的に、プロジェクト名やIP等、特に隠していません。(すでにプロジェクト削除済み)
前準備
以下のコマンドをインストールします。 jqコマンドは、gcloudコマンドの実行結果から必要な情報だけを抽出するために使ってます。なので任意です。
プロジェクト作成
まずプロジェクトを作成します。プロジェクト名は世界で唯一になっていないといけないようです。作成に1分程度かかりました。
$ gcloud projects create uphy-test Create in progress for [https://cloudresourcemanager.googleapis.com/v1/projects/uphy-test]. Waiting for [operations/pc.5401240501659590600] to finish...done.
プロジェクトを作ったら課金を有効にします。 ここだけはWebでやらないとだめっぽいです。 直感的に出来たので要点だけ。
- 請求先アカウントを作成(お支払>お支払の設定)
- Container Engineにアクセスして、作成したプロジェクトを選択して、「課金を有効化する」をクリックする
CLI設定
ここから先で実行するコマンドで、ゾーンというものを意識する必要があります。 ゾーンによって環境が微妙に違ったり、価格が異ったりするらしいです。 今回、無料の範囲で使いたいので米国リージョンを用いました。 米国リージョンにもいくつかゾーンがあるみたいだけどどれでも良さそう。 ひとまずus-central1-aを採用。 以降、各gcloudコマンドで毎回zoneを指定するのは間違いのもとなので、以下でデフォルトを設定しておきます。
$ gcloud config set compute/zone us-central1-a Updated property [compute/zone].
また同様にプロジェクトも先程作成したものを用いるようにします。
$ gcloud config set core/project uphy-test Updated property [core/project].
クラスタ作成
続いてGKEのクラスタを作ります。 GKEはKubernetesというDockerコンテナのオーケストレーションをするための管理ソフトウェアを用いています。 Kubernetesは、複数のノードにまたがるデプロイを行えます。その複数のノードの集まりをクラスタと呼んでいるようです。
ここで、GKEの無料枠を確認。 12ヶ月後以降ももちろん無料で使いたいので、「いつまでも無料のプロダクト」の条件に従って構築します。
Google Container Engine (抜粋)
5 ノード以下の基本クラスタ 基本クラスタは無料ですが、各ノードには Compute Engine の標準料金が適用されます。
Google Compute Engine (抜粋)
1 f1-micro インスタンス(1 か月あたり、米国リージョンのみ) 30 GB の HDD(期間合計)、5 GB のスナップショット(期間合計) 1 GB の北米から全リージョン宛て下りネットワーク(1 か月あたり、中国およびオーストラリアを除く)
GKEのノード = GCEのインスタンスと考えてよさそう。 上記から、クラスタ作成時のポイントは以下。
- f1-microを用いる
- ノード数は1
- HDD 30GB以内
※通信量が1GBと意外と少ないので注意して使いましょう。
ノード数は1にしなければなりませんが、仕様上いきなり1では作れないようです。まず最低の3で作成後、1に変更します。3,4分程度かかりました。
$ gcloud container clusters create --machine-type=f1-micro --disk-size=10 --num-nodes=3 test-cluster Creating cluster test-cluster...done. Created [https://container.googleapis.com/v1/projects/uphy-test/zones/us-central1-a/clusters/test-cluster]. kubeconfig entry generated for test-cluster. NAME ZONE MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS test-cluster us-central1-a 1.6.4 35.184.182.214 f1-micro 1.6.4 3 RUNNING
間髪入れずに1に変更!!!(この瞬間、もしかすると2ノード✕1時間分請求されるかもしれません。たぶん数円)
$ gcloud container clusters resize test-cluster --size=1 -q Resizing test-cluster...done. Updated [https://container.googleapis.com/v1/projects/uphy-test/zones/us-central1-a/clusters/test-cluster].
ノード数の変更はすぐには反映されないようです。1分くらいたって、以下のようにノード1個になりました。一安心。
$ gcloud container clusters list NAME ZONE MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS test-cluster us-central1-a 1.6.4 35.184.182.214 f1-micro 1.6.4 1 RUNNING
Kubernetes Web UIの利用
続いて、作成したKubernetesクラスタのWeb UIに接続してみます。 まずは接続のための準備。以下のコマンドで、~/.kube/configにGKEへの接続情報が記載されます。 これによりkubectlコマンドでGKE上のKubernetes環境を管理できるようになります。
$ gcloud container clusters get-credentials test-cluster Fetching cluster endpoint and auth data. kubeconfig entry generated for test-cluster.
続いてローカルの8001番ポートをGKEのWeb UIにプロキシします。
$ kubectl proxy
Starting to serve on 127.0.0.1:8001
http://localhost:8001/ui にアクセス。
Web UIでコンテナをデプロイしたり、状態を確認したりできます。
試しに見てはみましたが、この記事では以降Web UIは使いません。
コンテナのデプロイ
続いて、試しにCLIでnginxをデプロイしてみます。
nginx.deployment.ymlを作成。
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx spec: replicas: 1 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
以下のコマンドでdeploymentを作成します。
$ kubectl create -f nginx.deployment.yaml deployment "nginx" created
続いて動作確認のため、nginxにアクセスしたいのですが、 この状態ではポートが外部に公開されていないためアクセスできません。 公開する方法としてよくWebで見かけるのは、ロードバランサを用いる方法。 しかし!ロードバランサの費用はこちら なんと月額だと$18もかかる!こんな貧弱なサーバーに$18もかけるくらいならVPS借ります! 参考までに、お金がかかるロードバランサを用いた方法はこちらです。
有料注意
kubectl expose deployment nginx --port=80 --type="LoadBalancer"
ではどうやって無料で公開するのか。ロードバランサを用いず、ノードのポートを直接公開します!
nginx.service.ymlを作成。
kind: Service apiVersion: v1 metadata: name: nginx spec: selector: app: nginx ports: - name: http protocol: TCP port: 80 targetPort: 80 externalIPs: # 適宜変更 - 10.128.0.2
ここでポイントが2つ。
- selectorの値は、先述のdeploymentのlabelsと合わせる。
- externalIPsの値は適宜変更すること。ここの値にはノードの内部IPを用いる。コマンドで取得すると以下。
$ gcloud --format json compute instances list | jq -r '.[].networkInterfaces[].networkIP' 10.128.0.2
deploymentと同じようにサービスを作成します。
$ kubectl create -f nginx.service.yaml deployment "nginx" created
最後に、ノードのポートを開放します。今回はhttpなので80番。
$ gcloud compute firewall-rules create http-firewall --allow tcp:80 Creating firewall...|Created [https://www.googleapis.com/compute/v1/projects/uphy-test/global/firewalls/http-firewall]. Creating firewall...done. NAME NETWORK SRC_RANGES RULES SRC_TAGS TARGET_TAGS http-firewall default 0.0.0.0/0 tcp:80
コマンド実行完了後、すぐには反映されませんでした。1分くらい。
アクセスするためのノードの外部IPを調べます。
$ gcloud --format json compute instances list | jq -r '.[].networkInterfaces[].accessConfigs[].natIP' 35.184.37.161
curlで確認。
$ curl http://35.184.37.161 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...略... <p><em>Thank you for using nginx.</em></p> </body> </html>
アクセスできることを確認できました!
プロジェクト削除
検証完了したので、作ったものを削除します。 プロジェクトを削除しても、しばらくの間環境は生きているようなので、クラスタをまず削除。(プロジェクトだけで十分かも)
$ gcloud container clusters delete test-cluster The following clusters will be deleted. - [test-cluster] in [us-central1-a] Do you want to continue (Y/n)? Y Deleting cluster test-cluster...done. Deleted [https://container.googleapis.com/v1/projects/uphy-test/zones/us-central1-a/clusters/test-cluster].
引き続きプロジェクトも削除します。
$ gcloud projects delete uphy-test Your project will be deleted. Do you want to continue (Y/n)? Y Deleted [https://cloudresourcemanager.googleapis.com/v1/projects/uphy-test]. You can undo this operation for a limited period by running: $ gcloud projects undelete uphy-test
まとめ
Google Container Engineを無料で使う検証を行いました。 おそらくこれで完全無料で使えると思いますが、しばらくは請求情報をウォッチしておこうと思います。