1. Deployment概述
Deployment对象,顾名思义,是用于部署应用的对象。它使Kubernetes中最常用的一个对象,它为ReplicaSet和Pod的创建提供了一种声明式的定义方法,从而无需像前两篇文章中那样手动创建ReplicaSet和Pod对象(使用Deployment而不直接创建ReplicaSet是因为Deployment对象拥有许多ReplicaSet没有的特性,例如滚动升级和回滚)。
一个最简单的nginx应用,其Deployment文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
# 如果被指定, .spec.selector 必须匹配 .spec.template.metadata.labels,否则它将被API拒绝。如果 .spec.selector 没有被指定, .spec.selector.matchLabels 默认是 .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
通过kubectl create -f nginx-deployment.yaml
命令或者kubectl apply -f nginx-deployment.yaml
命令创建名为nginx-deployment的Deployment对象。
通过Deployment对象,你可以轻松的做到以下事情:
- 创建ReplicaSet和Pod
- 滚动升级(不停止旧服务的状态下升级)和回滚应用(将应用回滚到之前的版本)
- 平滑地扩容和缩容
- 暂停和继续Deployment
2. Deployment的创建
以上面的nginx-deployment.yaml文件为例,使用以下命令创建一个nginx的
Deployment:
kubectl create -f nginx-deployment.yaml --record
--record
参数可以记录当前版本的Deployment都执行过哪些命令。
创建完成后立即执行get命令可以查看这个Deployment:
$kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 0 0 0 1s
NAME
代表Deployment的名字,DESIRED
代表这个Deployment期望的副本数量,CURRENT代表当前已经创建了的副本数量,UP-TO-DATE
代表已经更新完成的副本数量,AVAILABLE
代表对于当前用户可用的副本数量,AGE
代表当前Deployment已经运行的时长。
等待几秒钟,再次运行get命令,可以查看到变化:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 3 3 3 18s
通过kubectl get rs
来查看系统中ReplicaSet对象,由此可以看出Deployment会自动创建一个ReplicaSet对象。
通过kubectl get pods --show-labels
命令来查看当前系统中的Pod对象,可以成功观察到nginx-deployment创建的3个Pod。
3. Deployment的更新
假如我们现在想要让 nginx pod 使用 nginx:1.9.1 的镜像来代替原来的 nginx:1.7.9 的镜像,运行以下命令:
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
或者我们可以使用 edit 命令来编辑 Deployment,将image从nginx:1.7.9 改写成 nginx:1.9.1。
kubectl edit deployment/nginx-deployment
查看更新进度:
$ 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
扩容:
kubectl scale deployment nginx-deployment --replicas 10
如果集群支持 horizontal pod autoscaling 的话,还可以为 Deployment 设置自动扩展:
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
Deployment更新时会创建一个新的ReplicaSet,然后将新的ReplicaSet中的Pod慢慢扩容到指定的副本数,将旧的ReplicaSet慢慢缩容到0。因此,更新时总能够确保旧的服务不会停止,这就是滚动更新。
4. Deployment的回滚
当我们像上文一样更新了Deployment之后,我们发现nginx:1.9.1的镜像不是很稳定,因此想要修改回nginx:1.7.9的版本,此时我们不需要手动更改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
因为我们创建 Deployment 的时候使用了 —recored 参数可以记录命令,我们可以很方便的查看每次 revison 的变化。
查看单个 revision 的详细信息:
kubectl rollout history deployment/nginx-deployment --revision=2
现在,可以使用rollout undo
命令回滚到前一个revision:
$ kubectl rollout undo deployment/nginx-deployment
deployment "nginx-deployment" rolled back
也可以使用--to-revision参数指定某个历史版本:
$ kubectl rollout undo deployment/nginx-deployment --to-revision=2
deployment "nginx-deployment" rolled back
你可以通过设置 .spec.revisonHistoryLimit 项来指定 deployment 最多保留多少 revison 历史记录。默认的会保留所有的 revision;如果将该项设置为 0,Deployment 就不允许回退了。
只有 Deployment 的 rollout 被触发才会创建一个 revision!注意!当且仅当 Deployment 的 Pod template被更改,例如更新 template 中的 label 和容器镜像时,才会触发一个rollout,从而为Deployment创建出一个新的 revision。
rollout
命令的更多用法:
滚动更新相关配置:
-
.spec.minReadySeconds
: 新创建的Pod状态为Ready持续的时间至少为.spec.minReadySeconds才认为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. 可以为整数或者百分比,默认为desired Pods数的25%. Scale Up新的ReplicaSet时,按照比例计算出允许的MaxSurge,计算时向上取整(比如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.可以为整数或者百分比,默认为desired Pods数的25%. Scale Down旧的ReplicaSet时,按照比例计算出允许的maxUnavailable,计算时向下取整(比如3.6,取3)。
因此,在Deployment rollout时,需要保证Available(Ready) Pods数不低于 desired pods number - maxUnavailable; 保证所有的Pods数不多于 desired pods number + maxSurge。
网友评论