お題
前回、クラスタ作るところまでやったので、いよいよアプリをGKE上にデプロイする。
環境
前回と同じ。
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.7", GitCommit:"dd5e1a2978fd0b97d9b78e1564398aeea7e7fe92", GitTreeState:"clean", BuildDate:"2018-04-19T00:05:56Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"9+", GitVersion:"v1.9.7-gke.6", GitCommit:"9b635efce81582e1da13b35a7aa539c0ccb32987", GitTreeState:"clean", BuildDate:"2018-08-16T21:33:47Z", GoVersion:"go1.9.3b4", Compiler:"gc", Platform:"linux/amd64"}
前提
- 自前でGCPプロジェクトは契約済み
- gcloudをローカルで使える状態になっている
実践
1)クラスタ作成
前回はクラウドコンソールで作成した。今回はgcloudコマンドで作成してみる。
$ gcloud container clusters create go-webapi-for-gke-study-cluster-1 --zone asia-northeast1-a
WARNING: Starting in 1.12, new clusters will have basic authentication disabled by default. Basic authentication can be enabled (or disabled) manually using the `--[no-]enable-basic-auth` flag.
WARNING: Starting in 1.12, new clusters will not have a client certificate issued. You can manually enable (or disable) the issuance of the client certificate using the `--[no-]issue-client-certificate` flag.
WARNING: Currently VPC-native is not the default mode during cluster creation. In the future, this will become the default mode and can be disabled using `--no-enable-ip-alias` flag. Use `--[no-]enable-ip-alias` flag to suppress this warning.
This will enable the autorepair feature for nodes. Please see
https://cloud.google.com/kubernetes-engine/docs/node-auto-repair for more
information on node autorepairs.
WARNING: Starting in Kubernetes v1.10, new clusters will no longer get compute-rw and storage-ro scopes added to what is specified in --scopes (though the latter will remain included in the default --scopes). To use these scopes, add them explicitly to --scopes. To use the new behavior, set container/new_scopes_behavior property (gcloud config set container/new_scopes_behavior true).
Creating cluster go-webapi-for-gke-study-cluster-1...done.
Created [https://container.googleapis.com/v1/projects/【プロジェクトID】/zones/asia-northeast1-a/clusters/go-webapi-for-gke-study-cluster-1].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/asia-northeast1-a/go-webapi-for-gke-study-cluster-1?project=【プロジェクトID】
kubeconfig entry generated for go-webapi-for-gke-study-cluster-1.
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
go-webapi-for-gke-study-cluster-1 asia-northeast1-a 1.9.7-gke.6 xxx.xxx.xxx.xxx n1-standard-1 1.9.7-gke.6 3 RUNNING
2)クラスタをミニマム仕様で再作成
作っておきながらなんだけど、勉強用途でn1-standard-1マシンを3台立ち上げ続けるのは避けたい(でも、いちいち落とすのは忘れそう)ので、無料枠内でできるミニマム仕様を探る。
当然、先人がいるので参考にする。
https://blog.a-know.me/entry/2018/06/17/220222
参考サイトのようにプリエンプティブVMを使い、スペックもf1-microのディスクサイズ10GBにしてトライ。
参考サイトではエラーになると書かれてあるノード数 1 も、あえて付けてみた。
$ gcloud container clusters create go-webapi-for-gke-study-cluster-1-min --zone asia-northeast1-a --preemptible --machine-type=f1-micro --disk-size=10 --num-nodes=1
〜省略〜
ERROR: (gcloud.container.clusters.create) ResponseError: code=400, message=Clusters of f1-micro instances must contain at least 3 nodes. Please make the cluster larger or use a different machine type.
怒られた。
おとなしくノード数 3 でリトライ。
$ gcloud container clusters create go-webapi-for-gke-study-cluster-1-min --zone asia-northeast1-a --preemptible --machine-type=f1-micro --disk-size=10 --num-nodes=3
〜省略〜
Creating cluster go-webapi-for-gke-study-cluster-1-min...done.
Created [https://container.googleapis.com/v1/projects/【プロジェクトID】/zones/asia-northeast1-a/clusters/go-webapi-for-gke-study-cluster-1-min].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/asia-northeast1-a/go-webapi-for-gke-study-cluster-1-min?project=【プロジェクトID】
kubeconfig entry generated for go-webapi-for-gke-study-cluster-1-min.
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
go-webapi-for-gke-study-cluster-1-min asia-northeast1-a 1.9.7-gke.6 xxx.xxx.xxx.xxx f1-micro 1.9.7-gke.6 3 RUNNING
ちなみに、gcloudコマンドで各種操作を行うやり方は以下に書いてある。
https://cloud.google.com/kubernetes-engine/docs/clusters/operations?hl=ja
3)アプリをデプロイ
公式のクイックスタートに則るなら、以下のように kubectl コマンド一発でとりあえずデプロイはできるらしい。
$ kubectl run go-webapi-for-gke-study-server --image gcr.io/【プロジェクトID】/go-webapi-for-gke-study@sha256:4d1897773110c4ed095fd43d6f08d946c2a9692245cbdf653a689c2dd64e3419 --port 80
deployment "go-webapi-for-gke-study-server" created
「deployment」が作成されたとの簡素なメッセージ。
「デプロイメントが作られた」って、どういうことだ???
公式の説明によると、「Deployment は複数の同じポッドのセットを表します。」とのこと。
先ほどの kubectl コマンドにより『ポッドのセットが作られた(そして、その中に(すべてに?)Dockerコンテナがデプロイされた)』ということか。
(クラスタ内に特定のインスタンスとして? クラスタ内の特定の(or すべての)ノード(=GCEインスタンス)内に?)
次は、「ポッド」。
これは公式の説明によると、
「ポッドは、Kubernetes でデプロイできる最小かつ最も基本的なオブジェクトです。ポッドは、クラスタ内で実行されるプロセスの単一インスタンスを表します。」とのこと。
「ポッドは、クラスタ内のノードで実行されます。」ともある。今時点の理解で登場人物を構造で表してみると、こんな感じか。
/ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー\
|①クラスタ(=GCEインスタンスグループ) |
| |
| /ーーーーーーーーーーーーーーーーーーーーーーーーーーー\ |
| |②ノード(=GCEインスタンス) | |
| | | | x N
| | /ーーーーーーーーーーーーーーーーーーーー\ | |
| | |③ポッド(=論理ホスト) | | x N |
| | | | | |
| | | /ーーーーーーーーーーーーー\ | x N | |
| | | |④コンテナ | | | |
| | | | | x N | | |
| | | | /ーーーーーー\ | | | |
| | | | |⑤アプリ | x N | | | |
| | | | | | | | | |
| | | | \ーーーーーー/ | | | |
| | | \ーーーーーーーーーーーーー/ | | |
| | \ーーーーーーーーーーーーーーーーーーーー/ | |
| \ーーーーーーーーーーーーーーーーーーーーーーーーーーー/ |
\ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー/
「クラスタ」がGKEの領域で「ノード」と「ポッド」はk8s自体の概念。
各階層で配下に複数持てることを「x N」で表したけど、階層によって少し意味合いが違う。
②と③の「x N」はスケールする意味を表し、それ以外は複数の種類を持てることを表す。
先の kubectl コマンドにより、デプロイメント=複数のポッドが作られた。
実際、クラウドコンソールで確認してみると、GKEの「ワークロード」(=Dockerコンテナ)に「タイプ「Deployment」」で情報が載っていた。
https://cloud.google.com/kubernetes-engine/docs/concepts/kubernetes-engine-overview?hl=ja#workloads
詳細情報に飛ぶと以下のような感じ。
これで、アプリのGKEデプロイは完了しアクセスできるのか? とクラスタのエンドポイントIPにアクセスしてみる。応答返ってこない。
いや、ダメだろうというのはわかる。一応ドキュメント読んでるので。インターネット上からアクセス可能な状態にするにはまた別の概念「サービス(=要するにロードバランサのようだけど)」が必要。
実際、公式のクイックスタートにもデプロイした後に「Deployment を公開する」という手順がある。
上のデプロイメントの詳細画像の最下部に「Services 一致するサービスはありません」とあり、公開状態でないことが表されている。
4)アプリを公開
アプリの公開には Service を作成するとある。 kubectl コマンド使うと以下のようにする。
$ kubectl expose deployment go-webapi-for-gke-study-server --type "LoadBalancer"
service "go-webapi-for-gke-study-server" exposed
クラウドコンソールで確認してみると、今まで存在しなかったサービスが出来ている。
ワークロードでも「一致するサービスはありません」だった箇所で紐付けがされている。
5)アクセス確認
サービスのエンドポイントに対してブラウザでアクセス
やった。
アプリ自体、ポート80で受け付けるように作り、Dockerコンテナでもポート80でExposeし、k8sのデプロイメント作成時もポート80でExposeしたなら、サービス公開にてインターネット上からアクセス可能になる。
ちなみに、GCPのダッシュボードを見てみると、GCEインスタンス3個とGCSバケット2個の記録があった。
GCEインスタンスの方は、GKEのクラスタ作成時にノードプールのサイズを「3」で定義しているから。
GCSバケットの方は、1つはGAEのだった。もう1つはCloud Build使ったことで作られたものの様子。ソースを固めたものか?
あと、一応、StackdriverLoggingでもログを確認してみる。アプリでログ出力先を標準出力にしておくとGKEで勝手に拾ってSDLに流してくれるので楽。
まとめ
公式のクイックスタートをやれば5分で終わったであろう内容を、わざわざ自前でしょうもないWebアプリを作ってDockerコンテナ化し、公式ドキュメントその他を読み込みながら、Cloud Source RepositoriesやらCloud Build、Container Registryを介して、GKEにデプロイするという手順を取った結果、0.5人日以上かけた気がする。
けど、5分じゃ、ただなんとなくわかった気になって終わってただろうから、よしとしよう。
ただ、当然、そもそもk8sの機能やGKEの機能としてもわかっていないことだらけなので、まだまだ勉強は必要。