一、概念
在学习rc和rs控制器资源时,这两个资源都是控制pod的副本数量的,但是,他们两个有个缺点,就是在部署新版本pod或者回滚代码的时候,需要先apply资源清单,然后再删除现有pod,通过资源控制,重新拉取新的pod来实现回滚或者迭代升级;
Depolyment控制器将Pod部署成无状态的应用,它只关心Pod的数量、更新方式、使用的镜像和资源限制等。由于是无状态的管理方式,因此Deployment控制器中没有“角色”和“顺序”的概念。即在Deployment控制器中没有状态。
deployments资源,实际上就是用来专门部署业务代码的控制器,专门用于企业业务代码的升级和回滚;
Deployment控制器、ReplicaSet和Pod之间关系图
- 创建Depolyment的过程
- 用户在创建Deployment时,Kubernetes会自动创建一个ReplicaSet。ReolicaSet在后台根据指定的副本数创建Pod,并检查Pod的状态,以确定Pod是启动成功还是失败
- 更新Deployment的过程
- 当用户更新Deployment时,Kubernetes会创建一个新的ReplicaSet。Deployment会将Pod从旧的ReplicaSet中迁移到新的ReplicaSet中
- 如果迁移失败或Pod不稳定,则Deployment会自动回滚到上一个版本
- 如果迁移成功,则Deployment将清除旧的,不必要的ReplicaSet.
- 当用户更新Deployment时,Kubernetes会创建一个新的ReplicaSet。Deployment会将Pod从旧的ReplicaSet中迁移到新的ReplicaSet中
二、Deployment的创建和使用
2.1 编辑资源清单dm.yaml
[root@master deployment-demo]# cat dm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dm01
spec:
#控制pod的副本数量
replicas: 7
#指定标签选择器,基于标签匹配pod
selector:
#声明基于标签匹配pod;
matchLabels:
k8s: dolphin
#pod的编写,定义pod模板;
template:
metadata:
name: pod01
labels:
k8s: dolphin
spec:
containers:
- name: c1
image: dolphinc/nginx:v1
ports:
- containerPort: 80
2.2 创建资源
[root@master deployment-demo]# kubectl apply -f dm.yaml
查看资源,可以看到多出来一个自动生成的标签
原理:
通过“标签”管理,实现rs资源的控制,它会在自动创建rs的过程中给rs自动生成一个特有的标签(专属于deplpyment),当apply更新资源清单的时候,它会通过标签选定是使用历史的rs还是重新创建rs
三、Deployment实现升级和回滚
基于上面创建的资源清单继续操作
3.1 创建service资源
[root@master deployment-demo]# cat svc.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-dm
spec:
type: NodePort
selector:
k8s: dolphin
ports:
- port: 99
targetPort: 80
nodePort: 31000
3.2 创建资源
[root@master deployment-demo]# kubectl apply -f svc.yaml
3.3 查看资源
资源绑定成功
3.4 浏览器访问资源
3.5 修改镜像,并更新资源
[root@master deployment-demo]# cat dm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dm01
spec:
#控制pod的副本数量
replicas: 7
#指定标签选择器,基于标签匹配pod
selector:
#声明基于标签匹配pod;
matchLabels:
k8s: dolphin
#pod的编写,定义pod模板;
template:
metadata:
name: pod01
labels:
k8s: dolphin
spec:
containers:
- name: c1
image: dolphinc/nginx:v2
ports:
- containerPort: 80
[root@master deployment-demo]# kubectl apply -f dm.yaml
deployment.apps/dm01 configured
3.6 再次查看资源(升级成功)
我们可以看到再次执行apply命令,会创建新的rs资源进行,并创建新的pod临时标签
访问资源页面,资源版本更新了
上面的升级操作我们也可以通过一下命令来操作
kubectl --record deployment.app/dm01 set image deployment.apps/dm01 dolphinc/nginx:v2
###
--record 是为了能够追溯修改的历史记录
3.7 追溯修改的历史
[root@master deployment-demo]# kubectl rollout history deployment dm01
deployment.apps/dm01
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3.8 回滚到之前的版本
上边的1就是之前的版本
[root@master deployment-demo]# kubectl rollout undo deployment dm01 --to-revision=1
deployment.apps/dm01 rolled back
查看页面,回滚成功
查看资源,我们可以看到回滚到之前版本,临时标签是不变的
四、Deployment的升级策略
4.1 Recreate
先停止所有pod,再批量创建新的pod;生产环境不建议使用,因为用户在此时会访问不到服务;
使用案例
[root@master deployment-demo]# cat dm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dm01
spec:
strategy:
type: Recreate
#控制pod的副本数量
replicas: 7
#指定标签选择器,基于标签匹配pod
selector:
#声明基于标签匹配pod;
matchLabels:
k8s: dolphin
#pod的编写,定义pod模板;
template:
metadata:
name: pod01
labels:
k8s: dolphin
spec:
containers:
- name: c1
image: dolphinc/nginx:v2
ports:
- containerPort: 80
4.2 RollingUpdate
滚动更新,即实现部分更新,逐渐替换掉原有的pod,也就是默认的策略;
[root@master deployment-demo]# cat dm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dm01
spec:
strategy:
type: RollingUpdate
#如果设置了滚动更新RollingUpdate类型,还需要设置更新的策略;
rollingUpdate:
#在原有Pod副本数量的基础上,多启动Pod的数量(也就是说,更新过程中可以存在2+副本个数的Pod,新旧版本一起)
maxSurge: 2
# 在升级过程中最大不可能访问pod的数量(也就是说,Pod副本数-1数量可以备注访问)
maxUnavailable: 1
#控制pod的副本数量
replicas: 7
#指定标签选择器,基于标签匹配pod
selector:
#声明基于标签匹配pod;
matchLabels:
k8s: dolphin
#pod的编写,定义pod模板;
template:
metadata:
name: pod01
labels:
k8s: dolphin
spec:
containers:
- name: c1
image: dolphinc/nginx:v1
ports:
- containerPort: 80
创建资源,下边截了三个状态的截图,刚更新资源,更新资源中,更新资源后
开始更新以及更新中,我们Running中的有6个( replicas: 7,也就是上边配置的maxUnavailable:1)符合配置要求
更新中我们有1个关闭中的,6个running+3个ContainerCreating(共9个,maxSurge: 2)说明我们更新过程中多启动了2个
更新结束最红我们是7个正在Running的pod资源
清空资源
[root@master deployment-demo]# kubectl delete deployment --all
deployment.apps "dm01" deleted
[root@master deployment-demo]# kubectl delete svc --all
service "kubernetes" deleted
service "svc-dm" deleted
五、常用的应用部署策略
5.1 金丝雀部署
金丝雀部署也叫灰度部署。是先让一部分用户继续使用旧版,而另一部分用户开始使用新版本;如果新版本没有发生意外,则逐步扩大新版本的使用范围,直到使用旧版本的用户都是用新版本。
5.1.1 svc.yaml
编辑创建service资源
[root@master deployment-demo]# cat svc.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-dm
spec:
type: NodePort
selector:
k8s: dolphin
ports:
- port: 99
targetPort: 80
nodePort: 31000
[root@master deployment-demo]# kubectl apply -f svc.yaml
5.1.2 dm-old.yaml (5个副本为例)
编辑创建旧版本deployment资源
[root@master deployment-demo]# cat dm-old.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dm01-v1
spec:
#控制pod的副本数量
replicas: 5
#指定标签选择器,基于标签匹配pod
selector:
#声明基于标签匹配pod;
matchLabels:
k8s: dolphin
version: v1.0
#pod的编写,定义pod模板;
template:
metadata:
name: pod01
labels:
k8s: dolphin
version: v1.0
spec:
containers:
- name: c1
image: dolphinc/nginx:v1
ports:
- containerPort: 80
[root@master deployment-demo]# kubectl apply -f dm-old.yaml
deployment.apps/dm01-v1 created
5.1.3 dm-new.yaml(1个副本为例)
编辑创建新版本deployment资源
[root@master deployment-demo]# cat dm-new.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dm01-v2
spec:
#控制pod的副本数量
replicas: 1
#指定标签选择器,基于标签匹配pod
selector:
#声明基于标签匹配pod;
matchLabels:
k8s: dolphin
version: v2.0
#pod的编写,定义pod模板;
template:
metadata:
name: pod01
labels:
k8s: dolphin
version: v2.0
spec:
containers:
- name: c1
image: dolphinc/nginx:v1
ports:
- containerPort: 80
[root@master deployment-demo]# kubectl apply -f dm-new.yaml
deployment.apps/dm01-v2 created
查看结果
[root@master deployment-demo]# for a in {1..100}; do sleep 1; curl "10.15.233.42:99"; done
上边部署了6个实例,5个版本1的,1个版本2的,我们通过服务循环访问,可以看到我们大概1/5概率会访问到服务2
5.1.4 将版本1缩容到2个,版本2扩容到3个
[root@master deployment-demo]# kubectl scale --replicas=2 deploy dm01-v1
deployment.apps/dm01-v1 scaled
[root@master deployment-demo]# kubectl scale --replicas=3 deploy dm01-v2
deployment.apps/dm01-v2 scaled
再次循环访问,访问版本服务的比例变了
5.1.5 停掉版本1,把版本2扩容到我们需的实例数
5.1.6 部署完成
至此,金丝雀部署完成。
总结:
我们用2个部署控制器部署项目,都交由同一个svc来对外提供服务,两个版本都注册到同一个endpoints上,来控制不同版本的数量,最终替换掉所有的旧版本。
清空资源:
5.2 蓝绿部署
蓝绿部署可以在线进行,具有较小风险,但是会对用户的体验有影响。另外,蓝绿部署由于同时部署了新旧两套版本,所以需要双倍的资源
5.2.1 svc.yaml(服务标签选择指定版本)
[root@master deployment-demo]# cat svc.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-dm
spec:
type: NodePort
selector:
k8s: dolphin
version: v1.0
ports:
- port: 99
targetPort: 80
nodePort: 31000
[root@master deployment-demo]# kubectl apply -f svc.yaml
service/svc-dm created
5.2.2 dm-old.yaml
同5.1.2一样
[root@master deployment-demo]# cat dm-old.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dm01-v1
spec:
#控制pod的副本数量
replicas: 5
#指定标签选择器,基于标签匹配pod
selector:
#声明基于标签匹配pod;
matchLabels:
k8s: dolphin
version: v1.0
#pod的编写,定义pod模板;
template:
metadata:
name: pod01
labels:
k8s: dolphin
version: v1.0
spec:
containers:
- name: c1
image: dolphinc/nginx:v1
ports:
- containerPort: 80
5.2.3 dm-new.yaml
同5.1.3一样
[root@master deployment-demo]# cat dm-new.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dm01-v2
spec:
#控制pod的副本数量
replicas: 5
#指定标签选择器,基于标签匹配pod
selector:
#声明基于标签匹配pod;
matchLabels:
k8s: dolphin
version: v2.0
#pod的编写,定义pod模板;
template:
metadata:
name: pod01
labels:
k8s: dolphin
version: v2.0
spec:
containers:
- name: c1
image: dolphinc/nginx:v2
ports:
- containerPort: 80
[root@master deployment-demo]# kubectl apply -f dm-old.yaml
deployment.apps/dm01-v1 created
[root@master deployment-demo]# kubectl apply -f dm-new.yaml
deployment.apps/dm01-v2 created
5.1.4 查看访问资源
因为我们service资源绑定的是version:v1.0这个资源,所以我们目前访问的都是版本1
5.1.5 切换Service服务到新版本
[root@master deployment-demo]# kubectl patch service/svc-dm -p '{"spec":{"selector":{"version":"v2.0"}}}'
再次请求服务,看到切换成功
5.1.6 删除旧版本,部署完成
[root@master deployment-demo]# kubectl delete deployment.apps/dm01-v1
deployment.apps "dm01-v1" deleted
5.3 滚动部署
我们平常修改yaml文件,再次应用的部署就是滚动部署,相对蓝绿部署更加节约资源。
5.5 总结
用户访问 | 版本时效 | 切换版本修改对象 | 对用户影响 | 风险 | |
---|---|---|---|---|---|
金丝雀部署 | 用户同时能访问两个版本,根据新旧版本都实例个数随机访问 | 切换过程中两个版本会存在较长时间 | deployment | 极小 | 中 因为部署过程中两个都存在,万一新版本有问题,用户能明显感知到 |
蓝绿部署 | 用户只能访问其中一个版本, | 因为两个版本都是稳定后才会切换,所以两个版本存在时间较长 | service | 有一定影响 | 低 因为切换版本我们一般是稳定测试过后切换,所以风险低 |
滚动部署 | 用户可能会访问到2个版本,但版本替换过程快 | 替换新版本,旧版本会马上被移出 | deoloyment | 极小 | 高 因为在执行应用新资源命令时,应用是逐步被替换,一般很快,所以万一新版本有问题,那么用户能立刻感知到 |