DRYな備忘録

Don't Repeat Yourself.

【GCP】Google Container Engineで Hello, World

Google Container Engineとは

Google Container Engine へようこそ。Container Engine は、Google がコンテナベース分散システムを構築、実行してきた経験から生まれたもので、Google のもっとも強力な内部システムのいくつかをベースにしています。これを使えば、Google のエンジニアと同じようにコンテナを開発、管理できます。

コンテナベースのコンピューティングでは、アプリケーション デベロッパーは、デプロイやホスト環境への統合ではなく、アプリケーションコードに力を注ぐことができます。しかも、アプリケーションは、ほとんど制約を受けずに作ることができます。プラットフォームは堅牢で、計算資源をすばやくプロビジョニングし、アプリケーションを簡単に管理できます。

自作のdocker imageさえあればいいのかな?

Google が Container Engine の開発で重点を置いたのは、ツールの開発と処理の制御です。同時に、負荷を移動しやすくして、コンテナ化されたアプリケーションをマルチクラウドで実行できるようにしたいと思いました。そこで、私たちはオープンソーステクノロジーの Kubernetes をサポートする形で Container Engine を設計し、アプリケーションをマルチクラウドで実行できるようにしました。

コンテナ化されたアプリケーションとあるから、やっぱり更新はdocker imageなのかな。あと、Kubernetsってなに。

Kubernetsとは

Kubernetes is an open-source system for automating deployment, operations, and scaling of containerized applications.

なるほど。わからん。やってみりゃわかんだろ。やりながらいろいろ読もう。

参考

以下、ログです

まず、gcloudとkubectlをインストール

Container Engine コンテナクラスタを作成

f:id:otiai10:20160409031015p:plain

f:id:otiai10:20160409031048p:plain

コンテナクラスタとは、コンテナが動くpodと呼ばれる単位が動く仮想ホストのクラスタ。podというのは、複数のコンテナがお互いにネットワークなど見れる単位でまとまったもの。それはアーキテクチャ上はdocker machine相当の概念だけど、オペレーションそのものを行う対象はdeploymentという概念なので、ちょっと違う。

デプロイしたいDockerイメージをつくる

これは別にGKEに限った話ではなく、単にローカルでdocker imageをbuildしてくださいという作業。

アプリケーションはなんてことないソースです

% cd $GOPATH/src/github.com/otiai10/gcpx/gkex/hello
% vi main.go
% vi Dockerfile
% docker-machine create just-for-build -d virtualbox
% eval $(docker-machine env just-for-build)
% docker build -t gcr.io/otiai10-playground/test-1:v1 .
# イメージレジストリサービスにgcr.ioを使うので、名前もそうしておく
% docker images
# gcr.io/otiai10-playground/test-1 というイメージができてるはず

これを、gcr.ioに登録する

GKEから参照できる、プライベートなイメージレジストリgcloudコマンドを使ってpushできる

% gcloud docker push gcr.io/otiai10-playground/test-1:v1

そうすっと、コンソールから確認できる(図は、v2タグもpushしてるけど)

f:id:otiai10:20160409033428p:plain

登録したイメージを使って、deploymentをつくる

deploymentをつくると、コンテナクラスタのなかにpodがつくられる。もう動いてる状態。

% kubectl run test-1 --image=gcr.io/otiai10-playground/test-1:v2 --port=8080

docker run相当のことを、コンテナクラスタに対して行うようなもの。ただし、コンテナクラスタに出来上がるのは、deploymentという概念と、それが稼働しているひとつのpodになる。

kubectl runのリファレンスはこちら kubectl run - Kubernetes

deploymentを確認。

% kubectl get deployments
% kubectl get deployments
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
test-1    1         1         1            1           50m
%

すでにコンテナクラスタ上に稼働しているpodがつくられている

% kubectl get pods
NAME                      READY     STATUS    RESTARTS   AGE
test-1-2840955185-mjsux   1/1       Running   0          54m
%

ネットワーク的にアクセス可能にする

この状態だと、このdeploymentに紐付いたpodsはprivate IPアドレスだけ持っている状態なので、ネットワーク的にアクセス可能にするには、public IPアドレスが必要になる。Container Engineのコンテナクラスタは、もともとGCEそのものとほぼ同じだが、public IPを持たない仮想サーバの状態っぽい。ここに、serviceというレイヤーを投入して、public IPアドレスを付与し、deploymentを紐付ける必要がある。

% kubectl expose deployment test-1 --type="LoadBalancer"
service "test-1" exposed
%

LoadBalancerというタイプを持ったserviceをつくった

% kubectl get services
NAME         CLUSTER-IP      EXTERNAL-IP       PORT(S)    AGE
kubernetes   10.115.240.1    <none>            443/TCP    3d
test-1       10.115.246.11                     8080/TCP   39s
%

public IPアドレスの付与には数分かかるので、この時点ではまだない。待つべし。

kubernetesというserviceがすでにあるのは、このコンテナクラスタへの操作をうけつけるkubelet APIプロセスが生きてて、それはEXTERNAL IPを持ってないという意味。たぶんkubectlの内部でごにょごにょして(認証情報とプロジェクトIDとかつかってGCPからなんかもらうんだろうな)、さっきからkubectlコマンドでこのコンテナクラスタへいろいろできているんではなかろうか。

参考: 【kubectl】The connection to the server localhost:8080 was refused と叱られる - DRYな備忘録

そろそろpublic IPアドレスが付与されてるはず。

% kubectl get services
NAME         CLUSTER-IP      EXTERNAL-IP       PORT(S)    AGE
kubernetes   10.115.240.1    <none>            443/TCP    3d
test-1       10.115.246.11   130.211.164.125   8080/TCP   4m
%

いざ、アクセス

% curl http://130.211.164.125:8080?name=otiai10
Hello, otiai10!
%                                                                                                                                                                                                                           %

f:id:otiai10:20160409051408p:plain

念のため、service削除しとく

% kubectl delete service test-1
service "test-1" deleted

良い感じだ

雑感

  • Dockerイメージをデプロイし、deployment単位でscaleできるので、特殊なライブラリを必要とするサーバアプリケーションも簡単にスケーラブルにできる。良い。
  • 3年前とかにGCE使ったとき、ドキュメントも不親切だしコンソールのデザインもうんこで「ああぜんぜんAWSのほうがいいな」と思った覚えある
  • 今あらためてやってみると、ドキュメントめっちゃ丁寧だし、コンソールのデザインも(GCPのサービスへの慣れが必要だけど)ヘルプも多いし、良い。
  • なんか最近、getting started読んだら難なくgetting startedできることが多い
  • 前までめっちゃ苦労してたのに
  • getting started読んでその通りにするのにも、知識が必要なんだなあ、というのを実感してる
  • あんまり苦労しなくなっちゃったので、Hello,World系のブログ書く意味も無くなってしまった…
  • 概念が多くて理解するの大変だけど、分かると
    • serviceはpodに紐づくのではなくdeployに紐づく、とか
    • deployをスケールするとpodが増える、とか
  • すごい綺麗だし、雑に言って凄いなと思った
  • GCE生に使っても管理めんどいので、ぜったいこっちのほうがいいと思う
  • ContainerEngineからCloudSQLやCloudStorageへのアクセスってどうやんのかなー

DRYな備忘録として