Deployment概述
Deployment 是 kubernetes 中最常用的资源对象,为 ReplicaSet 和 Pod 的创建提供了一种声明式的定义方法,在 Deployment 对象中描述一个期望的状态,Deployment 控制器就会按照一定的控制速率把实际状态改成期望状态,通过定义一个 Deployment 控制器会创建一个新的 ReplicaSet 控制器,通过ReplicaSet 创建 pod,删除 Deployment 控制器,也会删除 Deployment 控制器下对应的 ReplicaSet 控制器和 pod 资源。使用 Deployment 而不直接创建 ReplicaSet 是因为 Deployment 对象拥有许多 ReplicaSet 没有的特性,例如滚动升级和回滚。
通过 Deployment 对象,你可以轻松的做到以下事情:
-
创建 ReplicaSet 和 Pod
-
滚动升级(不停止旧服务的状态下升级)和回滚应用(将应用回滚到之前的版本)
-
暂停和继续 Deployment
-
平滑地扩容和缩容
Deployment创建
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
namespace: default
labels:
app: nginx-deploy
spec:
replicas: 2
template:
metadata:
name: nginx-pod
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.21.5
imagePullPolicy: IfNotPresent
selector:
matchLabels:
app: nginx-pod
执行下面的命令,创建Deployment
kubectl apply -f nginx-deploy.yaml
#查看Deployment
kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deploy 2/2 2 2 7s
#查看ReplicaSet
kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deploy-746f69785b 2 2 2 11s
#查看pod状态
kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deploy-746f69785b-gt5jk 1/1 Running 0 3m16s 10.81.85.242 k8s-node01 <none> <none>
nginx-deploy-746f69785b-zdgpn 1/1 Running 0 3m16s 10.81.58.230 k8s-node02 <none> <none>
通过观察创建好的Deployment、ReplicaSet、Pod,ReplicaSet的名称是由Deployment名称+hash值,Pod的名称是由ReplicaSet名称+hash值。
Deployment管理
扩容、缩容
Deployment控制器对于进行扩容或缩容有多种方式,下面我们分别用不用的方式来进行操作;
修改yaml方式
修改资源文件中的spec.replicas
的值,例如我当前修改为4并保存,重新执行命令kubectl apply -f nginx-deploy.yaml
,然后查看pod状态
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deploy-746f69785b-ds9k2 1/1 Running 0 4s 10.81.58.231 k8s-node02 <none> <none>
nginx-deploy-746f69785b-gt5jk 1/1 Running 0 71m 10.81.85.242 k8s-node01 <none> <none>
nginx-deploy-746f69785b-lk7h7 1/1 Running 0 4s 10.81.85.243 k8s-node01 <none> <none>
nginx-deploy-746f69785b-zdgpn 1/1 Running 0 71m 10.81.58.230 k8s-node02 <none> <none>
kubectl edit方式
kubectl edit deploy nginx-deploy
**这种方式跟修改资源文件方式一样,也是修改spec.replicas
的值保存退出,只不过不用重新执行kubectl apply
命令,它会自动更新。**这次将副本数修改为1个,然后查看pod状态。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deploy-746f69785b-gt5jk 1/1 Running 0 82m 10.81.85.242 k8s-node01 <none> <none>
kubectl scale方式
kubectl scale deploy nginx-deploy --replicas=3
这种方式效率最高,直接一条命令搞定,这里我们把副本数又修改成了3个,我们再次查看pod状态。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deploy-746f69785b-gt5jk 1/1 Running 0 85m 10.81.85.242 k8s-node01 <none> <none>
nginx-deploy-746f69785b-tp6ng 1/1 Running 0 6s 10.81.58.232 k8s-node02 <none> <none>
nginx-deploy-746f69785b-vt7lf 1/1 Running 0 6s 10.81.58.233 k8s-node02 <none> <none>
滚动更新
Deployment 控制器是建立在 ReplicaSet 之上的一个控制器,可以管理多个 ReplicaSet,每次更新镜像版本,都会生成一个新的 ReplicaSet,把旧的 ReplicaSet 替换掉,多个 ReplicaSet 同时存在,但是只有一个 ReplicaSet 运行。 ReplicaSet v1控制三个 pod,当升级v2版本时,在 eplicaSet v2上重新建立一个pod,然后删除一个ReplicaSet v1上的pod,依次类推,直到全部pod都是由 ReplicaSet v2控制,如果ReplicaSet v2有问题,还可以回滚,Deployment 是建构在 ReplicaSet 之上的,多个 ReplicaSet 组成一个Deployment,但是只有一个 ReplicaSet 处于活跃状态。
#修改Deployment控制器
kubectl edit deploy nginx-deploy
通过上面的命令修改Deployment控制器的内容,例如我们修改一下nginx镜像的版本,从1.21.5
修改为1.19.2-alpine
,修改完成后保存退出,然后观察ReplicaSet和pod的状态;
#实时查看pod状态
kubectl get pod -w
NAME READY STATUS RESTARTS AGE
nginx-deploy-54c7949846-d9sdw 0/1 ContainerCreating 0 26s
nginx-deploy-746f69785b-gt5jk 1/1 Running 0 112m
nginx-deploy-746f69785b-tp6ng 1/1 Running 0 27m
nginx-deploy-746f69785b-vt7lf 1/1 Running 0 27m
nginx-deploy-54c7949846-d9sdw 1/1 Running 0 38s
nginx-deploy-54c7949846-4xjv6 0/1 Pending 0 0s
nginx-deploy-54c7949846-4xjv6 0/1 Pending 0 0s
nginx-deploy-746f69785b-vt7lf 1/1 Terminating 0 27m
nginx-deploy-54c7949846-4xjv6 0/1 ContainerCreating 0 0s
nginx-deploy-54c7949846-4xjv6 0/1 ContainerCreating 0 2s
nginx-deploy-746f69785b-vt7lf 0/1 Terminating 0 27m
nginx-deploy-746f69785b-vt7lf 0/1 Terminating 0 27m
nginx-deploy-746f69785b-vt7lf 0/1 Terminating 0 27m
Pending表示正在进行调度,ContainerCreating表示正在创建一个pod,Running表示运行一个pod,Running起来一个pod之后再Terminating一个pod,以此类推,直到所有pod完成滚动升级。从上面我们可以发现当更新镜像以后会发生如下变化:
- 创建一个新的ReplicaSet控制器
nginx-deploy-54c7949846
; - 创建并启动新的pod,名称以
nginx-deploy-54c7949846
为前缀; - 新的pod启动成功一个后便会停止一个旧的pod(
nginx-deploy-746f69785b-*
); - 重复第三步的动作,直到所有旧的pod全部停止完毕,从而实现滚动更新。
版本回滚
滚动升级完成后,我们查看ReplicaSet的状态如下,上面那个是新的,下面那个是旧的,已经被停掉,但是可以随时进行回滚。
#查看ReplicaSet
kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deploy-54c7949846 3 3 3 101s
nginx-deploy-746f69785b 0 0 0 113m
#查看更新历史记录
kubectl rollout history deploy nginx-deploy
REVISION CHANGE-CAUSE
1 <none>
2 <none>
从上面的信息可以看出有两个版本,REVISION=1的是更新前的版本1.21.5,REVISION=2是更新后的版本1.19.2-alpine,下面我们把版本回滚到更新前的版本。
#根据版本号查看版本的内容
kubectl rollout history deployment nginx-deploy --revision=1
kubectl rollout history deployment nginx-deploy --revision=2
#根据版本号回滚到指定版本
kubectl rollout undo deployment nginx-deploy --to-revision=1
等回滚完成后,再次查看ReplicaSet状态,当前生效的又变回了nginx-deploy-746f69785b
,说明回滚成功
NAME DESIRED CURRENT READY AGE
nginx-deploy-746f69785b 3 3 3 10m
nginx-deploy-54c7949846 0 0 0 10m