infrastructure

GCP ロードバランサと GKE クラスタを Terraform を使って構築する

GCP ロードバランサと GKE クラスタを Terraform を使って構築自動化

4 minute read

こんにちは。@jedipunkz です。

少し前まで Google Cloud Platform (GCP) を使っていたのですが、今回はその時に得たノウハウを記事にしようと思います。

Google Container Engine (GKE) とロードバランサを組み合わせてサービスを立ち上げていました。手動でブラウザ上からポチポチして構築すると人的ミスや情報共有という観点でマズイと思ったので Terraform を使って GCP の各リソースを構築するよう仕掛けたのですが、まだまだ Terraform を使って GCP インフラを構築されている方が少ないため情報が無く情報収集や検証に時間が掛かりました。よって今回はまだネット上に情報が少ない GKE とロードバランサの構築を Terraform を使って行う方法を共有します。

構築のシナリオ

構築するにあたって2パターンの構築の流れがあると思います。

  • 1) GKE クラスタとロードバランサを同時に構築する
  • 2) GKE クラスタを予め構築しそのクラスタ向けにロードバランサを構築する

両方の方法を記していきます。

1) GKE クラスタとロードバランサを同時に構築する

GKE クラスタとロードバランサを同時に作る方法です。

早速ですが下記に terraform ファイルを記しました。それぞれのシンタックスの意味については Terraform の公式ドキュメントをご覧になってください。

公式ドキュメント : https://www.terraform.io/docs/providers/google/

ここで特筆すべき点としては下記が挙げられます。

