Kubernetes 定义Deployment控制器
编写 Deployment:
在所有的 Kubernetes 配置中,Deployment 也需要apiVersion,kind和metadata、 spec 这些配置项。
Pod Template:
deployment.spec.template 是 .spec中唯一必须的字段。
deployment.spec.template 是 pod template. 它跟 Pod有一模一样的结构有metadata、spec字段,除了它是嵌套的并且不需要apiVersion 和 kind字段。
另外为了划分Pod的范围,Deployment中的pod template必须指定适当的label(不要跟其他controller重复了,例如:在Deployments中定义了一个 labels是app = nginx,在Replica Set、Replication Controller 中都不来在定义app=nginx这个labels)和适当的重启策略。.spec.template.spec.restartPolicy 可以设置为 Always , 如果不指定的话这就是默认配置。
Replicas:
.spec.replicas 是可以选字段,指定期望的pod数量,默认是1。
Selector:
.spec.selector是可选字段,用来指定 label selector ,圈定Deployment管理的pod范围。
如果被指定, .spec.selector 必须匹配 .spec.template.metadata.labels,否则它将被API拒绝。如果 .spec.selector 没有被指定, .spec.selector.matchLabels 默认是 .spec.template.metadata.labels。
在Pod的template跟.spec.template不同或者数量超过了.spec.replicas规定的数量的情况下,Deployment会杀掉label跟selector不同的Pod。
注意: 您不应该再创建其他label跟这个selector匹配的pod,或者通过其他Deployment,或者通过其他Controller,例如ReplicaSet和ReplicationController。否则该Deployment会被把它们当成都是自己创建的。Kubernetes不会阻止您这么做。
如果您有多个controller使用了重复的selector,controller们就会互相打架并导致不正确的行为。
策略:
.spec.strategy 指定新的Pod替换旧的Pod的策略。 .spec.strategy.type 可以是”Recreate”或者是 “RollingUpdate”。”RollingUpdate”是默认值。
Recreate Deployment:
.spec.strategy.type==Recreate时,在创建出新的Pod之前会先杀掉所有已存在的Pod。
Rolling Update Deployment:
.spec.strategy.type==RollingUpdate时,Deployment使用rolling update 的方式更新Pod 。您可以指定maxUnavailable 和 maxSurge 来控制 rolling update 进程。
MAX UNAVAILABLE:
.spec.strategy.rollingUpdate.maxUnavailable 是可选配置项,用来指定在升级过程中不可用Pod的最大数量。该值可以是一个绝对值(例如5),也可以是期望Pod数量的百分比(例如10%)。通过计算百分比的绝对值向下取整。如果.spec.strategy.rollingUpdate.maxSurge 为0时,这个值不可以为0。默认值是1。
例如,该值设置成30%,启动rolling update后旧的ReplicatSet将会立即缩容到期望的Pod数量的70%。新的Pod ready后,随着新的ReplicaSet的扩容,旧的ReplicaSet会进一步缩容,确保在升级的所有时刻可以用的Pod数量至少是期望Pod数量的70%。
MAX SURGE:
.spec.strategy.rollingUpdate.maxSurge 是可选配置项,用来指定可以超过期望的Pod数量的最大个数。该值可以是一个绝对值(例如5)或者是期望的Pod数量的百分比(例如10%)。当MaxUnavailable为0时该值不可以为0。通过百分比计算的绝对值向上取整。默认值是1。
例如,该值设置成30%,启动rolling update后新的ReplicatSet将会立即扩容,新老Pod的总数不能超过期望的Pod数量的130%。旧的Pod被杀掉后,新的ReplicaSet将继续扩容,旧的ReplicaSet会进一步缩容,确保在升级的所有时刻所有的Pod数量和不会超过期望Pod数量的130%。
Revision History Limit:
Deployment revision history存储在它控制的ReplicaSets中。
.spec.revisionHistoryLimit 是一个可选配置项,用来指定可以保留的旧的ReplicaSet数量。该理想值取决于心Deployment的频率和稳定性。如果该值没有设置的话,默认所有旧的Replicaset或会被保留,将资源存储在etcd中,是用kubectl get rs查看输出。每个Deployment的该配置都保存在ReplicaSet中,然而,一旦您删除的旧的RepelicaSet,您的Deployment就无法再回退到那个revison了。
如果您将该值设置为0,所有具有0个replica的ReplicaSet都会被删除。在这种情况下,新的Deployment rollout无法撤销,因为revision history都被清理掉了。
Paused:
.spec.paused是可以可选配置项,boolean值。用来指定暂停和恢复Deployment。Paused和没有paused的Deployment之间的唯一区别就是,所有对paused deployment中的PodTemplateSpec的修改都不会触发新的rollout。Deployment被创建之后默认是非paused。
revision清理策略:
您可以通过设置.spec.revisonHistoryLimit项来指定 deployment 最多保留多少 revision 历史记录。默认的会保留所有的 revision;如果将该项设置为0,Deployment就不允许回退了。
实例:
1 |
|
查看定义的deployments资源:
注释:查看当前有哪些deployment
deployments管理的rs:
注释:一个deployment可以管理多个rs,但是处于运行状态的只有一个。例如:nginx-ye-5ddd85887。说明当前已经更新了三个版本了其中RS (nginx-ye-5b5d8d5794 、nginx-ye-5d6cc588fd)已经没用了,但是回滚的时候会用到。您可能会注意到 ReplicaSet 的名字总是<Deployment的名字>-<pod 模板的hash值>,只要模板不同后面的HASH值就不同,就表示不同的RS。
deployments资源详细信息:
Deployment为Pod和Replica Set(升级版的 Replication Controller)提供声明式更新。
你只需要在 Deployment 中描述您想要的目标状态是什么,Deployment controller 就会帮您将 Pod 和ReplicaSet 的实际状态改变到您的目标状态。您可以定义一个全新的 Deployment 来创建 ReplicaSet 或者删除已有的 Deployment 并创建一个新的来替换。
注意:您不该手动管理由 Deployment 创建的 Replica Set,否则您就篡越了 Deployment controller 的职责!下文罗列了 Deployment 对象中已经覆盖了所有的用例。如果未有覆盖您所有需要的用例,请直接在 Kubernetes 的代码库中提 issue。
典型的用例如下:
- 使用Deployment来创建ReplicaSet。ReplicaSet在后台创建pod。检查启动状态,看它是成功还是失败。
- 然后,通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态。这会创建一个新的ReplicaSet,Deployment会按照控制的速率将pod从旧的ReplicaSet移动到新的ReplicaSet中。
- 如果当前状态不稳定,回滚到之前的Deployment revision。每次回滚都会更新Deployment的revision。
- 扩容Deployment以满足更高的负载。
- 暂停Deployment来应用PodTemplateSpec的多个修复,然后恢复上线。
- 根据Deployment 的状态判断上线是否hang住了。
- 清除旧的不必要的 ReplicaSet。
Deployments滚动升级过程:
Deployment直接使用kubectl edit deployment/deploymentName 或者kubectl set方法就可以直接升级(原理是Pod的template发生变化,例如更新label、更新镜像版本等操作会触发Deployment的滚动升级):
将nginx的版本进行升级,从1.7.9升级到1.8。第一种方法,直接set镜像:
1 |
|
第二种方法,直接edit:
1 |
|
deployments可以同时控制多个RS控制器。在滚动升级的时候先创建一个RS,然后deploymen在删除V1版本的Pod后在创建一个另个RS里创建一个V2版本。但是只有一个是处于活动状态的。Deployment可以控制更新粒度,例如5个Pod的时候,可以设置最大允许6个Pod,最少允许4个。那么在滚动更新的时候会先更新一个新版本然后在删掉一个老版本,直到更新完成。如果你允许最大是7个Pod那么就是两个Pod一起更新。 如果设置只允许少不允许多,最少允许4个。那么就先删除一个然后在更新一个, 直到更新完成。
最后介绍下Deployment的一些基础命令。
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
Deploymentsce层级关系:
在上述输出中,可以看到自动添加到注解中的“deployment.kubernetes.io/revision=2”字段,新建Deployment的revision是1,2表示这是更新过的第二版,前缀“deployment.kubernetes.io”表示这是系统保留的供deployment使用的关键字,用户不可以使用引种类型的注解。(注释:revision在回滚到某一个指定版本的时候需要用到)
关于更新失败:
如果在新版本中指定了错误的image名称,那么更新注定会失败。在本例中如果发生这种情况,首先Deployment会创建新的ReplicaSet,新ReplicaSet在创建每个pod实例就会因为取不到image而失败,整个更新过程会被卡住不再进行下去。即使失败也会产生一个新的修订版本号,并且新创建的ReplicaSet、因无法取到image而失败的pod仍存在于系统中。当然目前对外提供服务的仍然是旧版本的pod。如果发生这种情况就要乃至回滚功能,回到上一个正确的版本。
Rolling Back a Deployment:
Deployment会记录修订历史,当然对能记录的修订历史个数有限制(可以通过.spec.revisionHistoryLimit参数设置),因此Deployment能回滚到记录在案的以前的历史版本中。注意只有rollout操作才会触发修订历史记录,也就是只有.spec.template发生变更才被认为产生了新的版本。其它的变更,比如修改标签选择器、通过kubectl scalling命令扩缩容、被HPA自动扩缩容等不会被认为是新的版本。只回滚.spec.template部分,比如当前的副本数量是5,回滚的版本副本数量是3,回滚后副本数量不变仍然是5,但副本的内容变回以前。
查看修定历史记录,注意后边的CHANGE-CAUSE,需要在kubectl creae创建Deployment时指定–record=true才会有:(–record=false在资源注释中记录当前的kubectl命令。如果设置为false,则不要记录)
1 |
|
通过指定REVISION号码查看特定修订记录:
1 |
|
回滚到前一个版本:
1 |
|
通过revision号回滚到任意版本:
1 |
|
升级或创建(如果该资源还不存在,将创建它)
1 |
|