Get into the habit of writing together! This is the 10th day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .
I. Introduction
Deploy, upgrade, and rollback Deployment
using .Pod
Deployment
Provides a declarative definition method for and , which can be used in place of the previously used toPod
manage applications.ReplicaSet
ReplicationController(RC)
Deployment
Resource Pod
objects provide declarative definitions for and ReplicaSet
( upgrades of), describing the desired target state in the file.ReplicationController
Deployment YAML
Deployment Controller
will create a sum that matches the target state,ReplicaSet
andPod
if updatedDeployment
, the correspondingReplicaSet
andPod
will also change the state to match the new target state.
(1) Typical application scenarios
- define
Deployment
to createReplicaSet
andPod
Use
Deployment
to createReplicaSet
, whichReplicaSet
will be created in the backgroundPod
. You can checkPod
the startup status of , to see if it succeeded or failed. You canDeployment
also judge whether the online ishang
live or not according to the status of .
- Rolling upgrades and rollbacks of applications
通过更新
Deployment
的PodTemplateSpec
字段来声明Pod
的新状态,更新Deployment
后会创建一个新的ReplicaSet
,Deployment
会按照控制的速率删除由旧的ReplicaSet
创建的Pod
、并使用新的ReplicaSet
创建新的Pod
,当新生成的Pod
达到要求的目标状态后,会清除旧的ReplicaSet
。如果当前状态不稳定,可以回滚到之前的
Deployment revision
,每次回滚都会更新Deployment
的revision
。
- 扩容和缩容
根据系统负载进行
Deployment
的扩容和缩容。
- 暂停和继续
Deployment
暂停
Deployment
并修改PodTemplateSpec
字段,然后重新恢复上线。
(2)举个例子
- 定应
Deployment
文件nginx-deployment.yaml
它可以创建一个
Replica Set
来启动 3个nginx pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
复制代码
- 执行创建
$ kubectl create -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
复制代码
- 查看
Deployment
的状态、RS的状态,以及运行的Pod
副本数量
# 可以看到已经创建了 3 个符合要求的 Pod,这 3 个 Pod 都是最新的、都处于可用状态
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 39s
# 该 RS 需要 3 个 Pod,当前符合要求的有 3 个 Pod 并且已经创建好,RS 名字的组成:<Deployment 的名字>-<Pod template 的 hash 值>
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-5754944d6c 3 3 3 6m18s
# 使用 nginx-deployment-5754944d6c RS 创建的 3 个 Pod
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-5754944d6c-gv8x8 1/1 Running 0 6m36s
nginx-deployment-5754944d6c-hsp99 1/1 Running 0 6m36s
nginx-deployment-5754944d6c-qqh42 1/1 Running 0 6m36s
复制代码
- 查看
nginx-deployment
的详细信息
$ kubectl describe deployment nginx-deployment
# 在 Annotations 记录了版本 revision: 1
# 默认更新策略使用的是 RollingUpdate
# max unavailable 和 max surge 的默认值都为 25%
# ReplicaSet 为 nginx-deployment-5754944d6c
复制代码
二、Deployment
升级
Kubernetes
提供滚动升级,就不用暂停与该服务相关的所有pod
通常使用
Deployment
来创建Pod
资源对象,当Pod
在运行中,可以修改Deployment
的Pod
定义或是镜像名称,并应用到Deployment 对象上,这样就完成了 Deployment
的自动更新操作。
(1)举个栗子
- 将
pod
的镜像更新为nginx:1.9.1
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
deployment.extensions/nginx-deployment image updated
# 也可以使用 kubectl edit 命令进行更新,把 image 字段下的 nginx:1.7.9 更改为 nginx:1.9.1
$ kubectl edit deployment/nginx-deployment
deployment.extensions/nginx-deployment edited
复制代码
- 修改了镜像名,就会触发系统完成
Deployment
所有运行pod
的滚动升级操作,查看rollout
状态
Tips: 当且仅当
Deployment
的.spec.template
字段下的labels
或是image
更新时才会触发rollout
,其它的更新并不会触发rollout
。
$ kubectl rollout status deployment/nginx-deployment
deployment "nginx-deployment" successfully rolled out
复制代码
- 查看更新后的
Deployment
、RS
、Pod
:
# 可以看到 UP-TO-DATE 的数量已经变成了 3,说明已经全部更新完成
$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 143m
# 查看两个 RS 的最终状态,可以看到旧的 RS 已经没有 Pod 在运行了,新的 RS 创建好了 3 个新的 Pod
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-5754944d6c 0 0 0 143m
nginx-deployment-7448597cd5 3 3 3 6m11s
# 由新 nginx-deployment-7448597cd5 RS 创建出来的 3 个 Pod
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-7448597cd5-7c9ms 1/1 Running 0 6m19s
nginx-deployment-7448597cd5-h6k89 1/1 Running 0 5m58s
nginx-deployment-7448597cd5-m8dnk 1/1 Running 0 5m25s
复制代码
- 查看
nginx-deployment
详细信息
$ kubectl describe deployments/nginx-deployment
# ReplicaSet 更新为 nginx-deployment-7448597cd5
复制代码
(2)分析更新过程
Event
事件,可以看到Pod
的更新过程:
- 系统创建了一个新的
RS(nginx-deployment-7448597cd5)
,将其副本数量扩展到 1;将旧的RS(nginx-deployment-5754944d6c)
副本数量缩减为 2 - 新的
RS
副本数量扩展到了 2,旧的RS
副本数量缩减为 1 - 新的
RS
副本数量扩展到了 3,旧的RS
副本数量缩减为 0
(3)更新策略
Deployment
通过字段 spec.strategy
设置 Pod
更新策略。
上面创建的 Deployment
的相关默认设置如下:
spec:
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
复制代码
Deployment
的更新策略有两种:
Recreat
(重建): 先kill
掉所有正在运行的Pod
,然后创建新的Pod
。RollingUpdate
(滚动更新): 逐个更新Pod
。可以在字段spec.strategy.rollingUpdate
下设置两个参数maxSurge
和maxUnavailable
来控制滚动更新的过程。
关于两个参数的详细说明:
maxUnavailable
:
指定更新过程中不可用状态的 Pod
数量上限。默认值 25% 指的是:Pod
期望副本数的 25%,然后系统会以向下取整的方式计算出绝对值(整数)。对于这里而言,当开始滚动更新时,旧的 RS
立即将副本数缩小到所需副本总数的 75%(3 * 75% = 2.25,然后向下取整,绝对值为 2),一旦新的 Pod
创建并准备好,旧的 RS
会进一步缩容,新的 RS 会进一步扩容,整个过程中系统在任意时刻都可以确保可用状态的 Pod
总数至少占 Pod
期望副本总数的 75%。
maxSurge
:指定更新过程中Pod
总数超过Pod
期望副本数部分的最大值。默认值 25% 指的是:Pod
期望副本数的 25%,然后系统会以向上取整的方式计算出绝对值(整数)。对于这里而言,新的RS
可以在滚动更新开始时立即进行副本数扩容,只要保证新旧RS
的Pod
副本总数之和不超过期望副本数的 125% 即可。一旦旧的 Pod 被 kill 掉,新的RS
会进一步扩容。在整个过程中系统在任意时刻都能确保新旧RS
的Pod
副本总数之和不超过所需副本数的 125%。
(4)多重更新(Rollover)
“多重更新”也就是多个滚动更新(Rollout
)同时进行。
每当 Deployment Controller
检测到有新的 Deployment
创建时,如果没有已存在的 ReplicaSet
来创建期望个数的Pod
,Deployment Controller
就会创建一个新的 ReplicaSet
来执行改变,已存在的 ReplicaSet
控制 ``label匹配字段
spec.selector但是
template不匹配字段
spec.template的
Pod进行缩容,然后新的
ReplicaSet将会扩容出匹配字段
spec.replicas指定数目的
Pod,旧的
ReplicaSet` 将会缩容到 0。
举个例子:比如创建了一个有 5 个 nginx:1.7.9 replica
的 Deployment
,当刚刚创建到 3 个 nginx:1.7.9 replica
时,开始更新 Deployment
将其镜像修改为 nginx:1.9.1
。在这种情况下,Deployment
会立即 kill
掉已创建的 3 个 nginx:1.7.9
的 Pod
,并开始创建 nginx:1.9.1
的 Pod
,它不会等到所有 5 个 nginx:1.7.9
的 Pod
都创建完成后才开始执行滚动更新。
更新 Deployment
的标签选择器(Label Selector
)
通常情况下不建议更新
Deployment
的标签选择器,因为这样会导致Deployment
选择的Pod
列表发生变化,可能与其他控制器发生冲突。
步骤如下:
- 添加标签选择器
在添加标签选择器时,注意要同步修改
Deployment
配置的Pod
标签,为Pod
添加新的标签。
The difference here is that adding a tag selector is not backward compatible, the new tag selector will not match and use the ReplicaSets
and Pod
, so adding a new selector will cause all of the old ReplicaSets
and created by the old ReplicaSets
to Pod
be in Orphaned state, ie: not automatically deleted by the system and not under new ReplicaSet
control .
To add labels to both fields spec.selector.matchLabels
and fields , modify them with the following command:spec.template.matedata.labels
k8s: nginx-pod
$ kubectl edit deployment/nginx-deployment
deployment.extensions/nginx-deployment edited
复制代码
View the updated Deployment
, RS
, Pods
:
# 可以看到更新完成
$ kubectl get deployment/nginx-deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 3h58m
# 创建了新的 RS:
$ kubectl get rs nginx-deployment-8ff4cd577
NAME DESIRED CURRENT READY AGE
nginx-deployment-5754944d6c 0 0 0 3h58m
nginx-deployment-7448597cd5 3 3 3 101m
nginx-deployment-8ff4cd577 3 3 3 88s
# 使用新的 RS nginx-deployment-8ff4cd577 创建了 3 个 Pod,可以发现之前的 3 个 Pod 依然存在着,没有被删除
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-7448597cd5-7c9ms 1/1 Running 0 101m
nginx-deployment-7448597cd5-h6k89 1/1 Running 0 100m
nginx-deployment-7448597cd5-m8dnk 1/1 Running 0 100m
nginx-deployment-8ff4cd577-8gxw2 1/1 Running 0 95s
nginx-deployment-8ff4cd577-8plkw 1/1 Running 0 95s
nginx-deployment-8ff4cd577-g7bc2 1/1 Running 0 95s
复制代码
- Update tag selector
For example, updating the key or value of a tag in a selector has a similar effect as adding a new selector tag.
- remove tag selector
Deleting one or more tags from
Deployment
the tag selector of , the andDeployment
of the will not be affected, except that the deleted tags will still exist on the existing and .ReplicaSet
Pod
ReplicaSet
Pod