1. Deployment概述
Deployment對(duì)象,顧名思義,是用于部署應(yīng)用的對(duì)象。它使Kubernetes中最常用的一個(gè)對(duì)象,它為ReplicaSet和Pod的創(chuàng)建提供了一種聲明式的定義方法,從而無(wú)需像前兩篇文章中那樣手動(dòng)創(chuàng)建ReplicaSet和Pod對(duì)象(使用Deployment而不直接創(chuàng)建ReplicaSet是因?yàn)镈eployment對(duì)象擁有許多ReplicaSet沒(méi)有的特性,例如滾動(dòng)升級(jí)和回滾)。
一個(gè)最簡(jiǎn)單的nginx應(yīng)用,其Deployment文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
# 如果被指定, .spec.selector 必須匹配 .spec.template.metadata.labels,否則它將被API拒絕。如果 .spec.selector 沒(méi)有被指定, .spec.selector.matchLabels 默認(rèn)是 .spec.template.metadata.labels。
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
或
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: frontend
spec:
minReadySeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 3
maxUnavailable: 2
replicas: 25
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
# If your cluster config does not include a dns service, then to
# instead access environment variables to find service host
# info, comment out the 'value: dns' line above, and uncomment the
# line below:
# value: env
ports:
- containerPort: 80
通過(guò)kubectl create -f nginx-deployment.yaml命令或者kubectl apply -f nginx-deployment.yaml命令創(chuàng)建名為nginx-deployment的Deployment對(duì)象。
通過(guò)Deployment對(duì)象,你可以輕松的做到以下事情:
- 創(chuàng)建ReplicaSet和Pod
- 滾動(dòng)升級(jí)(不停止舊服務(wù)的狀態(tài)下升級(jí))和回滾應(yīng)用(將應(yīng)用回滾到之前的版本)
- 平滑地?cái)U(kuò)容和縮容
- 暫停和繼續(xù)Deployment
2. Deployment的創(chuàng)建
以上面的nginx-deployment.yaml文件為例,使用以下命令創(chuàng)建一個(gè)nginx的
Deployment:
kubectl create -f nginx-deployment.yaml --record
--record參數(shù)可以記錄當(dāng)前版本的Deployment都執(zhí)行過(guò)哪些命令。
創(chuàng)建完成后立即執(zhí)行g(shù)et命令可以查看這個(gè)Deployment:
$kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 0 0 0 1s
NAME代表Deployment的名字,DESIRED代表這個(gè)Deployment期望的副本數(shù)量,CURRENT代表當(dāng)前已經(jīng)創(chuàng)建了的副本數(shù)量,UP-TO-DATE代表已經(jīng)更新完成的副本數(shù)量,AVAILABLE代表對(duì)于當(dāng)前用戶可用的副本數(shù)量,AGE代表當(dāng)前Deployment已經(jīng)運(yùn)行的時(shí)長(zhǎng)。
等待幾秒鐘,再次運(yùn)行g(shù)et命令,可以查看到變化:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 3 3 3 18s
通過(guò)kubectl get rs來(lái)查看系統(tǒng)中ReplicaSet對(duì)象,由此可以看出Deployment會(huì)自動(dòng)創(chuàng)建一個(gè)ReplicaSet對(duì)象。
通過(guò)kubectl get pods --show-labels命令來(lái)查看當(dāng)前系統(tǒng)中的Pod對(duì)象,可以成功觀察到nginx-deployment創(chuàng)建的3個(gè)Pod。
3. Deployment的更新
假如我們現(xiàn)在想要讓 nginx pod 使用 nginx:1.9.1 的鏡像來(lái)代替原來(lái)的 nginx:1.7.9 的鏡像,運(yùn)行以下命令:
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
或者我們可以使用 edit 命令來(lái)編輯 Deployment,將image從nginx:1.7.9 改寫成 nginx:1.9.1。
kubectl edit deployment/nginx-deployment
查看更新進(jìn)度:
$ kubectl rollout status deployment/nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out
擴(kuò)容:
kubectl scale deployment nginx-deployment --replicas 10
如果集群支持 horizontal pod autoscaling 的話,還可以為 Deployment 設(shè)置自動(dòng)擴(kuò)展:
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
Deployment更新時(shí)會(huì)創(chuàng)建一個(gè)新的ReplicaSet,然后將新的ReplicaSet中的Pod慢慢擴(kuò)容到指定的副本數(shù),將舊的ReplicaSet慢慢縮容到0。因此,更新時(shí)總能夠確保舊的服務(wù)不會(huì)停止,這就是滾動(dòng)更新。
4. Deployment的回滾
當(dāng)我們像上文一樣更新了Deployment之后,我們發(fā)現(xiàn)nginx:1.9.1的鏡像不是很穩(wěn)定,因此想要修改回nginx:1.7.9的版本,此時(shí)我們不需要手動(dòng)更改Deployment文件,而是利用Deployment的回滾功能。
使用rollout history命令查看Deployment的版本(revision):
$ kubectl rollout history deployment/nginx-deployment
deployments "nginx-deployment":
REVISION CHANGE-CAUSE
1 kubectl create -f docs/user-guide/nginx-deployment.yaml --record
2 kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
因?yàn)槲覀儎?chuàng)建 Deployment 的時(shí)候使用了 —recored 參數(shù)可以記錄命令,我們可以很方便的查看每次 revison 的變化。
查看單個(gè) revision 的詳細(xì)信息:
kubectl rollout history deployment/nginx-deployment --revision=2
現(xiàn)在,可以使用rollout undo命令回滾到前一個(gè)revision:
$ kubectl rollout undo deployment/nginx-deployment
deployment "nginx-deployment" rolled back
也可以使用--to-revision參數(shù)指定某個(gè)歷史版本:
$ kubectl rollout undo deployment/nginx-deployment --to-revision=2
deployment "nginx-deployment" rolled back
你可以通過(guò)設(shè)置 .spec.revisonHistoryLimit 項(xiàng)來(lái)指定 deployment 最多保留多少 revison 歷史記錄。默認(rèn)的會(huì)保留所有的 revision;如果將該項(xiàng)設(shè)置為 0,Deployment 就不允許回退了。
只有 Deployment 的 rollout 被觸發(fā)才會(huì)創(chuàng)建一個(gè) revision!注意!當(dāng)且僅當(dāng) Deployment 的 Pod template被更改,例如更新 template 中的 label 和容器鏡像時(shí),才會(huì)觸發(fā)一個(gè)rollout,從而為Deployment創(chuàng)建出一個(gè)新的 revision。
rollout命令的更多用法:
滾動(dòng)更新相關(guān)配置:
-
.spec.minReadySeconds: 新創(chuàng)建的Pod狀態(tài)為Ready持續(xù)的時(shí)間至少為.spec.minReadySeconds才認(rèn)為Pod Available(Ready)。 -
.spec.strategy.rollingUpdate.maxSurge: specifies the maximum number of Pods that can be created over the desired number of Pods. The value cannot be 0 if MaxUnavailable is 0. 可以為整數(shù)或者百分比,默認(rèn)為desired Pods數(shù)的25%. Scale Up新的ReplicaSet時(shí),按照比例計(jì)算出允許的MaxSurge,計(jì)算時(shí)向上取整(比如3.4,取4)。 -
.spec.strategy.rollingUpdate.maxUnavailable: specifies the maximum number of Pods that can be unavailable during the update process. The value cannot be 0 if maxSurge is 0.可以為整數(shù)或者百分比,默認(rèn)為desired Pods數(shù)的25%. Scale Down舊的ReplicaSet時(shí),按照比例計(jì)算出允許的maxUnavailable,計(jì)算時(shí)向下取整(比如3.6,取3)。
因此,在Deployment rollout時(shí),需要保證Available(Ready) Pods數(shù)不低于 desired pods number - maxUnavailable; 保證所有的Pods數(shù)不多于 desired pods number + maxSurge。