K8S Deployments 使用 & 更新 & 回滚 & 扩容
K8S Deployments 提供比 Replication Controller 、ReplicaSet 更高一级的抽象,也具备更丰富的功能。Deployment对象不仅创建pod,还确保集群中始终运行正确数量的pod,处理可伸缩性,并持续处理pod的更新。所有这些活动都可以通过部署YAML中的字段进行配置。下面接下来就开始K8S Deployment的学习之旅吧。
Deployment 应用场景
以下是K8S Deployment典型的应用场景
- 创建Deployment展示ReplicaSet - ReplicaSet在后台自动创建Pod,所以Deployment也会自动创建Pod,并检查Pod是否创建成功
- 使用Deployment配置文件申明Pods状态 - Deployment管理Pods并将其迁移到新的ReplicaSet, 每个新的ReplicaSet都会更新Deployment版本信息
- 更新Deployment - 如新版本Deployment状态不稳定,支持回滚到之前的版本,每次回滚都会更新Deployment版本信息
- Deployment支持扩容,以支持更多的负载
- 暂停/恢复更新Deployment - 当更新需要修改多处配置信息时,暂停更新,等待修改完毕,再恢复更新Deployment
Deployment Example
演示环境
- OS 信息
- minikube 版本信息
- Kubectl 版本
- Dokcer 版本
- 启动minikube
minikube start --driver=docker
配置文件
# vim nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
配置说明:
- 根据**.metadata.name**字段配置值 ,创建名为 nginx-deployment的Deployment对象,该名称将作为ReplicaSet、Pod的前缀自动闯将这两种类型的对象
- Deployment根据**.spec.replicas**自动创建ReplicaSet对象,并创建3个副本Pod
- .spec.selector字段定义ReplicaSet如何匹配Pod,需要跟template.labels.app一致
- template模板字段包含以下信息
- 使用 .metadata.labels.app - 字段标记Pod
- spec字段指示Pod运行的容器(名称为nginx) ,以及容器镜像
- port容器端口
创建Deployment
kubectl apply -f nginx-deployment.yaml
运行状态
- 查看Deployment运行状态
# 创建成功后 使用以下命令查看deployment运行状态
kubectl get deployments | grep nginx-deployment
如图片所示,自动创建了名为nginx-deployment 的 Deployments集群,副本数为3,上述中每个字段的含义如下
- NAME - 列出默认命名空间集群中Deployment的名称
- READY - 显示应用程序副本的数量
- UP-TO-DATE - 显示已经达到期望状态的副本数量
- AVAILABLE - 显示集群中应用程序可用的副本数量,正常情况下应该跟期望值一致,Pod在创建过程中可能会少于期望值
- AGE - 显示应用程序运行时长
- 使用rollout命令 查看Deployment创建状态
kubectl rollout status deployment/nginx-deployment
- 查看Deployment自动创建的ReplicSet 信息
kubectl get rs | grep nginx
注意:ReplicSet对象的名称前缀跟Deployment定义中的一致
- 查看Deployment底层的Pod信息
kubectl get pods --show-labels | grep nginx-deployment
请注意,Pod后面携带的Hash值 - 7fb96c846b跟Deployment对应ReplicaSet对象的Hash值一致,他们之间由此产生关联。
更新 Deployment
仅当Deployment配置文件中的Pod模板(.spec.template)更改时,才会触发Deployment更新操作。例如Pod模板中的镜像文件更改,触发Deployment更新。
更新镜像版本
- 将之前nginx的镜像版本从 nginx:1.14.2 升级到 nginx:1.16.1
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1
此外还可以使用以下命令升级Deployment
kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
另外还可以使用以下命令,直接修改Deployment
找到镜像版本信息的位置,修改为更高级的版本进行更新Deployment,修改完毕之后,shell控制台输出如下
deployment.apps/nginx-deployment edited
更新过程
kubectl describe deploy nginx-deployment
使用以上命令,查看Deployment对象的详细创建过程
仔细查看Events信息,可以分析出Deployment 创建过程
- 第一次直接创建了3个副本的ReplicaSet
- 更新Deployment时,启动一个新的ReplicaSet
- 将旧ReplicaSet的三个副本减掉一个 对应 to 2 from 3
- 更新操作启动第二个ReplicaSet副本,此时新版本ReplicaSet变成2 to 2 from 1
- 将旧ReplicaSet的存活的2个副本减掉一个 对应 to 1 from 2
- 更新操作启动第三个ReplicaSet副本,此时新版本ReplicaSet变成2 to 3 from 2
- 将旧ReplicaSet的存活的1个副本减掉一个 对应 to 0 from 1
由此可知,更新Deployment对象会启动新的ReplicaSet,等待启动完成后,会自动停用旧版本的ReplicaSet。在升级过程中采用先启动后停用的方式,能够始终保持ReplicaSet期望的副本数。
更新策略
默认情况下,K8S会保留10个旧ReplicaSet版本,以方便回滚。超过10个以上的ReplicaSet将会被系统回收。可以使用spec.revisionHistoryLimit设置保留ReplicaSet的个数,设置为0时,不保留历史记录。
.spec.strategy.type参数设置会影响Deployment的更新机制
- Recreate - 先删除旧的Pod,再创建新的Pod
- RollingUpdate - 滚动更新,默认值,可以通过指定 maxUnavailable 、maxSurge来控制更新过程
- .spec.strategy.rollingUpdate.maxUnavailable 指定回滚更新时,最大不可用的Pod数量,默认25%,简单理解为一部分更新
- .spec.strategy.rollingUpdate.maxSurge 可以超过期望值的最大Pod数,可选字段,默认为25%
.spec.minReadySeconds 可选参数,指定新建的Pod在没有任何容器崩溃情况下视为就绪- Ready状态的最小时间,单位为秒,默认为0,即一旦创建Pod,则被视为可用
回滚Deployment
当部署不稳定、新版本发布失败时,用户可能需要回滚Deployment,继续使用旧版本Deployment提供服务。默认情况下所有回滚信息都会保存在系统中,目的是方便随时回滚.
当且仅当Deployment关联的Pod对象 (.spec.template) 发生变化时,Deployment才会创建新的版本信息。其他操作,如扩容伸缩操作并不会更新版本信息。因此也就意味着,回滚操作只需要回滚Deployment对象关联的Pod即可。
更新失败
- 假设您需要将nginx的版本从nginx:1.16.1回滚到nginx:1.161,可以使用如下命令进行回滚
kubectl set image deployment/nginx-deployment nginx=nginx:1.161
- 验证更新状态
kubectl rollout status deployment/nginx-deployment
如图片所示,此次更新失败。
- 检查ReplicaSet更新状态
kubectl get rs
新版本的ReplicaSet对象创建失败。
- 检查Pod状态
kubectl get pods
如图片所示,Pod启动失败的原因是镜像拉取失败(由于不存在对应版本镜像)。
系统回滚
- 首先检查回滚版本信息
kubectl rollout history deployment/nginx-deployment
我们更新了三次,最后一个是失败的。
- 查看回滚版本详细信息
kubectl rollout history deployment/nginx-deployment --revision=2
- 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment
- 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=1
- 检查Deployment信息
kubectl describe deployment nginx-deployment
如上图所示,Deployment中的镜像版本变成了最初的1.14.2,至此回滚成功。
扩容Deployment
手动扩容
当公司业务流程变大,需要更多的节点来处理新增的流量,此时需要将系统进行扩容。K8S Deployment扩容的方式非常简单,只需要使用以下命令即可进行扩容
kubectl scale deployment/nginx-deployment --replicas=10
扩容成功后,检查下Deployment的副本数量
kubectl get deploy
自动扩容
Deployment 还支持根据服务器运行情况进行扩容
# 当cpu超过80%的时候,进行扩容,副本数量最低10个,最高不超过15个
kubectl autoscale deployment/nginx-deployment --min=10 --max=15 --cpu-percent=80