KubernetesのDeploymentを試す
k8sでDockerイメージを更新するのはどうやるのかなと思って調べたところ、 Deployments というものがあるようなので触ってみた。
これは Pod と ReplicaSet をまとめて管理できるようなもののようですね。
Deployment用のマニフェスト
mysqlは作成済み。以前作ったReplicationControllerやPodは削除しておいた。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: rails-deploy
spec:
replicas: 5
template:
metadata:
labels:
app: rails
spec:
containers:
- name: rails
image: localhost:5000/r_takaishi/docker-mysql-rails:0.0.1
command: ["bundle", "exec", "rails", "s", "-p", "3000", "-b", "0.0.0.0"]
env:
- name: RAILS_ENV
value: development
- name: MYSQL_HOST
value: mysql.default.svc.cluster.local
- name: MYSQL_USER
value: root
- name: MYSQL_PASSWORD
value: passw0rd
lifecycle:
postStart:
exec:
command:
- /myapp/post-start.sh
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: rails
spec:
ports:
- port: 3000
targetPort: 3000
protocol: TCP
type: LoadBalancer
selector:
app: rails
Deploymentを作る
Deploymentを作成します。kubectlコマンドにもそろそろ慣れてきたな。
$ kubectl apply -f ./deploy.yml
deployment "rails-deploy" created
service "rails" configured
作成するとDeploymentとReplicaSet、Pod、Serviceが作られる。
# deployment一覧
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
rails-deploy 5 5 5 5 30s
# replicaset一覧
$ kubectl get replicasets
NAME DESIRED CURRENT READY AGE
rails-deploy-3732838062 5 5 5 35s
# pods一覧
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-8kd4q 1/1 Running 4 7d
rails-deploy-3732838062-4zwgr 1/1 Running 0 37s
rails-deploy-3732838062-hzv0q 1/1 Running 0 37s
rails-deploy-3732838062-mlw93 1/1 Running 0 37s
rails-deploy-3732838062-x388m 1/1 Running 0 37s
rails-deploy-3732838062-zvxbq 1/1 Running 0 37s
# service一覧
$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.0.0.1 <none> 443/TCP 7d
mysql 10.0.0.253 <pending> 3306:31785/TCP 7d
rails 10.0.0.214 <pending> 3000:31640/TCP 1h
イメージを更新したらローリングデプロイされる様子を観察する
この時点ではデプロイされているイメージは0.0.1。
$ kubectl get pods -o json | jq -r '.items[] | [.metadata.name, .status.phase, .spec.containers[0].image] | @tsv'
mysql-8kd4q Running mysql
rails-deploy-3732838062-5bpzw Running localhost:5000/r_takaishi/docker-mysql-rails:0.0.1
rails-deploy-3732838062-c086n Running localhost:5000/r_takaishi/docker-mysql-rails:0.0.1
rails-deploy-3732838062-dp1xl Running localhost:5000/r_takaishi/docker-mysql-rails:0.0.1
rails-deploy-3732838062-mg55s Running localhost:5000/r_takaishi/docker-mysql-rails:0.0.1
rails-deploy-3732838062-nn7dv Running localhost:5000/r_takaishi/docker-mysql-rails:0.0.1
これを0.0.2などに変更すると、そのイメージにローリングデプロイされるはず。
イメージを更新するにはこうやる。簡単〜
$ kubectl set image deployment/rails-deploy rails=localhost:5000/r_takaishi/docker-mysql-rails:0.0.2
deployment "rails-deploy" image updated
デプロイの様子を見守ろう。
$ watch -n 0.5 "kubectl get pods -o json | jq -r '.items[] | [.metadata.name, .status.phase, .spec.containers[0].image] | @tsv'"
ちゃんと、少しずつ0.0.1から0.0.2に切り替わっていることを確認できた。すごい!
ロールバックやオートスケールなど
間違えたような場合はロールバックできる。
$ kubectl rollout undo deployment/rails-deploy
レプリカセットの台数も設定可能。
$ kubectl scale deployment rails-deploy --replicas 5
まとめ
Deployment機能を触って、イメージを簡単に更新できそうだ、というのを知ることができた。ロールバック、スケールアウトも楽々でわくわくする。ただ、起動コンテナが増えた場合やそもそものイメージサイズが大きい場合、完全に切り替わるのにどのくらい時間がかかるのかは気になるな。