3.2 控制器之Deployment
文章目录1、Deployment的创建2、deployment管理应用升级3、deployment管理应用回滚4、滚动失败,deployment自动回滚Deployment是一种高阶控制器资源,在部署时,Deployment创建并管理ReplicaSet,由ReplicaSet创建管理pod。目的方便应用升级时,Deployment便于通过ReplicaSet管理一组pod进行应用升级。1、Dep
Deployment是一种高阶控制器资源,在部署时,Deployment创建并管理ReplicaSet,由ReplicaSet创建管理pod。目的方便应用升级时,Deployment便于通过ReplicaSet管理一组pod进行应用升级。
1、Deployment的创建
与pod、replicaset一样,deployment在k8s中也是一种资源,可以通过yaml的声明方式声明一套deployment的定义,然后通过kubectl create创建出deployment。下面以demo_deployment.yaml为例
apiVersion: apps/v1beta1 #版本
kind: Deployment #资源类型
metadata: #deployment的元数据
name: mydeployment #Deployment的资源名字
spec: #Deployment描述信息
minReadySeconds: 10 #pod创建延迟至少10s然后才ready状态
replicas: 3 #创建pod的副本数
template: #pod的模板信息
metadata: #pod的元数据
labels: #定义pod标签
app: mynginx-pod #pod的标签
spec: #pod中容器描述信息
containers: #定义容器
- name: mynginx #容器的名字
image: mynginx:v0.2 #容器中镜像
ports: #定义容器暴露的端口
- containerPort: 80
根据yaml创建deployment
[root@k8s-master01 deployment_work]# ls
demo_deployment.yaml
#创建deployment
[root@k8s-master01 deployment_work]# kubectl create -f demo_deployment.yaml --record
deployment.apps/mydeployment created
#查询deployment
[root@k8s-master01 deployment_work]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
mydeployment 3/3 3 3 10s
#查询replicaset
[root@k8s-master01 deployment_work]# kubectl get rs
NAME DESIRED CURRENT READY AGE
mydeployment-7fd7865495 3 3 3 17s
#查询pod
[root@k8s-master01 deployment_work]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mydeployment-7fd7865495-57jnx 1/1 Running 0 29s
mydeployment-7fd7865495-8vfdl 1/1 Running 0 29s
mydeployment-7fd7865495-c7j7c 1/1 Running 0 29s
由此可见,deployment显示创建了一个名字为mydeployment-7fd7865495的replicaset,由replicaset创建了3个pod。–record能显示变更历史原因,方便查看每个版本变更的原因。
2、deployment管理应用升级
当应用需要升级时,只需要修改deployment中的pod模板就可以控制pod中应用从旧版本升级到新版本中。deployment升级时,通过新建一个ReplicaSet,然后通过ReplicaSet重建新版本应用的pod,然后删除旧版本的pod,但是管理旧版本pod的ReplicaSet保留着,以防后续回滚用 deployment在升级pod应用过程 中采用两种升级策略:
- Recreate : 删除旧版本的pod后才会创建新版本的pod,会导致应用出现短暂的停机状态,如果应用不支持多版本,可以选择该策略。
- RollingUpdate : 删除旧版本的pod时,同时创建新版本的pod,应用平滑的升级,使应用在升级过程中也保持可用,但需要支持应用多版本,否则会导致数据错乱。Deployment的默认升级策略。
下面通过示例演示滚动升级,首先通过deployment部署mynginx:v0.2版本的应用,然后滚动升级成mynginx:v0.3版本,首先查看v0.2版本应用
#查看部署的pod
[root@k8s-master01 deployment_work]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mydeployment-6c5cf4c646-8knrf 1/1 Running 0 4m49s 10.244.2.75 k8s-node02 <none> <none>
mydeployment-6c5cf4c646-jp84k 1/1 Running 0 4m49s 10.244.1.73 k8s-node01 <none> <none>
mydeployment-6c5cf4c646-mwt2d 1/1 Running 0 4m49s 10.244.2.76 k8s-node02 <none> <none>
#访问pod中的应用,输出当前版本为2
[root@k8s-master01 deployment_work]# curl 10.244.2.75
hello lzj, this is version 2
下面升级镜像
kubectl set image deployment mydeployment mynginx=mynginx:v0.3
监控pod滚动更新状态如下:
[root@k8s-master01 deployment_work]# kubectl get pod -w
NAME READY STATUS RESTARTS AGE
mydeployment-6c5cf4c646-8knrf 1/1 Running 0 18m
mydeployment-6c5cf4c646-jp84k 1/1 Running 0 18m
mydeployment-6c5cf4c646-mwt2d 1/1 Running 0 18m
mydeployment-797fcb456f-6x9xm 1/1 Running 0 16s
mydeployment-6c5cf4c646-8knrf 1/1 Terminating 0 18m
mydeployment-797fcb456f-dd26l 0/1 Pending 0 0s
mydeployment-797fcb456f-dd26l 0/1 Pending 0 0s
mydeployment-797fcb456f-dd26l 0/1 ContainerCreating 0 0s
mydeployment-6c5cf4c646-8knrf 0/1 Terminating 0 18m
mydeployment-797fcb456f-dd26l 1/1 Running 0 1s
mydeployment-6c5cf4c646-8knrf 0/1 Terminating 0 18m
mydeployment-6c5cf4c646-8knrf 0/1 Terminating 0 18m
mydeployment-6c5cf4c646-mwt2d 1/1 Terminating 0 18m
mydeployment-797fcb456f-kl2m4 0/1 Pending 0 0s
mydeployment-797fcb456f-kl2m4 0/1 Pending 0 0s
mydeployment-797fcb456f-kl2m4 0/1 ContainerCreating 0 0s
mydeployment-6c5cf4c646-mwt2d 0/1 Terminating 0 18m
mydeployment-797fcb456f-kl2m4 1/1 Running 0 2s
mydeployment-6c5cf4c646-mwt2d 0/1 Terminating 0 18m
mydeployment-6c5cf4c646-mwt2d 0/1 Terminating 0 18m
mydeployment-6c5cf4c646-jp84k 1/1 Terminating 0 18m
mydeployment-6c5cf4c646-jp84k 0/1 Terminating 0 18m
mydeployment-6c5cf4c646-jp84k 0/1 Terminating 0 19m
mydeployment-6c5cf4c646-jp84k 0/1 Terminating 0 19m
[root@k8s-master01 deployment_work]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mydeployment-797fcb456f-6x9xm 1/1 Running 0 5m14s 10.244.1.74 k8s-node01 <none> <none>
mydeployment-797fcb456f-dd26l 1/1 Running 0 4m52s 10.244.2.77 k8s-node02 <none> <none>
mydeployment-797fcb456f-kl2m4 1/1 Running 0 4m31s 10.244.1.75 k8s-node01 <none> <none>
#请求pod,发现pod返回内容当前版本为3
[root@k8s-master01 deployment_work]# curl 10.244.1.74
hello lzj, this is version 3
发现pod是先创建一个v0.3版本的pod,然后停止一个v0.2版本的pod,直至滚动结束。从更新的状态中可以看出,deployment滚动更新时,是通过创建了另外一个ReplicaSet,然后通过ReplicaSet创建了3个v0.3版本的pod。最后把原来的ReplicaSet下的3个v0.2版本的pod删除掉。
注意:如果修改了deployment中的pod模板,会立即触发滚动更新,如果没修改pod模板,只是修改了deployment的一些属性,不会触发滚动更新的。
3、deployment管理应用回滚
当deployment部署应用升级后,如果发现当前版本有bug,需要回滚到上一版本,则可以通过deployment的rollout undo进行回滚。回滚的原理就是根据旧版本的ReplicaSet重新建旧版本的Pod应用,然后删除新版本的pod。如下所示,当前应用镜像版本为mynginx:v0.3,需要回滚到上一应用版本
[root@k8s-master01 dockerfile_work]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mydeployment-797fcb456f-2xj82 1/1 Running 0 82s 10.244.1.80 k8s-node01 <none> <none>
mydeployment-797fcb456f-8kczn 1/1 Running 0 60s 10.244.2.81 k8s-node02 <none> <none>
mydeployment-797fcb456f-c7z25 1/1 Running 0 39s 10.244.1.81 k8s-node01 <none> <none>
#访问pod中的当前应用,输出内容为v0.3版本的应用
[root@k8s-master01 dockerfile_work]# curl 10.244.1.80
hello lzj, this is version 3
#回滚到上一版本应用
[root@k8s-master01 dockerfile_work]# kubectl rollout undo deployment mydeployment
deployment.extensions/mydeployment rolled back
[root@k8s-master01 dockerfile_work]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mydeployment-6c5cf4c646-4nbfv 1/1 Running 0 77s 10.244.1.82 k8s-node01 <none> <none>
mydeployment-6c5cf4c646-5nj5j 1/1 Running 0 55s 10.244.2.83 k8s-node02 <none> <none>
mydeployment-6c5cf4c646-88sjf 1/1 Running 0 99s 10.244.2.82 k8s-node02 <none> <none>
#回滚结束后,重新访问pod中的应用,发现版本已经回退到v0.2版本
[root@k8s-master01 dockerfile_work]# curl 10.244.1.82
hello lzj, this is version 2
注意:执行上述操作后,应用已经回滚到了v0.2版本,如果按上述步骤再次执行就又会回到v0.3版本,可以通过指定回滚到的版本进行回滚。
#查询deployment的滚动历史,创建deployment时添加了--record,所以下面CHANGE-CAUSE才会有变更步骤的记录原因
[root@k8s-master01 dockerfile_work]# kubectl rollout history deployment mydeployment
deployment.extensions/mydeployment
REVISION CHANGE-CAUSE
1 kubectl create --filename=demo_deployment.yaml --record=true
3 kubectl create --filename=demo_deployment.yaml --record=true
4 kubectl create --filename=demo_deployment.yaml --record=true
#其中REVISION代表每次滚动时的版本编号,回滚时可以指定版本编号回滚到指定的版本。下面回滚到最初的应用版本。
[root@k8s-master01 dockerfile_work]# kubectl rollout undo deployment mydeployment --to-revision=1
deployment.extensions/mydeployment rolled back
[root@k8s-master01 dockerfile_work]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mydeployment-7fd7865495-7kdjl 1/1 Running 0 2m37s 10.244.1.83 k8s-node01 <none> <none>
mydeployment-7fd7865495-m77pm 1/1 Running 0 2m15s 10.244.2.84 k8s-node02 <none> <none>
mydeployment-7fd7865495-tr2mm 1/1 Running 0 114s 10.244.1.84 k8s-node01 <none> <none>
#回滚到最初的版本后,访问pod中的应用,发现输出了最初的NGINX内容
[root@k8s-master01 dockerfile_work]# curl 10.244.1.83
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
4、滚动失败,deployment自动回滚
在应用版本升级时,如果版本有bug,应控制deployment自动回滚到前一个版本。实现该功能需借助minReadySeconds和探针实现。
minReadySeconds用来指定没有任何容器crash的Pod并被认为是可用状态的最小秒数。默认是0(Pod在ready后就会被认为是可用状态)。如果minReadySeconds设置10s,可以使用minReadySeconds可以让deployment在第一个pod就绪之后继续等待10s,如pod没有问题,继续升级下一个pod继续等待10s,如此类推。一般设置minReadySeconds时间等于应用启动后可以正常接受流量的长度。在pod中设置就绪探针,如果在minReadySeconds时间内,探针失败了,deployment进行自动回滚。下面通过demo_deployment.yaml实例演示
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: mydeployment
spec:
minReadySeconds: 10
replicas: 3
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
name: myreplicaset
labels:
app: myreplicaset
spec:
containers:
- name: mynginx
image: mynginx:v0.3
ports:
- containerPort: 80
其中可以通过定义deployment的属性maxSurge与maxUnavailable控制滚动升级速率。
maxSurge:决定了deployment配置的副本数之外,最多允许超出的pod实例数量,比如副本数设置3,maxSurge设置的1,在deployment的滚动升级之间,最多允许存在4个 pod实例数量;
maxUnavailable:决定了deployment滚动升级之间,相对于期望副本数量最多有多少个pod实例数量处于不可用状态。比如副本设置为3,maxUnavailable设置为1,滚动升级时最多有2个pod实例处于可用状态。
#创建mydeployment
[root@k8s-master01 deployment_work]# kubectl apply -f demo_deployment.yaml --record
deployment.apps/mydeployment created
#查询创建出来的pod
[root@k8s-master01 dockerfile_work]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mydeployment-768bc94c96-gtf9w 1/1 Running 0 15s 10.244.1.92 k8s-node01 <none> <none>
mydeployment-768bc94c96-mphqp 1/1 Running 0 15s 10.244.2.93 k8s-node02 <none> <none>
mydeployment-768bc94c96-s8npx 1/1 Running 0 15s 10.244.1.93 k8s-node01 <none> <none>
#访问pod中应用,版本为2
[root@k8s-master01 dockerfile_work]# curl 10.244.1.92
hello lzj, this is version 2
下面修改yaml中镜像并为pod添加探针
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: mydeployment
spec:
minReadySeconds: 10
replicas: 3
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
name: myreplicaset
labels:
app: myreplicaset
spec:
containers:
- name: mynginx
image: mynginx:v0.3 #镜像修改为v0.3版本
readinessProbe: #增加就绪探针
periodSeconds: 1
httpGet:
path: /test.html
port: 8080
ports:
- containerPort: 80
容器中暴漏的是80端口,而探针探测的时8080端口,探针必定时失败的,下面执行deployment的滚动升级
#滚动升级mydeployment
[root@k8s-master01 deployment_work]# kubectl apply -f demo_deployment.yaml --record
deployment.apps/mydeployment configured
#查看升级后的pod,发现滚动失败,创建第一个pod时,状态为就绪,因此deployment自动回滚,回到v0.2版本
[root@k8s-master01 dockerfile_work]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mydeployment-5bcf884b6d-4ldjx 0/1 Running 0 11m 10.244.2.94 k8s-node02 <none> <none>
mydeployment-768bc94c96-gtf9w 1/1 Running 0 13m 10.244.1.92 k8s-node01 <none> <none>
mydeployment-768bc94c96-mphqp 1/1 Running 0 13m 10.244.2.93 k8s-node02 <none> <none>
mydeployment-768bc94c96-s8npx 1/1 Running 0 13m 10.244.1.93 k8s-node01 <none> <none>
#访问pod中应用,发现应用没有升级到v0.3版本,依然是v0.2版本
[root@k8s-master01 dockerfile_work]# curl 10.244.1.92
hello lzj, this is version 2
注意
1. kubectl create 与 kubectl apply区别
kubectl create只能执行一次,不能重复执行;
kubectl apply可以重复执行,是增量的执行,yaml中增加了什么东西,apply执行时只会创建增加的资源。
2. deployment相关操作命令
kubectl rollout status deployment mydeployment #查看deployment部署状态
kubectl set image deployment mydeployment mynginx=mynginx:v0.2 #版本升级为v0.2
kubectl rollout undo deployment mydeployment #回滚到上一级
kubectl rollout undo deployment mydeployment --to-revision=2 #回滚到指定的步骤
kubectl rollout pause deployment mydeployment #暂停升级,可以多次修改deployment后再恢复执行
kubectl rollout resume deployment mydeployment #恢复升级
参考《kubenetes in Action》
更多推荐
所有评论(0)