0%

k8s教程04-Deployment

Deployment是⼀种更⾼阶资源,⽤于部署应⽤程序并以声明的⽅式升级应⽤,⽽不是通过ReplicationController或ReplicaSet进⾏部署,它们都被认为是更底层的概念。

1. Deployment

1.1介绍

当创建⼀个Deployment时,ReplicaSet资源也会随之创建 。 在 使 ⽤ Deployment 时 ,实 际 的 pod 是 由 Deployment 的Replicaset创建和管理的,⽽不是由Deployment直接创建和管理的。

image-20240121162110548

Deployment也是由标签选择器、期望副数和pod模板组成的。此外,它还 包 含 另 ⼀ 个 字 段 , 指 定 ⼀ 个 部 署 策 略 , 该策 略 定 义 在 修 改 Deployment资源时应该如何执⾏更新。

image-20240121162255006

1.2 创建

1
kubectl create -f kubia-deployment-vl.yaml --record

image-20240121163116643

注意这些pod的命名,之前当使⽤ReplicationController创建pod时,它们的名称是由Controller的名称加上⼀个运⾏时⽣成的随机字符串(例如kubia-v1-m33mv)组成的。现在由Deployment创建的三个pod名称中均包含⼀个额外的数字。那是什么呢?

这个数字实际上对应Deployment和ReplicaSet中的pod模板的哈希值 。 如 前 所 述 , Deployment 不 能 直 接 管 理 pod 。 相反 , 它 创 建 了ReplicaSet来管理pod。

Deployment会创建多个ReplicaSet,⽤来对应和管理⼀个版本的 pod模板。像这样使⽤pod模板的哈希值,可以让Deployment始终对给定版本的pod模板创建相同的(或使⽤已有的)ReplicaSet。

1.3 滚动升级

Deployment的升级策略决定的,默认策略是执⾏滚动更新(策略名为RollingUpdate)。另⼀种策略为Recreate,它会⼀次性删除所有旧版本的pod,然后创建新的pod,整个⾏为类似于修改ReplicationController的pod模板,然后删除所有的pod。Recreate 策略会导致应⽤程序出现短暂的不可⽤。

要触发滚动升级,需要将pod镜像修改为luksa/kubia:v2。使 ⽤ kubectl set image 命 令 来 更 改 任 何 包 含 容 器 资 源 的 镜 像(ReplicationController、ReplicaSet、Deployment等)。

1
2
$ kubectl set image deployment kubia nodejs=luksa/kubia:v2 
deployment "kubia"image updated
image-20240121191610073
1
2
3
4
5
$ kubectl rollout status deployment kubia

Waiting for rollout to finish:1 out of 3 new replicas have been updated...
Waiting for rollout to finish:2 out of 3 new replicas have been updated...
Waiting for rollout to finish:1 old replicas are pending termination... deployment "kubia"successfully rolled out

image-20240121191856140

1.4 回滚

Deployment会被回滚到上⼀个版本。

1
2
$ kubectl rollout undo deployment kubia 
deployment "kubia"rolled back

回滚升级之所以可以这么快地完成,是因为Deployment始终保持着升级的版本历史记录。之后也会看到,历史版本号会被保存在ReplicaSet中。滚动升级成功后,⽼版本的ReplicaSet也不会被删掉,这也使得回滚操作可以回滚到任何⼀个历史版本,⽽不仅仅是上⼀个版本。可以使⽤ kubectl rollout history 来显⽰升级的版本:

1
2
3
4
5
6
$ kubectl rollout history deployment kubia 

deployments "kubia":
REVISION CHANGE-CAUSE
2 kubect1 set image deployment kubia nodejs=luksa/kubia:v2
3 kubectl set image deployment kubia nodejs=luksa/kubia:v3

还记得创建Deployment时的–record 参数吗?如果不给定这个参数,版本历史中的 CHANGE-CAUSE 这⼀栏会为空。这也会使⽤户很难辨别每次的版本做了哪些修改。

通过在 undo 命令中指定⼀个特定的版本号,便可以回滚到那个特定的版本。

1
kubectl rollout undo deployment kubia --to-revision=1

旧版本的ReplicaSet过多会导致ReplicaSet列表过于混乱,可以通过指定Deployment的 revisionHistoryLimit 属性来限制历史版本数量。默认值是 2,所以正常情况下在版本列表⾥只有当前版本和上⼀个版本(以及只保留了当前和上⼀个ReplicaSet),所有再早之前的ReplicaSet都会被删除。

1.5 就绪探针 + minReadySeconds

image-20240121193045890

当新的pod启动时,就绪探针会每隔⼀秒发起请求(在pod spec中,就绪探针的间隔被设置为1秒)。在就绪探针发起第五个请求的时候会出现失败,因为应⽤从第五个请求开始⼀直返回HTTP状态码 500。因此,pod会从Service的endpoint中移除。当执⾏ curl 循环请求服务时,pod已经被标记为未就绪。

image-20240121193434973

因为新的pod⼀直处于不可⽤状态。即使变为就绪状态之后,也⾄少需要保持10秒,才是真正可⽤的。在这之前滚动升级过程将不再创建任何新的pod,因为当前maxUnavailable属性设置为0,所以也不会删除任何原始的pod。

如果只定义就绪探针没有正确设置 minReadySeconds,⼀旦有⼀次就绪探针调⽤成功,便会认为新的pod已经处于可⽤状态。因此最好适当地设置minReadySeconds 的值。

给作者打赏,可以加首页微信,咨询作者相关问题!