29.Deployment
Deployment
- 定义
Deployment 来创建Pod 和ReplicaSet - 滚动升级和回滚应用
- 扩容和缩容
- 暂停和继续
Deployment
比如一个简单的
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
扩容:
kubectl scale deployment nginx-deployment --replicas 10
如果集群支持
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
更新镜像也比较简单:
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
回滚:
kubectl rollout undo deployment/nginx-deployment
Deployment 结构示意图
Deployment 是什么?
您只需要在
注意:您不该手动管理由
典型的用例如下:
- 使用
Deployment 来创建ReplicaSet 。ReplicaSet 在后台创建pod 。检查启动状态,看它是成功还是失败。 - 然后,通过更新
Deployment 的PodTemplateSpec 字段来声明Pod 的新状态。这会创建一个新的ReplicaSet ,Deployment 会按照控制的速率将pod 从旧的ReplicaSet 移动到新的ReplicaSet 中。 - 如果当前状态不稳定,回滚到之前的
Deployment revision 。每次回滚都会更新Deployment 的revision 。 - 扩容
Deployment 以满足更高的负载。 - 暂停
Deployment 来应用PodTemplateSpec 的多个修复,然后恢复上线。 - 根据
Deployment 的状态判断上线是否hang 住了。 - 清除旧的不必要的
ReplicaSet 。
创建Deployment
下面是一个
下载示例文件并执行命令:
$ kubectl create -f https://kubernetes.io/docs/user-guide/nginx-deployment.yaml --record
deployment "nginx-deployment" created
将--record
的true
可以在
然后立即执行 get
将获得如下结果:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 0 0 0 1s
输出结果表明我们希望的.spec.replicas
配置)当前.status.replicas
)是.status.updatedReplicas
)是.status.availableReplicas
)是
过几秒后再执行 get
命令,将获得如下输出:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 3 3 3 18s
我们可以看到.spec.minReadySeconds
声明,处于已就绪状态的kubectl get rs
和kubectl get pods
会显示
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-2035384211 3 3 0 18s
您可能会注意到<Deployment 的名字>-<pod template 的 hash 值>
。
$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-2035384211-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211
nginx-deployment-2035384211-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211
nginx-deployment-2035384211-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211
刚创建的
注意: 您必须在app = nginx
Pod-template-hash label
注意:这个
注意上面示例输出中的
更新Deployment
注意:.spec.template
)中的
假如我们现在想要让nginx:1.9.1
的镜像来代替原来的 nginx:1.7.9
的镜像。
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
deployment "nginx-deployment" image updated
我们可以使用edit
命令来编辑.spec.template.spec.containers [0].image
,将nginx:1.7.9
改写成nginx:1.9.1
。
$ kubectl edit deployment/nginx-deployment
deployment "nginx-deployment" edited
查看
$ 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
get
Deployment:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 3 3 3 36s
我们通过执行 kubectl get rs
可以看到
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-1564180365 3 3 0 6s
nginx-deployment-2035384211 0 0 0 36s
执行get pods
只会看到当前的新的
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-1564180365-khku8 1/1 Running 0 14s
nginx-deployment-1564180365-nacti 1/1 Running 0 14s
nginx-deployment-1564180365-z9gth 1/1 Running 0 14s
下次更新这些
在未来的
例如,如果您自己看下上面的
$ kubectl describe deployments
Name: nginx-deployment
Namespace: default
CreationTimestamp: Tue, 15 Mar 2016 12:01:06 -0700
Labels: app=nginx
Selector: app=nginx
Replicas: 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-1564180365 (3/3 replicas created)
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
36s 36s 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3
23s 23s 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1
23s 23s 1 {deployment-controller} Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2
23s 23s 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2
21s 21s 1 {deployment-controller} Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0
21s 21s 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3
我们可以看到当我们刚开始创建这个
当我们更新这个
接着继续使用相同的
Rollover(多个rollout 并行)
每当.spec.selector
匹配但是.spec.template
不匹配的.spec.replicas
指定数目的
如果您更新了一个的已存在并正在进行中的
例如,假如您创建了一个有niginx:1.7.9
nginx:1.7.9
的nginx:1.9.1
nginx:1.7.9
的nginx:1.9.1
的nginx:1.7.9
的
Label selector 更新
我们通常不鼓励更新
任何情况下,只要您想要执行
- 增添
selector 需要同时在Deployment 的spec 中更新新的label ,否则将返回校验错误。此更改是不可覆盖的,这意味着新的selector 不会选择使用旧selector 创建的ReplicaSet 和Pod ,从而导致所有旧版本的ReplicaSet 都被丢弃,并创建新的ReplicaSet 。 - 更新
selector ,即更改selector key 的当前值,将导致跟增添selector 同样的后果。 - 删除
selector ,即删除Deployment selector 中的已有的key ,不需要对Pod template label 做任何更改,现有的ReplicaSet 也不会成为孤儿,但是请注意,删除的label 仍然存在于现有的Pod 和ReplicaSet 中。
回退Deployment
有时候您可能想回退一个
默认情况下,revision history limit
来更改保存的
注意:只要.spec.template
)被更改,例如更新
其他的更新,比如扩容
假设我们在更新nginx:1.91
,而正确的名字应该是 nginx:1.9.1
:
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.91
deployment "nginx-deployment" image updated
$ kubectl rollout status deployments nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
按住
您会看到旧的
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-1564180365 2 2 0 25s
nginx-deployment-2035384211 0 0 0 36s
nginx-deployment-3066724191 2 2 2 6s
看下创建
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-1564180365-70iae 1/1 Running 0 25s
nginx-deployment-1564180365-jbqqo 1/1 Running 0 25s
nginx-deployment-3066724191-08mng 0/1 ImagePullBackOff 0 6s
nginx-deployment-3066724191-eocby 0/1 ImagePullBackOff 0 6s
注意,
$ kubectl describe deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Tue, 15 Mar 2016 14:48:04 -0700
Labels: app=nginx
Selector: app=nginx
Replicas: 2 updated | 3 total | 2 available | 2 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
OldReplicaSets: nginx-deployment-1564180365 (2/2 replicas created)
NewReplicaSet: nginx-deployment-3066724191 (2/2 replicas created)
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
1m 1m 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3
22s 22s 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1
22s 22s 1 {deployment-controller} Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2
22s 22s 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2
21s 21s 1 {deployment-controller} Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0
21s 21s 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3
13s 13s 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 1
13s 13s 1 {deployment-controller} Normal ScalingReplicaSet Scaled down replica set nginx-deployment-1564180365 to 2
13s 13s 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 2
为了修复这个问题,我们需要回退到稳定的
检查Deployment 升级的历史记录
首先,检查下
$ kubectl rollout history deployment/nginx-deployment
deployments "nginx-deployment":
REVISION CHANGE-CAUSE
1 kubectl create -f https://kubernetes.io/docs/user-guide/nginx-deployment.yaml--record
2 kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
3 kubectl set image deployment/nginx-deployment nginx=nginx:1.91
因为我们创建--record
参数可以记录命令,我们可以很方便的查看每次
查看单个
$ kubectl rollout history deployment/nginx-deployment --revision=2
deployments "nginx-deployment" revision 2
Labels: app=nginx
pod-template-hash=1159050644
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
QoS Tier:
cpu: BestEffort
memory: BestEffort
Environment Variables: <none>
No volumes.
回退到历史版本
现在,我们可以决定回退当前的
$ kubectl rollout undo deployment/nginx-deployment
deployment "nginx-deployment" rolled back
也可以使用--revision
参数指定某个历史版本:
$ kubectl rollout undo deployment/nginx-deployment --to-revision=2
deployment "nginx-deployment" rolled back
该DeploymentRollback
的
$ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 3 3 3 30m
$ kubectl describe deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Tue, 15 Mar 2016 14:48:04 -0700
Labels: app=nginx
Selector: app=nginx
Replicas: 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-1564180365 (3/3 replicas created)
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
30m 30m 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3
29m 29m 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1
29m 29m 1 {deployment-controller} Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2
29m 29m 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2
29m 29m 1 {deployment-controller} Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0
29m 29m 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 2
29m 29m 1 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 1
29m 29m 1 {deployment-controller} Normal ScalingReplicaSet Scaled down replica set nginx-deployment-1564180365 to 2
2m 2m 1 {deployment-controller} Normal ScalingReplicaSet Scaled down replica set nginx-deployment-3066724191 to 0
2m 2m 1 {deployment-controller} Normal DeploymentRollback Rolled back deployment "nginx-deployment" to revision 2
29m 2m 2 {deployment-controller} Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3
清理Policy
您可以通过设置 .spec.revisonHistoryLimit
项来指定
Deployment 扩容
您可以使用以下命令扩容
$ kubectl scale deployment nginx-deployment --replicas 10
deployment "nginx-deployment" scaled
假设您的集群中启用了 horizontal pod autoscaling,您可以给
$ kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
deployment "nginx-deployment" autoscaled
比例扩容
例如,您正在运行中含有
$ kubectl get deploy
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 10 10 10 10 50s
您更新了一个镜像,而在集群内部无法解析。
$ kubectl set image deploy/nginx-deployment nginx=nginx:sometag
deployment "nginx-deployment" image updated
镜像更新启动了一个包含
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-1989198191 5 5 0 9s
nginx-deployment-618515232 8 8 8 1m
然后发起了一个新的
在我们上面的例子中,
$ kubectl get deploy
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 15 18 7 8 7m
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-1989198191 7 7 0 7m
nginx-deployment-618515232 11 11 11 7m
删除autoscale
kubectl get hpa
kubectl delete hpa ${name of hpa}
暂停和恢复Deployment
您可以在发出一次或多次更新前暂停一个
例如使用刚刚创建
$ kubectl get deploy
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx 3 3 3 3 1m
[mkargaki@dhcp129-211 kubernetes]$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-2142116321 3 3 3 1m
使用以下命令暂停
$ kubectl rollout pause deployment/nginx-deployment
deployment "nginx-deployment" paused
然后更新
$ kubectl set image deploy/nginx nginx=nginx:1.9.1
deployment "nginx-deployment" image updated
注意新的
$ kubectl rollout history deploy/nginx
deployments "nginx"
REVISION CHANGE-CAUSE
1 <none>
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-2142116321 3 3 3 2m
您可以进行任意多次更新,例如更新使用的资源:
$ kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi
deployment "nginx" resource requirements updated
最后,恢复这个
$ kubectl rollout resume deploy nginx
deployment "nginx" resumed
$ KUBECTL get rs -w
NAME DESIRED CURRENT READY AGE
nginx-2142116321 2 2 2 2m
nginx-3926361531 2 2 0 6s
nginx-3926361531 2 2 1 18s
nginx-2142116321 1 2 2 2m
nginx-2142116321 1 2 2 2m
nginx-3926361531 3 2 1 18s
nginx-3926361531 3 2 1 18s
nginx-2142116321 1 1 1 2m
nginx-3926361531 3 3 1 18s
nginx-3926361531 3 3 2 19s
nginx-2142116321 0 1 1 2m
nginx-2142116321 0 1 1 2m
nginx-2142116321 0 0 0 2m
nginx-3926361531 3 3 3 20s
^C
$ KUBECTL get rs
NAME DESIRED CURRENT READY AGE
nginx-2142116321 0 0 0 2m
nginx-3926361531 3 3 3 28s
注意:在恢复
Deployment 状态
进行中的Deployment
Deployment 正在创建新的ReplicaSet 过程中。Deployment 正在扩容一个已有的ReplicaSet 。Deployment 正在缩容一个已有的ReplicaSet 。- 有新的可用的
pod 出现。
您可以使用 kubectl rollout status
命令监控
完成的Deployment
Deployment 最小可用。最小可用意味着Deployment 的可用replica 个数等于或者超过Deployment 策略中的期望个数。- 所有与该
Deployment 相关的replica 都被更新到了您指定版本,也就说更新完成。 - 该
Deployment 中没有旧的Pod 存在。
您可以用 kubectl rollout status
命令查看kubectl rollout status
将返回一个
$ kubectl rollout status deploy/nginx
Waiting for rollout to finish: 2 of 3 updated replicas are available...
deployment "nginx" successfully rolled out
$ echo $?
0
失败的Deployment
您的
- 无效的引用
- 不可读的
probe failure - 镜像拉取错误
- 权限不够
- 范围限制
- 程序运行时配置错误
探测这种情况的一种方式是,在您的spec.progressDeadlineSeconds
。spec.progressDeadlineSeconds
表示
下面的 kubectl
命令设置 progressDeadlineSeconds
使
$ kubectl patch deployment/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'
"nginx-deployment" patched
当超过截止时间后,status.conditions
中增加一条
- Type=Progressing
- Status=False
- Reason=ProgressDeadlineExceeded
注意:Reason=ProgressDeadlineExceeded
状态信息外不会对卡住的
注意:如果您暂停了一个
您可能在使用
$ kubectl describe deployment nginx-deployment
<...>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True ReplicaSetUpdated
ReplicaFailure True FailedCreate
<...>
执行kubectl get deployment nginx-deployment -o yaml
,
status:
availableReplicas: 2
conditions:
- lastTransitionTime: 2016-10-04T12:25:39Z
lastUpdateTime: 2016-10-04T12:25:39Z
message: Replica set "nginx-deployment-4262182780" is progressing.
reason: ReplicaSetUpdated
status: "True"
type: Progressing
- lastTransitionTime: 2016-10-04T12:25:42Z
lastUpdateTime: 2016-10-04T12:25:42Z
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: 2016-10-04T12:25:39Z
lastUpdateTime: 2016-10-04T12:25:39Z
message:
'Error creating: pods "nginx-deployment-4262182780-" is forbidden: exceeded quota:
object-counts, requested: pods=1, used: pods=3, limited: pods=2'
reason: FailedCreate
status: "True"
type: ReplicaFailure
observedGeneration: 3
replicas: 2
unavailableReplicas: 2
最终,一旦超过
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing False ProgressDeadlineExceeded
ReplicaFailure True FailedCreate
您可以通过缩容Status=True
并且Reason=NewReplicaSetAvailable
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
Type=Available
、 Status=True
意味着您的Type=Progressing
、 Status=True
意味着您的Reason=NewReplicaSetAvailable
意味着
您可以使用 kubectl rollout status
命令查看kubectl rollout status
将返回非
$ kubectl rollout status deploy/nginx
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
error: deployment "nginx" exceeded its progress deadline
$ echo $?
1
操作失败的Deployment
所有对完成的
清理Policy
您可以设置.spec.revisionHistoryLimit
项来指定保留多少旧的
注意:将该值设置为
用例
金丝雀Deployment
如果您想要使用
编写Deployment Spec
在所有的apiVersion
,kind
和 metadata
这些配置项。配置文件的通用使用说明查看 部署应用,配置容器,和使用
Pod Template
.spec.template
是 .spec
中唯一要求的字段。
.spec.template
是 pod templateapiVersion
和 kind
字段。
另外为了划分
.spec.template.spec.restartPolicy
可以设置为Always
Replicas
.spec.replicas
是可以选字段,指定期望的
Selector
.spec.selector
是可选字段,用来指定 label selector ,圈定
如果被指定, .spec.selector
必须匹配 .spec.template.metadata.labels
,否则它将被.spec.selector
没有被指定, .spec.selector.matchLabels
默认是 .spec.template.metadata.labels
。
在.spec.template
不同或者数量超过了 .spec.replicas
规定的数量的情况下,
注意:您不应该再创建其他
如果您有多个
策略
.spec.strategy
指定新的.spec.strategy.type
可以是 “Recreate” 或者是 “RollingUpdate”
Recreate Deployment
.spec.strategy.type==Recreate
时,在创建出新的
Rolling Update Deployment
.spec.strategy.type==RollingUpdate
时,maxUnavailable
和 maxSurge
来控制
Max Unavailable
.spec.strategy.rollingUpdate.maxUnavailable
是可选配置项,用来指定在升级过程中不可用.spec.strategy.rollingUpdate.maxSurge
为
例如,该值设置成
Max Surge
.spec.strategy.rollingUpdate.maxSurge
是可选配置项,用来指定可以超过期望的MaxUnavailable
为
例如,该值设置成
Progress Deadline Seconds
.spec.progressDeadlineSeconds
是可选配置项,用来指定在系统报告type=Progressing
、Status=False
、 Reason=ProgressDeadlineExceeded
前可以等待的
如果设置该参数,该值必须大于 .spec.minReadySeconds
。
Min Ready Seconds
.spec.minReadySeconds
是一个可选配置项,用来指定没有任何容器
Rollback To
.spec.rollbackTo
是一个可以选配置项,用来配置
Revision
.spec.rollbackTo.revision
是一个可选配置项,用来指定回退到的
Revision History Limit
.spec.revisionHistoryLimit
是一个可选配置项,用来指定可以保留的旧的kubectl get rs
查看输出。每个
如果您将该值设置为
Paused
.spec.paused
是可以可选配置项,