GKEでkubernetesを理解する

image

Kubernetesはコンテナを使ったシステムのライフサイクルを管理するオープンソースです。

大体のインフラ1で動きますが、今回はKubernetesの環境が予め用意されているGKEを使って、使う側の視点で学びたいと思います。


大雑把な理解

まず、ざっくり構成を把握するために図を見てみます

image

図:Kubernetes architecture

左側がKubernetesのコントローラーで、右側が管理対象のコンテナです。以下の単語を簡単に抑えておきます。


  • Node・・Dockerが動くマシンのこと。

  • Pod・・コンテナを配置する入れ物。この単位でスケールさせたりします。

  • Proxy・・コンテナとの通信を経由するプロキシ。

APIやコマンドラインで管理するときに、以下の単語が頻繁に出てくるのでざっくり覚えておきます。


  • Deployments 2・・Pod(コンテナ)を管理するもの

  • Service 3・・Pod(コンテナ)と通信を維持するためのポリシーなどを定義するもの


何で学ぶ?

以下のチュートリアルを使ってkubernetesを理解していきたいと思います。

チュートリアルに記載してある情報が古い(ReplicptionControllerの作成からDeploymentの作成に変わっている)ので以下も参考にしながら進めます。

こんな形なものを作ります。

                +--------------+

| LoadBalancer |
+--------------+
|
+--------------+
| frontend |
+--------------+
| |
+--------------+ +--------------+
| redis-master | | redis-slave |
+--------------+ +--------------+


コマンド環境の準備

gcloud コマンドと kubectl コマンドを以下の通りに従ってセットアップしておきます。

Container Engine 開始方法

使う環境をデフォルトで設定しておく。コマンドを打つ度に指定しなくても済むので。

$ gcloud config set project PROJECT_ID # プロジェクトIDの指定

$ gcloud config set compute/zone asia-northeast1-a # ゾーンの指定

$ gcloud config list # 現在の設定を確認
Your active configuration is: [default]

[compute]
region = asia-northeast1
zone = asia-northeast1-a
[core]
account = EMAIL_ADDRESS
disable_usage_reporting = False
project = PROJECT_ID


クラスタ(ノード)の作成

最初に、コンテナを配置するクラスタ(ノード)を作成しておきます。デフォルトで3ノード数作成されますが、今回はノード数を1に指定して作成しました。

$ gcloud container clusters create guestbook --num-nodes=1

