Google Container Engine(GKE)が発表されたので、早速試してみた
つい先日、GoogleがGKEなるプラットフォームを発表しました。いわゆるDaaSの一種と見做して良いと思いますが、Dockerにご執心の身としては触らないわけには・・・ということで、早速試してみました。
このエントリでは、既存のdocker imageからザクッとcontainerを立ち上げ、外から見れるようにする所まで、おおまかに解説していこうと思います。
なお、今回は以前僕がdockerhubに上げたytnobody/docker-riji を使っていきます。
※基本的にGKEのGetting startedみて解かる人は、このエントリは読まなくて良さそうだと思います。
※ytnobodyは、執筆時点において、kubernetesについて全く教養を持ち合わせていません。
環境など
僕の試したクライアント環境はこんな感じです。
- Lubuntu-14.10 amd64 on VMware
Mac? 僕は常時VMで生活してる人間なのでよくわかりませんね。多分問題なく利用できるんじゃないですか(無責任
準備
先にやっておこう
予めやっておくこととしては、以下の作業が挙げられます。
- gcloud(Google Cloud SDK)を入れておく →参考:Installation and Quick Start
gcloud auth login
で Google Cloud Engine(以下GCE)にログインしておく- GCEに登録する →参考:Sign Up for Google Compute Engine
- GCEにプロジェクトを登録しておく
gcloud に preview コンポーネントを追加する
手始めに、gcloud
にkubarnatesを操作するためのサブコマンドたちを追加するため、preview というコンポーネントを追加します。
$ gcloud component update preview
その後、gcloud
に project id を食わせておきましょう。
$ gcloud config set project project-id-123
GKEクラスタを作る
次に、docker containerをまとめ上げるクラスタを作ります。your-cluster-nameのところ(=クラスタ名)は任意の名前を入れてください。
$ gcloud preview container clusters --zone=asia-east1-a create your-cluser-name
なお、この時に指定可能なzoneは、執筆時点で以下の通りです。(europe-west1-aは利用不可のようです)
- asia-east1-a
- asia-east1-b
- asia-east1-c
- europe-west1-b
- europe-west1-c
- us-central1-a
- us-central1-b
- us-central1-f
ここで指定したzoneとクラスタ名は非常に重要ですので、忘れないでください。
コマンドを実行すると、なんだかワチャワチャと情報が表示されますが、念の為以下のコマンドでクラスタのステータスを確認してみてください。
$ gcloud preview container clusters --zone=asia-east1-a list
ここまでやって、以下のような具合で出力されていれば、クラスタは無事に作成できています。
clusters:
- clusterApiVersion: 0.4.2
containerIpv4Cidr: 10.141.0.0/16
creationTimestamp: '2014-11-05T01:44:28+00:00'
description: ''
endpoint: 104.155.204.24
masterAuth:
password: n4Gmjl6nfjLXqFBM
user: admin
name: ytnobody01
nodeConfig:
machineType: f1-micro
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/backports-debian-7-wheezy-v20141021
nodeRoutingPrefixSize: 24
numNodes: 1
servicesIpv4Cidr: 10.0.0.0/16
status: running
zone: asia-east1-a
Google Developers Consoleから見てみる
「ほんとにクラスタはできてるの?」とご心配でしたら、Google Developers Consoleにアクセスして、今回新しく作ったプロジェクトを見てみましょう。
プロジェクトメニューが左側に展開されたら、その中から 計算処理>Container Engine という順にたどってみてください。そこには以下の画像のように、先ほど作ったGKEクラスタの一覧が表示されていますね。
ではクラスタ名をクリックしてみましょう。以下の画像のようになっていることと思います。
ここで一つ気がつく方もいるかもしれませんが、Cluster detailsのところに、インスタンスが2こ並んでますね。これについては後ほど解説します。
GKEで必須の概念
さて、このあたりで、GKEで必須となる考え方を説明します。
podとservice
GKEではpodとserviceという概念が大変重要です。これらをそれぞれ雑に解説すると、、、
pod
: docker containerの構成をまとめあげた概念。何個コンテナを用意するかとか、環境変数とか、EXPOSEするポートなんかは、全部コイツで集中管理する。service
: 外界とpodを接続するための設定をまとめあげた概念。手っ取り早く例えるなら、ロードバランサーです。
という感じです。ネットワーク構成的には、
+-Master--+ +----Node----+
| | | |
Internet <---->| service |<---->| container1 |
| | | |
+---------+ +------------+
のような具合です。上のAAはあくまで、コンテナを1個しか用意しないpodを使う場合なのですが、これがコンテナを4個とか用意する場合は、
+-Master--+ +----Node----+
| | | |
Internet <---->| service |<---->| container1 |
| | | container2 |
+---------+ | container3 |
| container4 |
+------------+
のようになるということです。
なお実際のところ、replication controllerという重要な概念もあり、同一構成のコンテナを複数持たせたい場合に利用するようです。
MasterとNode
前述のAAを見て、もう察しの良い方は感づいたとおもいますけど、先ほどDevelopers Consoleでみた2つのノードはMaster
とNode
に分かれており、それぞれはっきりと役割が分担されています。
Master
: serviceに記述された設定がそのままデプロイされる。ただし、任意のアプリケーションを動作させる等といったことはできない。Node
: podに記述された設定の通りにコンテナがデプロイされる。
Nodeには直接インターネットからアクセスすることはできず、必ずMasterにデプロイされたserviceを通してアクセスすることになります。
おそらく、急激に負荷が増大した際には、pod側のコンテナ数を増やしてリデプロイすることでスケールアップができる、という具合なのかと思います。(この辺、多分replication controllerを使うべきなのでしょうね)
定義すべき設定
podを定義してみる
googleのドキュメンテーションには「guestbook」のような例が有ったりするのですが、要するにpodとserviceを適切に設定すると、それっぽく見えるようになる、ということらしいです。
では、今回の例に利用するpod定義ファイルriji-master-pod.json
をお披露目しましょう。
{
"id": "riji-master",
"kind": "Pod",
"apiVersion": "v1beta1",
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "riji-master",
"containers": [
{
"name": "riji-master",
"image": "ytnobody/docker-riji",
"ports": [
{
"name": "riji-server",
"containerPort": 80,
"destPort": 3650,
}
],
"env": [
{
"name": "BLOG_REPO_URL",
"value": "https://github.com/ytnobody/Riji-Vanilla.git"
}
]
}
]
}
},
"labels": { "name": "riji", "role": "master" }
}
これらの定義は、manifestを参照しながら対比してみるとよいでしょう。特徴として、manifest/containers/image
に対し、dockerhubにおけるimage名を指定している点です。基本的にはdockerhubからイメージを落としてくることが前提にある様で、今回の範囲では、プライベートレジストリからのdocker pullへの取り組みについては確認できておりません。
このpodは、riji-masterというpodクラスタを構成し、コンテナを1つだけ含んでおり、80/tcpで待ち受けてるrijiを、3650/tcpに置き換えて、コンテナ外部からアクセスを受け付ける、という内容のものです。envについては、riji setup
直後のデータをRiji-Vanillaという名称でgithubにpushしてあるので、それをサンプルとして利用することにしました。
serviceを定義してみる
今度はservice定義ファイルriji-master-service.json
です。
{
"apiVersion": "v1beta1",
"kind": "Service",
"id": "riji-master",
"port": 3650,
"containerPort": "riji-server",
"selector": { "name": "riji", "role": "master" },
"createExternalLoadBalancer": true
}
serviceの定義については、googleのドキュメンテーションにはそれっぽいリファレンス的なものが見当たらなかったのですが、Kubernetesのgithub project pageに若干それらしいものがあったので、参考にしつつ記述を行いました。
このserviceは、外界に対し3650/tcpを開放し、そこに来たアクセスをriji-server podクラスタに流し込む、というものです。
動かしてみる
podおよびserviceをデプロイ
以下のコマンドで、podのデプロイを行います。
$ gcloud preview container pods \
--cluster-name=your-cluster-name \
create riji-master-pod \
--zone=asia-east1-a \
--config-file=./riji-master-pod.json
実行後、以下のような方法で、podの状態確認を行いましょう。多少時間がかかるかもしれませんが、StatusがRunningになっていれば、デプロイ完了です。
$ gcloud preview container pods -n your-cluster-name list -z asia-east1-a
ID Image(s) Host Labels Status
---------- ---------- ---------- ---------- ----------
riji-master ytnobody/docker-riji xxx.internal/100.110.120.130 name=riji,role=master Running
次に、serviceをデプロイします。
$ gcloud preview container services \
--cluster-name=your-cluster-name \
create \
--zone=asia-east1-a \
--config-file=./riji-master-service.json
実行後、こちらもserviceの状態確認を行いましょう。
$ gcloud preview container services -n your-cluster-name list -z asia-east1-a
ID Labels Selector Port
---------- ---------- ---------- ----------
riji-master name=riji,role=master 3650
このように、指定したportが表示されていればOKです。
firewall設定を調整する
「よし、アクセスしてみよう!」と思ったはいいけど、実際MasterノードのIPの3650/tcpにアクセスしてみると、timeoutします。
ちょっと調べた末にたどり着いたのは「firewallで3650/tcpへのアクセスを許可する」という作業。とはいえ、これもコマンド一発で済ませられます。
$ gcloud compute firewall-rules create riji-allow-rule --allow tcp:3650
多少時間がかかりますが、以下のような表示が出てくればOKです。
Created [https://www.googleapis.com/compute/v1/projects/your-project-123/global/firewalls/riji-allow-rule].
NAME NETWORK SRC_RANGES RULES SRC_TAGS TARGET_TAGS
riji-allow-rule default 0.0.0.0/0 tcp:3650
アクセスしてみる
さて、ここまで出来たら、あとはアクセスするだけ・・・なのですが、じゃあどこにアクセスすればいいんでしょう?
それを知っているのは、GCEのforwarding ruleです。以下のコマンドでアドレスを確認してみましょう。
$ gcloud compute forwarding-rules list
NAME REGION IP_ADDRESS IP_PROTOCOL TARGET
riji-master asia-east1 130.211.241.18 TCP asia-east1/targetPools/riji-master
この場合、 http://130.211.241.18:3650 へアクセスすれば良いことになります。早速アクセスしてみましょう。(なお、このアドレスはytnobodyがGKEを使って押さえているので、実際はみなさん自身のアドレスで確認してください。)
無事にrijiのサンプル記事が出てきましたでしょうか?ちゃんと見れたら、目的達成です。おめでとう。おめでとう。
実際使ってみた感想
GKEはエンタープライズ向けのDaaSという印象を受けました。実際のところ、今回構築したクラスタはレイテンシ面において大変優れているし、おそらく今回試さなかったreplication controllerを使うことで、より一層柔軟なスケーリング対応が可能となるはずです。
安定性、速度、柔軟性では、おそらくかなり優れていると思いますが、カジュアルさは一切ありませんでしたね。UX/UIの観点からみるに、正直Developers Consoleは使いやすいとは言えないですし、ドキュメンテーションもあっさりした内容で、深く掘り下げるには物足りない。
カジュアル用途、小規模用途には、すでに当ブログで紹介した tutumのほうが良さそうに思えます。しかし、大規模なコンテナクラスタを管理するとなると、GKEは良い選択肢となり得るでしょうね。