はじめに
先日GoogleCloudOnBoardという大きなイベントに参加しまして、色々と感動したわけです。私もGCP布教に一役買おうと思いContainerEngineについて書いてみました。
前回はAWS ECSを書きましたけど、やっぱりコンテナ管理といえばKubernetesですよ。
今回も前回とだいたい同じシナリオでやってみたいと思いますが、Autoscalerだけはベータでの提供とのことで一旦手を出すのをやめときました。また試したいと思います。
ひととおりやるとKubernetesがちょっとわかる(かも)知れません。
- Dockerのイメージを用意する
- 使い方の基本
- BlueGreenDeployment
- その他試したこと
Google Cloud Platform
Googleが提供しているパブリッククラウドのサービスです。
詳しい説明は色々なところで語られているので割愛します。
60日間3万円までの無料枠があります。相当色々できます。
が、、期間がちょっと短いのでもう少し欲しいです・・・。
Dockerのイメージを用意する
今回はGCPが提供するContainerRegistryにイメージを用意して、そこからコンテナにデプロイしてみようと思います。
Container Registryにpushする
Container Registry への pushをよみましょう。
pushするにはプロジェクトID を、使用可能ないずれかの gcr.io ホスト名に追加する必要があります。gcr.ioは米国でホストされるらしいのですが、変わる可能性があるのでローカライズされたホストを指定することが推奨されるようです。
ということでアジアに保管してみましょう。
- タグをつける
docker tag uzresk/demo:ver1.0 asia.gcr.io/uzr-esk/demo:ver1.0
- タグが付いていることを確認する
[root@centos7 gcp]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
asia.gcr.io/uzr-esk/demo ver2.0 14d465cbed4a 5 days ago 652.3 MB
uzresk/demo ver2.0 14d465cbed4a 5 days ago 652.3 MB
asia.gcr.io/uzr-esk/demo ver1.0 66717f366a03 5 days ago 652.3 MB
uzresk/demo ver1.0 66717f366a03 5 days ago 652.3 MB
- ContainerRegistryにpushする
gcloud docker push asia.gcr.io/uzr-esk/demo:ver1.0
- ver2.0も合わせてpushしておきます。
使い方の基本
CloudShellを使おう
- AWSはマネジメントコンソールで全てできますが、GCPは基本的にCUIベースになります。うっと思う人もいるかもしれませんがCUIのコマンドを使いやすくするためのCloudShellというものがGCPには用意されています。
- CloudShellはGCPが用意してくれる一時的な仮想マシンで、gcloudとかkubectlなどのコマンドを特に何もしなくても利用できるようになります。
- ストレージは5GB用意してくれていますし、ウェブでプレビュー機能などを使えばポートフォワードみたいなことをしてブラウザで表示できたりします。
- なんと言っても無料です。
CloudShellを有効にする
-
ちなみにChromeの拡張機能であるSSH For Google Cloud Platformをインストールすればコピペが楽になりますので入れておきましょう。
-
本題に入って、ここからコンテナクラスタに対してイメージをデプロイしてみたいと思います。
クラスタを作る
- asia-northeast1-aに3ノードのクラスタを作ってみます。
$ gcloud container clusters create demo-cluster --zone asia-northeast1-a --machine-type g1-small --num-nodes=3 --min-nodes=3 --max-nodes=3
kubectlを設定する
- デフォルトのクラスタの設定を行います。
$ gcloud config set container/cluster demo-cluster
Updated property [container/cluster].
- kubectlにクラスタ認証情報を渡す
- これを設定しないとkubectlコマンドが使えません
$ gcloud container clusters get-credentials demo-cluster --zone asia-northeast1-a
Fetching cluster endpoint and auth data.
kubeconfig entry generated for demo-cluster.
クラスタにイメージをデプロイする
- kubectl runコマンドで起動しても良いのですが、今回はyamlでpodの設定を行いデプロイしてみます。
- yamlの書き方についてはkubernetesのドキュメントを見るとよさそうです。
- 少し補足
- ポイントはLabelです。ここに記載されたLabelと後程でてくるロードバランサのSelectorがリンクしています。
- livenessProbeとはコンテナに対するヘルスチェックの設定でして、詳しくは「Kubernetesヘルスチェックの使い方」で詳しく解説してくれています。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: demo-ver1.0
spec:
replicas: 3
template:
metadata:
labels:
type: demo
spec:
containers:
- name: demo
image: asia.gcr.io/uzr-esk/demo:ver1.0
livenessProbe:
httpGet:
path: /app/loginForm
port: 8080
initialDelaySeconds: 30
timeoutSeconds: 1
ports:
- containerPort: 8080
- podを作ります
$ kubectl create -f demo-ver1.0.yml
- podが作られているかを確認する
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-ver1.0-3601253569-48haz 0/1 ContainerCreating 0 10s
demo-ver1.0-3601253569-5oati 0/1 ContainerCreating 0 10s
demo-ver1.0-3601253569-uucse 1/1 Running 0 10s
ロードバランサを作ってみよう
-
Creating an External Load Balancerを参考にロードバランサを作ってみます。
-
Configurationの設定はService Operationsを確認してみましょう
-
LBのサービスは80で受けて、コンテナの8080に転送するように設定してます。
apiVersion: v1
kind: Service
metadata:
name: demo-app-lb
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
protocol: TCP
selector:
type: demo
- LBを作ります
$ kubectl create -f LB-Service.yml
service "demo-app-lb" created
- external IPを確認しよう
-
kubectl get service
とkubectl get svc
は同じ意味です。
-
$ kubectl get service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-app-lb 10.27.241.244 104.198.126.185 80:30157/TCP 3m
kubernetes 10.27.240.1 <none> 443/TCP 12m
- アクセスできましたね
podを一つおとしてみるとどうなるのか
- まずは現在の状態を確認
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-ver1.0-3601253569-48haz 1/1 Running 1 39m
demo-ver1.0-3601253569-5oati 1/1 Running 1 39m
demo-ver1.0-3601253569-uucse 1/1 Running 0 39m
- 一番したのインスタンスを停止してみましょう
$ kubectl stop pods demo-ver1.0-3601253569-uucse
Command "stop" is deprecated, use "delete" instead.
pod "demo-ver1.0-3601253569-uucse" deleted
- 一瞬で上がってきます。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-ver1.0-3601253569-48haz 1/1 Running 1 45m
demo-ver1.0-3601253569-5oati 1/1 Running 1 45m
demo-ver1.0-3601253569-pha65 1/1 Running 0 10s
kubernetes dashboardにアクセスしてみよう
- kubernetesにはWEBのUIがついていてクラスタの情報が色々見れます
- CloudShellを使っている場合はこの手順ではアクセスできないので以下のように行います
アクセスの仕方
- portを指定してproxyします。
- port8080で起動しているのはCloudShellのウェブでプレビュー機能で許可されているポートは8080 から 8084だからです。
$ kubectl proxy --port=8080
Starting to serve on 127.0.0.1:8080
- CloudShellのウェブでのプレビュー機能を使います
- ブラウザが開きます
- not-authorizedと出てしまうので、URLを変更して(/ui)アクセスします。
https://8080-xxxxxxxxxxxxxxxxxx.com/ui/?authuser=0
残念ながらローカルのIPを利用する部分の表示はできませんので、表示したい場合はkubectlをローカルにインストールしてproxyしてください。
Blue/Green Deployment
- ver1.0,ver2.0のpodを作りましょう(labelにはversionが付与されているので注意してください)
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: demo-ver1.0
spec:
replicas: 3
template:
metadata:
labels:
type: demo
version: ver1.0
spec:
containers:
- name: demo
image: asia.gcr.io/uzr-esk/demo:ver1.0
livenessProbe:
httpGet:
path: /app/loginForm
port: 8080
initialDelaySeconds: 30
timeoutSeconds: 1
ports:
- containerPort: 8080
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: demo-ver2.0
spec:
replicas: 3
template:
metadata:
labels:
type: demo
version: ver2.0
spec:
containers:
- name: demo
image: asia.gcr.io/uzr-esk/demo:ver2.0
livenessProbe:
httpGet:
path: /app/loginForm
port: 8080
initialDelaySeconds: 30
timeoutSeconds: 1
ports:
- containerPort: 8080
- podの作成
$ kubectl create -f demo-ver1.0.yml
$ kubectl create -f demo-ver2.0.yml
- 起動していることを確認しましょう
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-ver1.0-1983367677-2bq5c 1/1 Running 0 15m
demo-ver1.0-1983367677-oyfbv 1/1 Running 0 15m
demo-ver1.0-1983367677-v3dfl 1/1 Running 0 15m
demo-ver2.0-2166737407-gfb3k 1/1 Running 0 9s
demo-ver2.0-2166737407-mh2w2 1/1 Running 0 9s
demo-ver2.0-2166737407-ycrux 1/1 Running 0 9s
- ver1.0に紐付いたらロードバランサを作ります。
apiVersion: v1
kind: Service
metadata:
name: demo-app-lb
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
protocol: TCP
selector:
type: demo
version: ver1.0
- ver2.0のpodに切り替えます。
$ kubectl edit service demo-app-lb
- viが上がってきますのでver1.0の部分をver2.0に編集します
- Selectorがver.2.0に切り替わってますね
$ kubectl describe service
Name: demo-app-lb
Namespace: default
Labels: <none>
Selector: type=demo,version=ver2.0
Type: LoadBalancer
IP: 10.27.241.244
LoadBalancer Ingress: 104.198.126.185
Port: <unset> 80/TCP
NodePort: <unset> 30157/TCP
Endpoints: 10.24.0.8:8080,10.24.0.9:8080,10.24.1.7:8080
- ちゃんとブラウザでも表示されました
Cluster Autoscaler
- AWSと同じようにCPU使用率などを見てクラスタをスケールさせることができます。
- こちらの機能は2017/2現在ベータ版とのことです。ベータが取れたら試してみたいと思います。
その他試したこと
クラスタのリサイズ
- 現在のノード数を確認
$ kubectl get nodes
NAME STATUS AGE
gke-demo-cluster-default-pool-8860cc2f-3sx1 Ready 2h
gke-demo-cluster-default-pool-8860cc2f-pf2q Ready 2h
- クラスタのサイズを上げてみます(レスポンスはすぐに返ってきます)
$ gcloud container clusters resize demo-cluster --size 3 --zone asia-northeas
t1-a
Pool [default-pool] for [demo-cluster] will be resized to 3.
Do you want to continue (Y/n)? Y
Resizing demo-cluster...done.
Updated [https://container.googleapis.com/v1/projects/uzr-esk/zones/asia-northeast1-a/clusters/demo-cluster]
.
- ちょっと時間がたつとノードが増えていますね。
$ kubectl get nodes
NAME STATUS AGE
gke-demo-cluster-default-pool-8860cc2f-3sx1 Ready 2h
gke-demo-cluster-default-pool-8860cc2f-8h93 Ready 40s
gke-demo-cluster-default-pool-8860cc2f-pf2q Ready 2h
マルチゾーン対応クラスタに更新する
- 今のデフォルトノード数が2なので、あと2つのリージョンに展開すると合計6ノードのクラスタができます。
gcloud beta container clusters update demo-cluster --additional-zones=asia-northeast1-b,asia-northeast1-c --zone asia-northeast1-a
- 更新している途中にブラウザでアクセスしてみましたが、サービスは提供され続けるようです。
- 確認してみましょう(コマンドライン)
gcloud container clusters describe demo-cluster --zone asia-northeast1-a
・・・
locations:
- asia-northeast1-a
- asia-northeast1-b
- asia-northeast1-c
- コンソール
ローカルにkubectlを設定するときにハマったところ
- こんなエラーが出てしまったら、KUBECONFIGという環境変数に.kube/configへのパスを設定しましょう。configは空でよいです。
ERROR: (gcloud.container.clusters.get-credentials) environment variable HOME or KUBECONFIG must be set to store credentials for kubectl
- こんなエラーが出てしまったら
gcloud auth application-default login
で認証情報を設定しましょう
error: google: could not find default credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.
さいごに
Kubernetesを初めて触りましたが奥深そうですのでジックリ勉強する必要がありそうです。Openstack上にKubernetesを浮かべたくなる人の気持ちも少しは分かるようになりました。
AWSは自分でいろいろ設定しないといけない分、動きが読めるので私には理解が進みました。AWSとGCPどちらも触ったことがなくコンテナ管理してみたいという人はGCPの方が入りやすいかもしれません。(今回の記事も調べながらやりながらで半日くらいでできましたので。)