Google Cloud Platform (GCP) の無料クレジットがまだ余っているものの、有効期限が迫っているので Google Kubernetes/Container Engine (GKE) で遊んでみる。
実使用ではyamlファイルを作成してInfrastructure as Codeまで行うのだろうけど、 今回はチュートリアルのDeploying a containerized web application に倣って、全てコマンドラインオプションで指定する。
アプリケーションはnginxとwsgiコンテナをシングルイメージに詰め込んだものを使用。 Dockerfileはこんな感じ。
FROM tiangolo/uwsgi-nginx:python2.7
COPY ./docker/nginx.conf /etc/nginx/conf.d/default.conf
# install MeCab
RUN apt update && apt install -y mecab mecab-utils mecab-ipadic-utf8 libmecab-dev
# install app
COPY ./app /app
COPY ./docker/uwsgi.ini /app/uwsgi.ini
WORKDIR /app
RUN pip install -r requirements.txt
gcloudコマンドラインツールを設定
毎回指定するのは面倒なので、デフォルト設定をしておく。
$ gcloud config set project summarizer-165702
$ gcloud config set zone us-central1-a
dockerコンテナイメージを作成する
ここらはいつものdockerそのまま。バージョンごとにイメージを作ることになるのでタグも付ける。
$ docker build -t gcr.io/summarizer-165702/summarizer-app:v1 .
イメージができているか確認。
$ docker images
ローカルでちゃんと動くかテスト。
$ docker run --rm -p 8888:80 gcr.io/summarizer-165702/summarizer-app:v1
$ curl http://localhost:8888
コンテナイメージをアップロード
gcloudコマンドを使ってイメージをContainer Registryへアップロードする。
$ gcloud docker -- push gcr.io/summarizer-165702/summarizer-app:v1
コンテナクラスターを作成する
次のコマンドでコンテナクラスターを作成する。 ノード数は3、マシンタイプはg1-small(安いので)にした。インスタンスを3つたちあげるのでしばらく時間が掛かる。 OSはデフォルトのGoogle Container-Optimized OS (cos)。
$ gcloud container clusters create summarizer-cluster --num-nodes=3 --machine-type=g1-small
Creating cluster summarizer-cluster...done.
Created [https://container.googleapis.com/v1/projects/summarizer-165702/zones/us-central1-a/clusters/summarizer-cluster].
kubeconfig entry generated for summarizer-cluster.
NAME ZONE MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
summarizer-cluster us-central1-a 1.7.8-gke.0 35.188.186.176 g1-small 1.7.8-gke.0 3 RUNNING
3つのg1-smallインスタンスができた。
$ gcloud compute instances list
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
gke-summarizer-cluster-default-pool-2ca45fdf-6s8h us-central1-a g1-small 10.128.0.2 35.188.139.14 RUNNING
gke-summarizer-cluster-default-pool-2ca45fdf-8xxk us-central1-a g1-small 10.128.0.3 104.197.177.170 RUNNING
gke-summarizer-cluster-default-pool-2ca45fdf-hxns us-central1-a g1-small 10.128.0.4 35.202.183.30 RUNNING
アプリケーションをデプロイする
Container Registryへアップロードしたイメージを使用してアプリケーションをデプロイする。
$ kubectl run summarizer-app --image=gcr.io/summarizer-165702/summarizer-app:v1 --port 80
deployment "summarizer-app" created
作成されたPodを確認。Pod数は後で増やすことにする。
Podとはコンテナをグループ化したもの。Kubernetes (k8s)ではコンテナをPod単位で扱う。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
summarizer-app-3299800503-bh28p 1/1 Running 0 2m
インターネットへ公開する
作成したDeploymentへロードバランサーを追加して外部へ公開する。
Deploymentとはデプロイ管理を行うもの。DeploymentがReplicaSetを管理し、ReplicaSetがPodを管理する。
$ kubectl expose deployment summarizer-app --type=LoadBalancer --port 80 --target-port 80
service "summarizer-app" exposed
サービス状況を確認。
$ kubectl get service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.31.240.1 <none> 443/TCP 10m
summarizer-app 10.31.241.104 130.211.148.49 80:31948/TCP 2m
EXTERNAL-IPが割り当てられるとブラウザでアクセス出来るようになる。
アプリケーションをスケールアップさせる
podを3つに増やしてスケールアップさせてみる。
$ kubectl scale deployment summarizer-app --replicas=3
deployment "summarizer-app" scaled
$ kubectl get deployment summarizer-app
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
summarizer-app 3 3 3 1 12m
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
summarizer-app-3299800503-bh28p 1/1 Running 0 12m
summarizer-app-3299800503-wqwg5 0/1 ContainerCreating 0 1m
summarizer-app-3299800503-zprpx 0/1 ContainerCreating 0 1m
新バージョンのアプリケーションをデプロイ
アプリケーションの更新手順を確認する。
ソースコードを修正、その後、更新版のイメージをビルドしてContainer Registryへアップロード。
$ docker build -t gcr.io/summarizer-165702/summarizer-app:v2 .
$ gcloud docker -- push gcr.io/summarizer-165702/summarizer-app:v2
v2イメージを展開。
$ kubectl set image deployment/summarizer-app summarizer-app=gcr.io/summarizer-165702/summarizer-app:v2
deployment "summarizer-app" image updated
Container Registryのビルドトリガー機能を使えば、イメージ生成とアップロードは楽できそう。
後始末
しばらく動かしておくつもりだけれども、削除方法も見ておく。
サービスを削除。
$ kubectl delete service summarizer-app
ロードバランサーは非同期で削除される。進捗状況は次のコマンドで確認。
$ gcloud compute forwarding-rules list
コンテナクラスターを削除。
$ gcloud container clusters delete summarizer-app
クラスターサイズを減らしてみる
クラスターサイズを変更するとどうなるか試してみる。ノード数は奇数でしょということで1まで減らす。
$ gcloud container clusters resize --size=1 summarizer-cluster
Pool [default-pool] for [summarizer-cluster] will be resized to 1.
Do you want to continue (Y/n)?
Resizing summarizer-cluster...done.
Updated [https://container.googleapis.com/v1/projects/summarizer-165702/zones/us-central1-a/clusters/summarizer-cluster].
$ gcloud compute instances list
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
gke-summarizer-cluster-default-pool-2ca45fdf-hxns us-central1-a g1-small 10.128.0.4 35.202.183.30 RUNNING
稼働インスタンスが1つになった。続いてDeploymentは...
$ kubectl get deployment summarizer-app
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
summarizer-app 3 3 3 2 1h
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
summarizer-app-809326932-9zs62 0/1 Pending 0 2m
summarizer-app-809326932-bvvbt 1/1 Running 0 2m
summarizer-app-809326932-h1t9l 1/1 Running 0 7m
PODを再配備している模様。これは面白い。
更にPODを減らしてみる
kubectl scale deployment summarizer-app --replicas=1
deployment "summarizer-app" scaled
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
summarizer-app-809326932-h1t9l 1/1 Running 0 30m
減ったへった。
総括
Kubernetesは素晴らしいものです。