ロードバランサに紐付けるバックエンドの ID 取得のため “${replace(element…” 的なことをしている

ロードバランサのバックエンドサービスに対して GKE クラスタを作成した際に自動で作成されるインスタンスグループの URI を紐付ける必要があります。ユーザとしては URI ではなく “インスタンスグループ名” であると扱いやすいのですが、URI が必要になります。この情報は下記のサイトを参考にさせていただきました。

ロードバランサ一つ作るために 6 個ものインフラリソースを作っている

一つのロードバランサを作るために6つのインフラリソースが必要になるというのも驚きですが公式ドキュメントを読むとなかなかその感覚がつかめませんでした。それぞれの簡単な意味を下記に記しておきます。

  • google_compute_http_health_check : ヘルスチェック
  • google_compute_backend_service : バックエンドサービス
  • google_compute_url_map : ロードバランサ名となるリソース
  • google_compute_target_http_proxy : プロキシ
  • google_compute_global_address : グローバル IP アドレス
  • google_compute_global_forwarding_rule : ポートマッピングによるフォワーディングルール

それでは実際の Terraform コードです

# 共通変数
variable "credentials" {default = "/path/to/credentials.json"}
variable "project" {default = "test01"}
variable "region" {default = "asia-northeast"}
variable "zone" {default = "asia-northeast1-b"}
# GKE クラスタ用の変数
variable "gke_name" {default = "gke-terraform-test"}
variable "machine_type" {default = "n1-standard-1"}
variable "disk_size_gb" {default = "50"}
variable "node_count" {default = "2"}
variable "network" {default = "default"}
variable "subnetwork" {default = "default"}
variable "cluster_ipv4_cidr" {default = "10.0.10.0/14"}
variable "username" {default = "username"}
variable "password" {default = "password"}
# ロードバランサ用の変数
variable "lb_name" {default = "lb-terraform-test"}
variable "healthcheck_name" {default = "healthcheck-terraform-test"}
variable "healthcheck_host" {default = "test.example.com"}
variable "healthcheck_port" {default = "30300"}
variable "backend_name" {default = "backend-terraform-test"}
variable "http_proxy_name" {default = "terraform-proxy"}
variable "global_address_name" {default = "terraform-global-address"}
variable "global_forwarding_rule_name" {default = "terraform-global-forwarding-rule"}
variable "global_forwarding_rule_port" {default ="80"}
variable "port_name" {default = "port-test"}
variable "enable_cdn" {default = false}

provider "google" {
  credentials = "${file("${var.credentials}")}"
  project     = "${var.project}"
  region      = "${var.region}"
}

resource "google_container_cluster" "cluster-terraform" {
  name                = "${var.gke_name}"
  zone                = "${var.zone}"
  initial_node_count  = "${var.node_count}"
  network             = "${var.network}"
  subnetwork          = "${var.subnetwork}"
  cluster_ipv4_cidr   = "${var.cluster_ipv4_cidr}"

  master_auth {
    username = "${var.username}"
    password = "${var.password}"
  }

  node_config {
    machine_type = "${var.machine_type}"
    disk_size_gb = "${var.disk_size_gb}"
    oauth_scopes = [
      "https://www.googleapis.com/auth/compute",
      "https://www.googleapis.com/auth/devstorage.read_only",
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring"
    ]
  }
  addons_config {
    http_load_balancing {
      disabled = true
    }
    horizontal_pod_autoscaling {
      disabled = true
    }
  }
}

resource "google_compute_http_health_check" "healthcheck-terraform" {
  name                = "${var.healthcheck_name}"
  project             = "${var.project}"
  request_path        = "/"
  host                = "${var.healthcheck_host}"
  check_interval_sec  = 5
  timeout_sec         = 5
  port                = "${var.healthcheck_port}"
}
resource "google_compute_backend_service" "backend-terraform" {
  name          = "${var.backend_name}"

  port_name     = "${var.port_name}"
  protocol      = "HTTP"
  timeout_sec   = 10
  enable_cdn    = "${var.enable_cdn}"
  region        = "${var.region}"
  project       = "${var.project}"
  backend {
    group = "${replace(element(google_container_cluster.cluster-terraform.instance_group_urls, 1), "Manager","")}"
  }
  health_checks = ["${google_compute_http_health_check.healthcheck-terraform.self_link}"]
}
resource "google_compute_url_map" "lb-terraform" {
  name            = "${var.lb_name}"
  default_service = "${google_compute_backend_service.backend-terraform.self_link}"
  project         = "${var.project}"
}
resource "google_compute_target_http_proxy" "http_proxy-terraform" {
  name        = "${var.http_proxy_name}"
  url_map     = "${google_compute_url_map.lb-terraform.self_link}"
}
resource "google_compute_global_address" "ip-terraform" {
  name    = "${var.global_address_name}"
  project = "${var.project}"
}
resource "google_compute_global_forwarding_rule" "forwarding_rule-terraform" {
  name        = "${var.global_forwarding_rule_name}"
  target      = "${google_compute_target_http_proxy.http_proxy-terraform.self_link}"
  ip_address  = "${google_compute_global_address.ip-terraform.address}"
  port_range  = "${var.global_forwarding_rule_port}"
  project     = "${var.project}"
}

2) GKE クラスタを予め構築しそのクラスタ向けにロードバランサを構築する

次に GKE クラスタとロードバランサを別々のタイミングに構築する方法です。 実際には GKE クラスタの上には多数のコンテナが起動されるのですでにクラスタが存在する状態でロードバランサを別サービスのために作成したいというケースが一般的なように思います。

GKE クラスタのインスタンスグループ URI を取得し設定

既存 GKE クラスタを用いる場合、インスタンスグループ URI がいずれにせよ必要になります。 インスタンスグループ URI を取得するには gcloud CLI を使って下記のように知ることができます。

$ gcloud compute instance-groups managed describe | grep -rin URI

ここで得たインスタンスグループ URI は下記のように variable “backend_group” に記します。

Port マッピングを手動で設定

ここは残念なのですが 201704 現在、Port マッピングの設定を WebUI 上から行う必要があります。UI から GKE クラスタのインスタンスグループを選択し、Port マッピングの設定を行い名前を記します。ここでは “port-test” として作成したとし説明します。

Terraform のコードを記述

ここでロードバランサ単独で構築する際の Terraform コードを見てみます。

variable "credentials" {default = "/path/to/credentials.json"}
variable "project" {default = "test01"}
variable "region" {default = "asia-northeast1"}
variable "lb_name" {default = "lb-terraform-test"}
variable "healthcheck_name" {default = "healthcheck-terraform-test"}
variable "healthcheck_host" {default = "test.example.com"}
variable "healthcheck_port" {default = "30300"}
variable "backend_name" {default = "backend-terraform-test"}
variable "backend_group" {default = "https://www.googleapis.com/compute/v1/projects/test01/zones/asia-northeast1-b/instanceGroups/gke-gke-terraform-test-default-pool-c001020e-grp"}
variable "http_proxy_name" {default = "terraform-proxy"}
variable "global_address_name" {default = "terraform-global-address"}
variable "global_forwarding_rule_name" {default = "terraform-global-forwarding-rule"}
variable "global_forwarding_rule_port" {default ="80"}
variable "port_name" {default = "port-test"}
variable "enable_cdn" {default = false}

provider "google" {
  credentials = "${file("${var.credentials}")}"
  project     = "${var.project}"
  region      = "${var.region}"
}
resource "google_compute_http_health_check" "healthcheck-terraform-test" {
  name                = "${var.healthcheck_name}"
  project             = "${var.project}"
  request_path        = "/"
  host                = "${var.healthcheck_host}"
  check_interval_sec  = 5
  timeout_sec         = 5
  port                = "${var.healthcheck_port}"
}
resource "google_compute_backend_service" "backend-terraform-test" {
  name          = "${var.backend_name}"
  port_name     = "${var.port_name}"
  protocol      = "HTTP"
  timeout_sec   = 10
  enable_cdn    = "${var.enable_cdn}"
  region        = "${var.region}"
  project       = "${var.project}"
  backend {
    group = "${var.backend_group}"
  }
  health_checks = ["${google_compute_http_health_check.healthcheck-terraform-test.self_link}"]
}
resource "google_compute_url_map" "lb-terraform-test" {
  name            = "${var.lb_name}"
  default_service = "${google_compute_backend_service.backend-terraform-test.self_link}"
  project         = "${var.project}"
}
resource "google_compute_target_http_proxy" "http_proxy-terraform-test" {
  name        = "${var.http_proxy_name}"
  url_map     = "${google_compute_url_map.lb-terraform-test.self_link}"
}
resource "google_compute_global_address" "ip-terraform-test" {
  name    = "${var.global_address_name}"
  project = "${var.project}"
}
resource "google_compute_global_forwarding_rule" "forwarding_rule-terraform-test" {
  name        = "${var.global_forwarding_rule_name}"
  target      = "${google_compute_target_http_proxy.http_proxy-terraform-test.self_link}"
  ip_address  = "${google_compute_global_address.ip-terraform-test.address}"
  port_range  = "${var.global_forwarding_rule_port}"
  project     = "${var.project}"

まとめ

GCP のロードバランサが特徴的な構築方法が必要になることが分かったと思います。将来的に URI で記す箇所を名前で記せれば構築がもっと簡単になると思いますので GCP 側の API バージョンアップを期待します。また今回は記しませんでしたが SSL (HTTPS) 証明書をロードバランサに紐付けることも Terraform を使えば容易に出来ます。試してみてください。一旦 Terraform 化すればパラメータを変更するだけで各ロードバランサが一発で構築できるので自動化は是非しておきたいところです。私は以前、この構築を Terraform + Hubot により ChatOps 化していました。作業の見える化と、メンバ間のコードレビューが可能になるからです。

Serverless on Kubernetes : Fission を使ってみた

Kubernetes 上で Serverless を実現する Fission を使ってみた

jedipunkz

2 minute read

こんにちは。 @jedipunkz です。

今日は Kubernetes を使って Serverless を実現するソフトウェア Fission を紹介します。

AWS の Lambda とよく似た動きをします。Lambda も内部では各言語に特化したコンテナが起動してユーザが開発した Lambda Function を実行してくれるのですが、Fission も各言語がインストールされた Docker コンテナを起動しユーザが開発したコードを実行し応答を返してくれます。

それでは早速なのですが、Fission を動かしてみましょう。

動作させるための環境

macOS か Linux を前提として下記の環境を用意する必要があります。また Kubernetes 環境は minikube が手っ取り早いので用いますが、もちろん minikube 以外の kubernetes 環境でも動作します。

  • macOS or Linux
  • minikube or kubernetes
  • kubectl
  • fission

ソフトウェアのインストール方法

簡単にですが、ソフトウェアのインストール方法を書きます。

OS

私は Linux で動作させましたが筆者の方は macOS を使っている方が多数だと思いますので、この手順では macOS を使った利用方法を書いていきます。

minikube

ここでは簡単な手順で kubernetes 環境を構築できる minikube をインストールします。

curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.16.0/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/fission

kubectl

直接必要ではありませんが、kubectl があると minikube で構築した kubernetes 環境を操作できますのでインストールしておきます。

curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.5.2/bin/linux/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/

Fission

Fission のインストールです。

curl http://fission.io/linux/fission > fission && chmod +x fission && sudo mv fission /usr/local/bin/fission

kubernetes の起動

ソフトウェアのインストールが完了したら minikube を使って kubernetes を起動します。

$ minikube start
$ minikube status
minikubeVM: Running
localkube: Running
$ kubectl get nodes
NAME       STATUS    AGE
minikube   Ready     1h

Fission の起動と環境変数の設定

Fission を起動します。

$ kubectl create -f http://fission.io/fission.yaml
$ kubectl create -f http://fission.io/fission-nodeport.yaml

次に環境変数を設定します。

$ export FISSION_URL=http://$(minikube ip):31313
$ export FISSION_ROUTER=$(minikube ip):31314

Fission を使って Python のコードを実行する

例として Python の Hello World を用意します。hello.py として保存します。

def main():
        return "Hello, world!\n"

ではいよいよ、kubernetes と Fission を使って上記の Hello World を実行させます。

まず Fission が用意してくれている Docker コンテナを扱うように ‘env’ を作ります。

$ fission env create --name python-env --image fission/python-env

次に Fission で Function を作ります。その際に上記の env と python コードを指定します。つまり、hello.py を fission/python-env という Docker コンテナで稼働する、という意味です。

$ fission function create --name python-hello -env python-env --code ./hello.py

次に Router を作ります。クエリの Path に対して Fuction を関連付けることができます。

$ fission route add --function python-hello --url /python-hello

Function を実行する環境ができました。実際に curl を使ってアクセスしてみましょう。

$ curl http://$FISSION_ROUTER/python-hello
Hello, world!

hello.py の実行結果が得られました。

まとめと考察

結果から Fission は “各言語の実行環境として Docker コンテナを用いていて、ユーザが開発したコードをそのコンテナ上で起動し実行結果を得られる。また各コード毎に URL パスが指定することができ、それをルータとして関係性を持たせられる” ということが分かりました。AWS の Lambda とほぼ同じことが実現出来ていることが分かると思います。

AWS には Lambda の実行結果を応答するための API Gateway があり、このマネージド HTTP サーバと併用することで API 環境を用意出来るのですが Fission の場合には HTTP サーバも込みで提供されていることも分かります。

あとは、この Fission を提供している元が “Platform9” という企業なのですが、この企業は OpenStack や kubernetes を使ったホスティングサービスを提供しているようです。開発元が一企業ということと、完全な OSS 開発体制になっていない可能性があって、万が一この企業に何かあった場合にこの Fission を使い続けられるのか問題がしばらくはありそうです。Fission 同等のソフトウェアを kubernetes が取り込むという話題は…あるのかなぁ?

kubernetes の Job Scheduler が同等の機能を提供してくれるかもしれませんが、まだ Job Scheduler は利用するには枯れていない印象があります。Fission と Job Scheduler 、どちらがいち早く完成度を上げられるのでしょうか。

Kubernetes Deployments を使ってみた!

Kubernetes Replication Controller の次世代版 Deployments を使ってみました

jedipunkz

4 minute read

こんにちは。 @jedipunkz です。

いま僕らは職場では GKE 上に Replication Controller と Services を使って Pod を起動しているのですが最近の Kubernetes 関連のドキュメントを拝見すると Deployments を使っている記事をよく見掛けます。Kubernetes 1.2 から実装されたようです。今回は Kubernetes の Replication Controller の次世代版と言われている Deployments について調べてみましたので理解したことを書いていこうかと思います。

参考資料

今回は Kubernetes 公式の下記のドキュメントに記されているコマンドを一通り実行していきます。追加の情報もあります。

Deployments を使って nginx Pod を起動

nginx をデプロイするための Yaml ファイルを用意します。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

作成した yaml ファイルを指定して Pod を作ります。 下記の通りここで “–record” と記しているのは、後に Deployments の履歴を表示する際に “何を行ったか” を出力するためです。このオプションを指定しないと “何を行ったか” の出力が “NONE” となります。

$ kubectl create -f nginx.yaml --record

ここで

  • deployments
  • replica set
  • pod
  • rollout

の状態をそれぞれ確認してみます。

$ kubectl get deployments
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2         2         2            2           8s

$ kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-4087004473   2         2         2         10s

$ kubectl get pods --show-labels
NAME                                READY     STATUS    RESTARTS   AGE       LABELS
nginx-deployment-4087004473-6csa7   1/1       Running   0          21s       app=nginx,pod-template-hash=4087004473
nginx-deployment-4087004473-teyzc   1/1       Running   0          21s       app=nginx,pod-template-hash=4087004473

$ kubectl rollout status deployment/nginx-deployment
deployment nginx-deployment successfully rolled out

結果から、下記の事が分かります。

  • yaml に記した通り “nginx-deployment” という名前で deployment が生成された
  • “nginx-deployment-4087004473” という名前の rs (レプリカセット) が生成された
  • yaml に記した通り2つの Pod が起動した
  • “nginx-deployment” が正常に Rollout された

Replication Controller でデプロイした際には作られない replica set, rollout というモノが出てきました。後に Deployments を使うメリットに繋がっていきます。

nginx イメージの Tag を更新してみる

ここで yaml ファイル内で指定していた “image: nginx:1.7.9” を “image: nginx:1.9.1” と更新してみます。 Replication Controller で言う Rolling-Update になります。後に述べますが他にも更新方法があります。

$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1

ここで先ほどと同様に状態を確認してみます。

$ kubectl get deployments
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2         2         2            2           2m

$ kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-3599678771   2         2         2         39s
nginx-deployment-4087004473   0         0         0         2m

$ kubectl get pods
NAME                                READY     STATUS    RESTARTS   AGE
nginx-deployment-3599678771-0vj9m   1/1       Running   0          53s
nginx-deployment-3599678771-t1y62   1/1       Running   0          53s

ここで…

  • 新しい Replica Set “nginx-deployment-3599678771” が作成された
  • 古い Replica Set “nginx-deployment-4087004473” の Pod は 0 個になった
  • Pod 内コンテナが更新された (NAME より判断)

となったことが分かります。 Replication Controller と異なり、Deployments では以前の状態が Replica Set として保存されていて状態の履歴が追えるようになっています。

ここで Rollout の履歴を確認してみます。

$ kubectl rollout history deployment/nginx-deployment
deployments "nginx-deployment"
REVISION        CHANGE-CAUSE
1               kubectl create -f nginx.yaml --record
2               kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1

REVISION という名前で履歴番号が付き、どの様な作業を行ったか CHANGE-CAUSE という項目で記されていることがわかります。作業の履歴がリビジョン管理されています。

下記のように REVSION 番号を付与して履歴内容を表示することも可能です。

$ kubectl rollout history deployment/nginx-deployment --revision=2
deployments "nginx-deployment" with revision #2
  Labels:       app=nginx
        pod-template-hash=3599678771
  Annotations:  kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
  Containers:
   nginx:
    Image:      nginx:1.9.1
    Port:       80/TCP
    Volume Mounts:      <none>
    Environment Variables:      <none>
  No volumes.

作業を切り戻してみる

先程 nginx の Image Tag を更新しましたが、ここで Deployments の機能を使って作業を切り戻してみます。下記の様に実行します。

$ kubectl rollout undo deployment/nginx-deployment

状態を確認します。

$ kubectl get deployments
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2         2         2            2           5m

$ kubectl rollout history deployment/nginx-deployment
deployments "nginx-deployment"
REVISION        CHANGE-CAUSE
2               kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
3               kubectl create -f nginx.yaml --record

ここでは…

  • コンテナが2個、正常に起動した
  • REVISION 番号 3 として初期構築の状態 (kubectl create ..) が新たに保存

ということが分かります。注意したいのは REVSION 番号 1 が削除され 3 が生成されたことです。1 と 3 は同じ作業ということと推測します。

念のため ‘nginx’ コンテナの Image Tag が切り戻っているか確認してみます。

$ kubectl describe pod nginx-deployment-4087004473-nq35u | grep "Image:"
    Image:              nginx:1.7.9

最初の Yaml ファイルに記した ‘nginx’ イメージ Tag “1.7.9” となっていることが確認できました。set image … でイメージ更新をした作業が正常に切り戻ったことになります。

レプリカ数を 2->3 へスケールしてみる

更に replicas の数値を 2 から 3 へスケールしてみます。

$ kubectl scale deployment nginx-deployment --replicas 3

同様に状態を確認してみます。

kubectl get pods
NAME                                READY     STATUS    RESTARTS   AGE
nginx-deployment-4087004473-esj5l   1/1       Running   0          6s
nginx-deployment-4087004473-nq35u   1/1       Running   0          4m
nginx-deployment-4087004473-tyibo   1/1       Running   0          4m

kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-3599678771   0         0         0         9m
nginx-deployment-4087004473   3         3         3         11m

kubectl rollout history deployment/nginx-deployment
deployments "nginx-deployment"
REVISION        CHANGE-CAUSE
2               kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
3               kubectl scale deployment nginx-deployment --replicas 3

ここで気になるのは REVISION 3 が上書きされたことです。REVSION 番号 4 が新たに作成されると思っていたからです。先程 REVISION 番号 3 として保存されていた下記の履歴が消えてしまいました。この点については引き続き検証してみます。今の自分には理解できませんでした。ご存知の方いましたら、コメントお願いします!

3               kubectl create -f nginx.yaml --record

Puase, Resume 機能を使ってみる

次は deployments の機能を使って Image Tag を更に 1.9.1 へ変更し、その処理をポーズしてみます。

kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1; kubectl

同様に状態を確認してみます。

$ kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-3599678771   2         2         2         10m
nginx-deployment-4087004473   2         2         2         12m

$ kubectl rollout status deployment/nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Ctrl-C #<--- キー入力

rollout status で deployment “deployment/nginx-deployment” を確認すると “waiting for rollout to finish” と表示され処理がポーズされていることが確認できました。また古い Deployment “nginx-deployment-4087004473” 上に未だコンテナが残り、新しい Deployment もコンテナが生成中であることが分かります。

では Resume します。

$ kubectl rollout resume deployment/nginx-deployment
deployment "nginx-deployment" resumed

この時点の状態を確認しましょう。

$ kubectl rollout status deployment/nginx-deployment
deployment nginx-deployment successfully rolled out

$ kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-3599678771   3         3         3         11m
nginx-deployment-4087004473   0         0         0         14m

ここからは…

  • 正常に Deployment “nginx-deployment” が Rollout されたこと
  • 古い Deployment 上のコンテナ数が 0 に、新しい Deployment 上のコンテナ数が 3 になった

ということが分かります。

Rolling-Update 相当の作業を行う方法

前述した通り、Replication Controller 時代にあった Rolling-Update 作業 (イメージタグ・レプリカ数等の更新) ですが、Deployments では下記の方法をとることが出来ます。

set オプションを付与する場合

set オプションを付与して Key 項目に対して新しい Value を渡します。

$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1

yaml ファイルを修正する場合

yaml ファイルの内容を更新して適用したい場合、下記のように apply オプションを付与します。

$ kubectl apply -f <新しいYamlファイル>

まとめと考察

REVISION の履歴が上書きされる点など、まだ未完成な感が否めませんでしたが(自分の勘違いかもしれません!)、Replication Controller と比べると作業の切り戻しや、履歴が保存され履歴内容も確認できる点など機能が追加されていることが分かりました。公式ドキュメントを読んでいてもコマンド結果等怪しい点があって流石に API バージョンが “v1beta1” だなぁという感じではありますが、機能が整理されていて利便性が上がっているので Replication Controller を使っているユーザは自然と今後、Deployments に移行していくのではないかと感じました。