Creating cluster guestbook...done.
Created [https://container.googleapis.com/v1/projects/{PROJECT_ID}/zones/asia-northeast1-a/clusters/guestbook].
kubeconfig entry generated for guestbook.
NAME ZONE MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
guestbook asia-northeast1-a 1.4.7 104.198.127.169 n1-standard-1 1.4.7 1 RUNNING

既にKubernetesも起動しているので、以下のコマンドでローカルプロキシを起動させてみます。

$ kubectl proxy

Starting to serve on 127.0.0.1:8001

http://localhost:8001/ui/ へにアクセスするとKubernetesの画面が現れます。見た目がイケてますね。 :heart_eyes:

image


Redisマスターの作成

Deployment(Podとコンテナ)を作成します。


  • redis-master-deployment.yaml ファイル


redis-master-deployment.yaml

apiVersion: extensions/v1beta1

kind: Deployment
metadata:
name: redis-master # 名前の指定(必須)
spec:
replicas: 1 # コンテナのレプリカ数の設定
template:
metadata:
labels: # ラベルをKV型で設定
app: redis
role: master
tier: backend
spec:
containers:
- name: master # コンテナの名前
image: gcr.io/google_containers/redis:e2e # コンテナイメージの指定(必須)
resources:
requests:
cpu: 100m # CPUを0.1コア確保
memory: 100Mi # メモリ100MiB確保
ports:
- containerPort: 6379 # コンテナポートの指定



  • kube createでこのファイルを読ませるとyamlに記載したとおりのコンテナを作成してくれます。

$ kubectl create -f redis-master-deployment.yaml

deployment "redis-master" created

- Deployment一覧を表示する

```bash
$ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
redis-master 1 1 1 1 2m


  • Pod一覧を表示する

$ kubectl get pod

NAME READY STATUS RESTARTS AGE
redis-master-343230949-6dmjd 1/1 Running 0 2m

Redisのコンテナが出来ました :tada:


寄り道(kubectl run コマンド)

yamlを作成しなくても、kubectl runコマンドで同じく作成することができます。



  • kubectl run コマンド

$ kubectl run redis-master \

> --image=gcr.io/google_containers/redis:e2e \
> --labels="app=redis,role=master,tier=backend" \
> --requests="cpu=100m,memory=100Mi" \
> --port=6379
deployment "redis-master-run" created

実は、これだとコンテナ名(実際のコンテナ名ではない)がredis-master(デフォルトでPod名)になってしまい、完全に同一ではありません。コンテナ名を設定するコマンド引数4が見つからなかったので、--overridesオプションで無理やり設定してみました。



  • --overridesオプションをつけてkubectl run

$ kubectl run redis-master \

> --image=gcr.io/google_containers/redis:e2e \
> --labels="app=redis,role=master,tier=backend" \
> --overrides='{"spec":{"template":{"spec":{"containers":[{"name":"master","image":"gcr.io/google_containers/redis:e2e","resources":{"requests":{"cpu":"100m","memory":"100Mi"}},"ports":[{"containerPort":6379}]}]}}}}'
deployment "redis-master" created

--imageオプションは必須なため、--overrides内とコンテナイメージのロケーションを二重で記載する必要があります。。 :sweat_smile: 殆どの部分をyamlからjsonに変換してる感じでちょっと無意味感。。

念のため kube describe pod <POD_NAME>の内容を比較してみます。


describeした内容を比較

$ diff -u redis-master.describe redis-master_run.describe 

--- redis-master.describe 2016-12-29 23:38:58.000000000 +0900
+++ redis-master_run.describe 2016-12-29 23:41:49.000000000 +0900
@@ -1,17 +1,17 @@
-Name: redis-master-343230949-6dmjd
+Name: redis-master-343230949-n0sxq
Namespace: default
Node: gke-guestbook-default-pool-af5eb675-xszz/10.146.0.2
-Start Time: Thu, 29 Dec 2016 22:37:55 +0900
+Start Time: Thu, 29 Dec 2016 23:40:41 +0900
Labels: app=redis
pod-template-hash=343230949
role=master
tier=backend
Status: Running
-IP: 10.52.0.11
+IP: 10.52.0.15
Controllers: ReplicaSet/redis-master-343230949
Containers:
master:
- Container ID: docker://2f57187ee653673df16d40532528086475aadbff9994540541147285600de612
+ Container ID: docker://49226c07f4a0ab49503cc46eea01c9382ffe3b62d9d27170ccd8b21f04500365
Image: gcr.io/google_containers/redis:e2e
Image ID: docker://sha256:e5e67996c442f903cda78dd983ea6e94bb4e542950fd2eba666b44cbd303df42
Port: 6379/TCP
@@ -19,7 +19,7 @@
cpu: 100m
memory: 100Mi
State: Running
- Started: Thu, 29 Dec 2016 22:38:24 +0900
+ Started: Thu, 29 Dec 2016 23:40:42 +0900
Ready: True
Restart Count: 0
Volume Mounts:

IPアドレスや日付以外で変更点はないので、同一な設定で作成できていることが分かります :tada:


寄り道(Deployment)

Deploymentは比較的新しく、Podの作成やローリングアップデートやロールバックなどを簡単にしてくれるものです。

Using Deployment objects with Kubernetes 1.2

それまでは Replication Controller5がその辺りの役割を担っていたこともあり、TutorialではReplication Controller で Pod を作成して説明しています。今のバージョン(1.4.7)では、DeploymentsでPodを作成すると、Replication Controller の次世代版である Replica Sets6 が動き出します。Replication Controller は無くなってしまうのかなぁ。。

ちなみに、Kubernetesの管理UIでは未だ Replication Controller がメインになっている様で、UIからPodを作成すると Replication Controller が作成されます。

試してみます。


  • コマンドラインからコンテナ(Pod)を作成

$ kubectl run cli --image=gcr.io/google-samples/gb-frontend:v4

deployment "cli" created

〜 ここで、KubernetesのUIからuiという名前でコンテナを作成 〜


  • 2つのPodが作成されています

$ kubectl get pod

NAME READY STATUS RESTARTS AGE
cli-2068554765-12stb 1/1 Running 0 1m
ui-sbpaz 1/1 Running 0 22s


  • UIから作成したコンテナは Replication Controller になっています

$ kubectl get replicationcontroller

NAME DESIRED CURRENT READY AGE
ui 1 1 1 45s


  • コマンドラインからはDeploymentになっています

$ kubectl get deployment

NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
cli 1 1 1 1 1m

yamlの設定自体は殆ど変わりません。強いて挙げると、metadataの箇所でlabelsを省略している所ぐらいです。


TutorialにあるRC用とDeployment用yamlの比較

--- legacy/redis-master-controller.yaml 2016-12-28 01:18:16.000000000 +0900

+++ redis-master-deployment.yaml 2016-12-28 01:43:37.000000000 +0900
@@ -1,13 +1,13 @@
-apiVersion: v1
-kind: ReplicationController
+apiVersion: extensions/v1beta1
+kind: Deployment
metadata:
name: redis-master
# these labels can be applied automatically
# from the labels in the pod template if not set
- labels:
- app: redis
- role: master
- tier: backend
+ # labels:
+ # app: redis
+ # role: master
+ # tier: backend
spec:
# this replicas value is default
# modify it according to your case
@@ -15,9 +15,10 @@
# selector can be applied automatically
# from the labels in the pod template if not set
# selector:
- # app: guestbook
- # role: master
- # tier: backend
+ # matchLabels:
+ # app: guestbook
+ # role: master
+ # tier: backend
template:
metadata:
labels:


寄り道(ノードにSSHログイン)

ノードにSSHログインすることもできます。



  • -o wideでPodが配置されているノードIDを表示させます。

$ kubectl get pod -o wide

NAME READY STATUS RESTARTS AGE IP NODE
redis-master-343230949-n0sxq 1/1 Running 0 11m 10.52.0.15 gke-guestbook-default-pool-af5eb675-xszz


  • 上記ノードを指定してSSHログインします。

$ gcloud compute ssh gke-guestbook-default-pool-af5eb675-xszz

Warning: Permanently added 'compute.7579721538501918346' (RSA) to the list of known hosts.

Welcome to Kubernetes v1.4.7!

You can find documentation for Kubernetes at:
http://docs.kubernetes.io/

The source for this release can be found at:
/home/kubernetes/kubernetes-src.tar.gz
Or you can download it at:
https://storage.googleapis.com/kubernetes-release/release/v1.4.7/kubernetes-src.tar.gz

It is based on the Kubernetes source at:
https://github.com/kubernetes/kubernetes/tree/v1.4.7

For Kubernetes copyright and licensing information, see:
/home/kubernetes/LICENSES
user@gke-guestbook-default-pool-af5eb675-xszz ~ $


  • ログイン出来たので"docker ps"コマンドを実行してみます。kubernetes関連のコンテナが沢山動いてますね。

user@gke-guestbook-default-pool-af5eb675-xszz ~ $ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
49226c07f4a0 gcr.io/google_containers/redis:e2e "redis-server /etc/re" 12 minutes ago Up 12 minutes k8s_master.b505b5b1_redis-master-343230949-n0sxq_default_c5e1c119-cdd4-11e6-9059-42010a920020_d5ed9c19
f2e1a93483ef gcr.io/google_containers/pause-amd64:3.0 "/pause" 12 minutes ago Up 12 minutes k8s_POD.d8dbe16c_redis-master-343230949-n0sxq_default_c5e1c119-cdd4-11e6-9059-42010a920020_594d5d61
ed54277b3108 asia.gcr.io/google_containers/addon-resizer:1.6 "/pod_nanny --cpu=80m" 2 hours ago Up 2 hours k8s_heapster-nanny.55df2c69_heapster-v1.2.0-1847815531-zrkw6_kube-system_378ff7ba-cdc2-11e6-9059-42010a920020_84f3de55
22a3bf8a8816 asia.gcr.io/google_containers/heapster:v1.2.0 "/heapster --source=k" 2 hours ago Up 2 hours k8s_heapster.d8c9b305_heapster-v1.2.0-1847815531-zrkw6_kube-system_378ff7ba-cdc2-11e6-9059-42010a920020_b3e26ab1
b4bb94588700 gcr.io/google_containers/pause-amd64:3.0 "/pause" 2 hours ago Up 2 hours k8s_POD.d8dbe16c_heapster-v1.2.0-1847815531-zrkw6_kube-system_378ff7ba-cdc2-11e6-9059-42010a920020_f00e16d7
262de7613d9e asia.gcr.io/google_containers/exechealthz-amd64:1.2 "/exechealthz '--cmd=" 2 hours ago Up 2 hours k8s_healthz.aaa6418e_kube-dns-v20-8uddr_kube-system_25491b5f-cdc2-11e6-9059-42010a920020_19442f61
218ef4491c93 asia.gcr.io/google_containers/kube-dnsmasq-amd64:1.4 "/usr/sbin/dnsmasq --" 2 hours ago Up 2 hours k8s_dnsmasq.daf813d2_kube-dns-v20-8uddr_kube-system_25491b5f-cdc2-11e6-9059-42010a920020_da4ffbd1
02b6c5abe863 asia.gcr.io/google_containers/kubedns-amd64:1.8 "/kube-dns --domain=c" 2 hours ago Up 2 hours k8s_kubedns.dc925936_kube-dns-v20-8uddr_kube-system_25491b5f-cdc2-11e6-9059-42010a920020_226b6b62
9fc09d1f352d asia.gcr.io/google_containers/defaultbackend:1.0 "/server" 2 hours ago Up 2 hours k8s_default-http-backend.8208ca2c_l7-default-backend-v1.0-shaxn_kube-system_251d5635-cdc2-11e6-9059-42010a920020_22aef95d
61d5ea514139 asia.gcr.io/google_containers/kubernetes-dashboard-amd64:v1.4.0 "/dashboard --port=90" 2 hours ago Up 2 hours k8s_kubernetes-dashboard.44adcd81_kubernetes-dashboard-v1.4.0-ev5z4_kube-system_2538ca75-cdc2-11e6-9059-42010a920020_3c45962e
ddc295bd5b86 asia.gcr.io/google_containers/fluentd-gcp:1.21 "/bin/sh -c 'rm /lib/" 2 hours ago Up 2 hours k8s_fluentd-cloud-logging.9d1761e_fluentd-cloud-logging-gke-guestbook-default-pool-af5eb675-xszz_kube-system_9d40f2ab7a284a2e847ba6ea821d674b_08346356
b5a7f7a969fe gcr.io/google_containers/pause-amd64:3.0 "/pause" 2 hours ago Up 2 hours k8s_POD.d8dbe16c_kube-dns-v20-8uddr_kube-system_25491b5f-cdc2-11e6-9059-42010a920020_cfddc70c
2625088adb2d gcr.io/google_containers/pause-amd64:3.0 "/pause" 2 hours ago Up 2 hours k8s_POD.d8dbe16c_l7-default-backend-v1.0-shaxn_kube-system_251d5635-cdc2-11e6-9059-42010a920020_2eb5e129
6904e351db39 gcr.io/google_containers/pause-amd64:3.0 "/pause" 2 hours ago Up 2 hours k8s_POD.d8dbe16c_kubernetes-dashboard-v1.4.0-ev5z4_kube-system_2538ca75-cdc2-11e6-9059-42010a920020_536e1b7b
7672d253bc84 gcr.io/google_containers/pause-amd64:3.0 "/pause" 2 hours ago Up 2 hours k8s_POD.d8dbe16c_fluentd-cloud-logging-gke-guestbook-default-pool-af5eb675-xszz_kube-system_9d40f2ab7a284a2e847ba6ea821d674b_85d10a63
16bdffccc672 gcr.io/google_containers/kube-proxy:31be43b1cb619b7b0ab8fe01f997fe2f "/bin/sh -c 'kube-pro" 2 hours ago Up 2 hours k8s_kube-proxy.3ea31aa7_kube-proxy-gke-guestbook-default-pool-af5eb675-xszz_kube-system_0a4a2e1c974bec66debcc5815d60085a_0833b062
9cacc1697cf5 gcr.io/google_containers/pause-amd64:3.0 "/pause" 2 hours ago Up 2 hours k8s_POD.d8dbe16c_kube-proxy-gke-guestbook-default-pool-af5eb675-xszz_kube-system_0a4a2e1c974bec66debcc5815d60085a_20190c5a


寄り道(SSHログインユーザー)

SSHログインの書式は、gcloud compute ssh [USER@]INSTANCE でUSERをつけないとローカル環境のユーザー名で接続します(通常のSSHと同様な動き)。ユーザーは自動的に作成されGCE側へ登録されます。

登録されているユーザーとSSH公開鍵は以下で確認することができます。

https://console.cloud.google.com/compute/metadata/sshKeys


Redis マスターのサービスの作成

コンテナと通信させるためのServiceを作成します。


  • redis-master-service.yaml ファイル


redis-master-service.yaml

apiVersion: v1

kind: Service
metadata:
name: redis-master
labels:
app: redis
role: master
tier: backend
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: redis
role: master
tier: backend


  • yamlファイルを読み込んでサービスを作成します。

$ kubectl create -f redis-master-service.yaml

service "redis-master" created


  • サービスの情報を表示します。

$ kubectl get service redis-master

NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-master 10.55.246.114 <none> 6379/TCP 43s


  • もちろん、コマンドラインでサービスを作成することもできます。

$ kubectl expose service redis-master \

> --labels="app=redis,role=master,tier=backend" \
> --selector="app=redis,role=master,tier=backend" \
> --port=6379 \
> --target-port=6379


Redis スレーブのコンテナとサービス作成

Redisマスターと同様にコンテナとサービスを作成していきます。


  • redis-slave-deployment.yaml ファイル


redis-slave-deployment.yaml

apiVersion: extensions/v1beta1

kind: Deployment
metadata:
name: redis-slave
spec:
replicas: 2 # レプリカ数を2に指定
template:
metadata:
labels:
app: redis
role: slave
tier: backend
spec:
containers:
- name: slave
image: gcr.io/google_samples/gb-redisslave:v1
resources:
requests:
cpu: 100m
memory: 100Mi
env:
- name: GET_HOSTS_FROM # 環境変数をセットしています。PHPのアプリケーションで使います。
value: dns
ports:
- containerPort: 6379


  • コンテナを作成してPod数が2になっていることを確認します。

$ kubectl create -f redis-slave-deployment.yaml 

deployment "redis-slave" created

$ kubectl get deployment redis-slave
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
redis-slave 2 2 2 0 24s # 2になっている

$ kubectl get pod
NAME READY STATUS RESTARTS AGE
redis-master-343230949-08kqi 1/1 Running 0 7m
redis-slave-132015689-3x3qp 1/1 Running 0 48s # 1Pod目
redis-slave-132015689-b6cha 1/1 Running 0 48s # 2Pod目

redis-slaveのPodが2つあるのが分かります。次にサービスを作成します。


  • redis-slave-service.yaml ファイル


redis-slave-service.yaml

apiVersion: v1

kind: Service
metadata:
name: redis-slave
labels:
app: redis
role: slave
tier: backend
spec:
ports:
- port: 6379
selector:
app: redis
role: slave
tier: backend


  • redis-slaveのサービスを作成して確認します。

$ kubectl create -f redis-slave-service.yaml

service "redis-slave" created

$ kubectl get svc redis-slave # servicesを"svc"と省略することができます。
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-slave 10.55.255.111 <none> 6379/TCP 18s


フロントエンド ウェブサーバーの作成

バックエンド側(redis)は作成したので、次からフロントエンドを作成していきます。


  • front-deployment.yaml ファイル


frontend-deployment.yaml

apiVersion: extensions/v1beta1

kind: Deployment
metadata:
name: frontend
spec:
replicas: 3
template:
metadata:
labels:
app: guestbook
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google-samples/gb-frontend:v4
resources:
requests:
cpu: 100m
memory: 100Mi
env:
- name: GET_HOSTS_FROM
value: dns
ports:
- containerPort: 80


  • frontendを作成して確認します。

$ kubectl create -f frontend-deployment.yaml

deployment "frontend" created

kubectl get deployment frontend
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
frontend 3 3 3 3 1m

$ kubectl get pods
NAME READY STATUS RESTARTS AGE
frontend-88237173-cp3rn 1/1 Running 0 1m
frontend-88237173-kxlgh 1/1 Running 0 1m
frontend-88237173-tw65g 1/1 Running 0 1m
redis-master-343230949-08kqi 1/1 Running 0 29m
redis-slave-132015689-3x3qp 1/1 Running 0 22m
redis-slave-132015689-b6cha 1/1 Running 0 22m

frontend用のサービスを作成します。frontendは複数台の負荷分散をしたいのでtype: LoadBalancerを指定しています。


  • frontend-service.yaml ファイル


frontend-service.yaml

apiVersion: v1

kind: Service
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: guestbook
tier: frontend

$ kubectl create -f frontend-service.yaml 

service "frontend" created

$ kubectl get svc frontend
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend 10.55.254.255 104.198.125.6 80/TCP 3m

type: LoadBalancer を指定すると別途GCEのロードバランサーが作成されています。デフォルトだとヘルスチェックなどの設定がされてないので必要に応じて変更する必要があります。

image

EXTERNAL_IPにブラウザでアクセスすると以下の様な画面がみれました。

image


PHPの中身

このアプリケーションはPHPで書かれているので何をしてるか確認してみたいと思います。


guestbook.php

<?php

error_reporting(E_ALL);
ini_set('display_errors', 1);

require 'Predis/Autoloader.php';

Predis\Autoloader::register();

if (isset($_GET['cmd']) === true) {
$host = 'redis-master';
if (getenv('GET_HOSTS_FROM') == 'env') {
$host = getenv('REDIS_MASTER_SERVICE_HOST');
}
header('Content-Type: application/json');
if ($_GET['cmd'] == 'set') {
$client = new Predis\Client([
'scheme' => 'tcp',
'host' => $host,
'port' => 6379,
]);

$client->set($_GET['key'], $_GET['value']);
print('{"message": "Updated"}');
} else {
$host = 'redis-slave';
if (getenv('GET_HOSTS_FROM') == 'env') {
$host = getenv('REDIS_SLAVE_SERVICE_HOST');
}
$client = new Predis\Client([
'scheme' => 'tcp',
'host' => $host,
'port' => 6379,
]);

$value = $client->get($_GET['key']);
print('{"data": "' . $value . '"}');
}
} else {
phpinfo();
} ?>


書き込みならRedisのマスターへ接続し、読み込みならRedisのスレーブへ接続する制御をしています。

Redisのマスターのホスト名はredis-masterで、スレーブはredis-slaveで接続しています。RedisのDeploymentを作成したときに指定したnameがコンテナのDNS空間に反映されているということですね。

逆にDNSを使わない場合もあるので、その判別if (getenv('GET_HOSTS_FROM') == 'env') {を入れて環境変数を使う事も出来るようにしています。

frontend-deployment.yamlで以下の設定がされているので、このPHPではDNS名を使っています。


frontend-deployment.yaml

...

env:
- name: GET_HOSTS_FROM
value: dns # envにするとPHPが環境変数を使うようになる
...


レプリカ数を変更してみる

簡単に途中でレプリカ数を変更することができます。


  • レプリカ数を5へ変更する

$ kubectl scale deployment frontend --replicas=5

deployment "frontend" scaled


  • 5になっていることが分かります。

$ kubectl get deployment frontend

NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
frontend 5 5 5 5 51m


  • Podを見ると増えているのが分かります

$ kubectl get pods

NAME READY STATUS RESTARTS AGE
frontend-88237173-cp3rn 1/1 Running 0 26m
frontend-88237173-kuyzx 1/1 Running 0 6s # 増えたPod
frontend-88237173-kxlgh 1/1 Running 0 26m
frontend-88237173-sljba 1/1 Running 0 6s # 増えたPod
frontend-88237173-tw65g 1/1 Running 0 26m
redis-master-343230949-08kqi 1/1 Running 0 53m
redis-slave-132015689-3x3qp 1/1 Running 0 47m
redis-slave-132015689-b6cha 1/1 Running 0 47m


寄り道(kube edit)

kube editコマンドを使ってレプリカ数やその他の設定を変更することもできます。

$ KUBE_EDITOR=vim kubectl edit deployment frontend # デフォルトエディタはvi

上記コマンドで、設定ファイル(yaml)が開くので修正して保存すると設定を変更することができます。


障害発生時のPodの挙動

コマンドでPodを削除して、障害発生をシミュレーションしてみたいと思います。


  • シミュレーションする前に状態を確認します。

$ kubectl get pods

NAME READY STATUS RESTARTS AGE
frontend-88237173-cp3rn 1/1 Running 0 53m
frontend-88237173-kxlgh 1/1 Running 0 53m
frontend-88237173-tw65g 1/1 Running 0 53m
redis-master-343230949-08kqi 1/1 Running 0 1h
redis-slave-132015689-3x3qp 1/1 Running 0 1h
redis-slave-132015689-b6cha 1/1 Running 0 1h


  • Podを一つ削除します。

$ kubectl delete pod frontend-88237173-cp3rn

pod "frontend-88237173-cp3rn" deleted


  • 即座に新しいPodが作成されています。

$ kubectl get pods

NAME READY STATUS RESTARTS AGE
frontend-88237173-0omu3 1/1 Running 0 3s # 直ぐPodが作成された
frontend-88237173-kxlgh 1/1 Running 0 54m
frontend-88237173-tw65g 1/1 Running 0 54m
redis-master-343230949-08kqi 1/1 Running 0 1h
redis-slave-132015689-3x3qp 1/1 Running 0 1h
redis-slave-132015689-b6cha 1/1 Running 0 1h

見事にレプリカが再作成されました。 :tada:


ラベルを変更してみる

Kubernetesはラベルをみてレプリカ数をチェックしているとのことで、そのラベルに変更があった場合の挙動を確認してみたいと思います。


  • ラベルがtier=frontend のPodを表示します。

$ kubectl get pod -l tier=frontend

NAME READY STATUS RESTARTS AGE
frontend-88237173-0omu3 1/1 Running 0 21m # このPodのラベルを変更する
frontend-88237173-fadzg 1/1 Running 0 1m
frontend-88237173-tw65g 1/1 Running 0 1h


  • ひとつのPodのラベルを変更します。

$ kubectl label --overwrite pods frontend-88237173-0omu3 tier=middle

pod "frontend-88237173-0omu3" labeled


  • ラベルがtier=frontendのPodを表示します。新しいPodに入れ替っているのが分かります。

$ kubectl get pod -l tier=frontend

NAME READY STATUS RESTARTS AGE
frontend-88237173-fadzg 1/1 Running 0 2m
frontend-88237173-kkjpu 1/1 Running 0 4s # 新しいPodに変わっている
frontend-88237173-tw65g 1/1 Running 0 1h


  • frontendとしてレプリカ数は維持しています。

$ kubectl get deployment frontend

NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
frontend 3 3 3 3 1h # Podの数は変わらない


  • 変更したPodはDeployment外に存在しています。

$ kubectl get pod -l tier=middle

NAME READY STATUS RESTARTS AGE
frontend-88237173-0omu3 1/1 Running 0 22m # 変更したPodは存在している

こちらも見事にレプリカを維持してくれています。 :tada:


クリーンアップ

リソースを全て削除します。

$ kubectl delete service,deployment --all

service "frontend" deleted
service "kubernetes" deleted
service "redis-master" deleted
service "redis-slave" deleted
deployment "frontend" deleted
deployment "redis-master" deleted
deployment "redis-slave" deleted

$ gcloud container clusters delete guestbook
The following clusters will be deleted.
- [guestbook] in [asia-northeast1-a]

Do you want to continue (Y/n)? Y

Deleting cluster guestbook...done.
Deleted [https://container.googleapis.com/v1/projects/{PROJECT_ID}/zones/asia-northeast1-a/clusters/guestbook].


最後に

簡単にコンテナの運用ができると実感しました。

プロビジョニングも簡単ですが、それよりも運用中の管理が柔軟にできるのが最大な魅力だと思います。今度はローリングアップデートなどより実践に近いことを学んでいきたいと思います。

それでは :smiley: