一、Deployment 高级控制器理论
1、Deployment控制器介绍
Deployment是ReplicaSet的高级别抽象,ReplicaSet控制器有的功能Deployment全部具备,ReplicaSet没有的Deployment也具备比如,它提供了滚动升级和回滚的功能。Deployment是控制多个ReplicaSet,从而可以实现无缝升级和回滚。
Deployment控制器特点:
- 选择器:ReplicaSet使用标签选择器来选择要管理的Pod副本。
- 伸缩性:Deployment高级控制器可以根据负载自动伸缩容器数量,以满足应用程序的需求。
- 自我修复:Deployment高级控制器可以监控容器的健康状况,并在容器出现故障时自动重启或替换容器。
- 负载均衡:Deployment高级控制器可以通过负载均衡算法,将请求分发到不同的容器实例上,以提高应用程序的性能和可用性。
- 版本控制:Deployment可以指定多个ReplicaSet,每个ReplicaSet可以控制不同版本的Pod,从而实现灰度发布和回滚。
- 声明式:指直接修改资源清单yaml文件,然后通过 apply ,就可以更改资源。
2、Deployment工作原理
Deployment控制器建立在ReplicaSet控制器之上,管理多个ReplicaSet,每次更新镜像版本,都会生成一个新的ReplicaSet,把旧的ReplicaSet替换掉,多个ReplicaSet同时存在,但只运行一个ReplicaSet。
如上图所示:ReplicaSet V1版本控制了三个Pod,ReplicaSet V1版本删除一个Pod,会在ReplicaSet V2版本新建一个Pod,以此类推,直到ReplicaSet V2版本完全替换完。
如果ReplicaSet V2版本更新上去存在问题,还可以回滚,Deployment建立在ReplicaSet之上,多个ReplicaSet组成一个Deployment,但只有一个ReplicaSet处于活跃状态。
二、Deployment YAML编写及参数解释
使用explain
命令查看定义 可以查看 deployment
控制器字段说明:
kubectl explain deployment
1、整体Deployment YAML资源清单内容:
cat demo-deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-deployment-1
labels:
env: uat
spec:
replicas: 3
minReadySeconds: 10 # 更新场景,等待时间,如果没有设置K8S会假设该容器启动起来后就提供服务了
paused: # 暂停,当更新Pod时,先暂停,而不是立马更新
progressDeadlineSeconds: 60 # 更新场景,等待时间超过此值,状态标记False,并说明原因,但是它并不会阻止 Deployment 继续进行卡住后面的操作
strategy:
rollingUpdate: # 滚动更新,定义滚动更新方式,也就是pod能多几个,少几个
maxSurge: 20% # 允许更新中,最多超过Pod数值
maxUnavailable: 20% # 允许更新中,最多允许几个不可用
selector:
matchLabels:
app: demo-nginx
template:
metadata:
labels:
app: demo-nginx
spec:
containers:
- name: demo-nginx
image: nginx
imagePullPolicy: IfNotPresent
startupProbe: # 启动探测
tcpSocket:
port: 80
livenessProbe: # 存活探测
httpGet:
port: 80
path: /index.html
readinessProbe: # 就绪探测
httpGet:
port: 80
path: "/index.html"
2、核心参数解释:
- spec.minReadySeconds:更新场景,等待时间,如果没有设置K8S会假设该容器启动起来后就提供服务了。
- spec.paused: 暂停,当更新Pod时,先暂停,而不是立马更新,后面金丝雀发布要用到
- spec.progressDeadlineSeconds:更新场景,等待时间超过此值,状态标记False,并说明原因,但是它并不会阻止 Deployment 继续进行卡住后面的操作
- spec.strategy.rollingUpdate:滚动更新,定义滚动更新方式,也就是pod能多几个,少几个
- spec.strategy.rollingUpdate.maxSurge:指定在更新期间可以创建的新Pod的最大数量。例如,如果maxSurge设置为1,而Deployment中有3个Pod,则在更新期间可以创建4个Pod,其中3个是旧的Pod,1个是新的Pod。
- spec.strategy.rollingUpdate.maxUnavailable:指定在更新期间可以同时停止的旧Pod的最大数量。例如,如果maxUnavailable设置为1,而Deployment中有3个Pod,则在更新期间可以停止2个Pod,其中1个是旧的Pod,1个是新的Pod。
3、Deployment更新策略:
Deployment目前支持两种更新策略
-
Recreate:重建式更新,把Pod全部删除,在重新创建,风险很大,不建议使用
-
rollingUpdate:滚动式更新,批量替换更新,平滑升级,用户无感知
4、Deployment更新策略百分比方式计算公式:
假设有5个副本,最多一个不可用,就表示最少有4个可用
- maxSurge: 25% 5*25%=1.25(~=2) 5+2=7个可用
- maxUnavailable: 25% 5%25%=1.25(~=1) 5-1=4个不可用
三、实战案例:
1、Deployment部署WEB站点
导入镜像:
ctr -n=k8s.io images import k8s_web.tar.gz
资源清单如下:
cat web-deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
labels:
env: uat
spec:
replicas: 5
minReadySeconds: 10
progressDeadlineSeconds: 60
strategy:
rollingUpdate:
maxSurge: 20%
maxUnavailable: 20%
selector:
matchLabels:
app: web-nginx
template:
metadata:
labels:
app: web-nginx
spec:
containers:
- name: web-nginx
image: web:v1
imagePullPolicy: IfNotPresent
startupProbe:
tcpSocket:
port: 80
livenessProbe:
httpGet:
port: 80
path: /index.html
readinessProbe:
httpGet:
port: 80
path: "/index.html"
执行YAML清单文件:
kubectl apply -f web-deployment.yaml
查看创建出来的资源:
kubectl get pod,rs -l app=web-nginx
访问WEB网站:
podIp=$(kubectl get pod -l app=web-nginx|awk NR==2|awk '{print $1}')
kubectl describe pod ${podIp}|grep -w IP:|awk NR==1|awk '{print $NF}'
curl 10.244.235.214
web version = V1
2、Deployment针对WEB站点扩缩容
扩容,将副本扩容至 7,根据上面YAML修改spec.replicas=7
修改完成后重新执行apply:
kubectl apply -f web-deployment.yaml
查看Pod数量:
kubectl get pods -l app=web-nginx|tail -n +2|wc -l
缩容,将副本缩容至 3,根据上面YAML修改spec.replicas=3
修改完成后重新执行apply:
kubectl apply -f web-deployment.yaml
查看Pod数量:
kubectl get pods -l app=web-nginx|tail -n +2|wc -l
3、Deployment针对WEB站点滚动更新
滚动更新是一种自动化较高的更新方式,即一批一批的更新Pod资源,用户体验比较平滑。滚动更新使用 spec.strategy.rollingUpdate
字段来定义。
基于上面YAML资源清单进行滚动更新,更换镜像版本为V2 YAML如下:
cat web-deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
labels:
env: uat
spec:
replicas: 5
minReadySeconds: 10
progressDeadlineSeconds: 60
strategy:
rollingUpdate:
maxSurge: 30% # 5*30%=1.5(~=2), 2+5=7,更新期间最多创建7个Pod
maxUnavailable: 20% # 5*20%=1, 1-5=4,更新期间最多停止4个Pod
selector:
matchLabels:
app: web-nginx
template:
metadata:
labels:
app: web-nginx
spec:
containers:
- name: web-nginx
image: web:v2 # 版本更新
imagePullPolicy: IfNotPresent
startupProbe:
tcpSocket:
port: 80
livenessProbe:
httpGet:
port: 80
path: /index.html
readinessProbe:
httpGet:
port: 80
path: "/index.html"
执行YAML文件:
kubectl apply -f web-deployment.yaml
访问WEB网站:
podIp=$(kubectl get pod -l app=web-nginx|awk NR==2|awk '{print $1}')
kubectl describe pod ${podIp}|grep -w IP:|awk NR==1|awk '{print $NF}'
curl 10.244.235.236
web version = V2
可以看到WEB网站内容更新至V2版本了
4、Deployment针对WEB站点回滚版本
查看历史版本:
kubectl rollout history deployment web-deployment
回滚版本:回滚到V1 版本
访问WEB网站:
podIp=$(kubectl get pod -l app=web-nginx|awk NR==2|awk '{print $1}')
kubectl describe pod ${podIp}|grep -w IP:|awk NR==1|awk '{print $NF}'
curl 10.244.235.231
web version = V1
可以看到WEB网站内容更新至V1版本了
四、蓝绿部署发布
1、蓝绿部署介绍
蓝绿部署中,需要有两套系统,一套是正在提供服务系统,标记为 绿色,另一套是准备发布的系统,标记为 蓝色,两套系统功能完善,只有 绿色 对外提供服务、蓝色用来发布前测试,测试无问题直接可以系统更新为 蓝色。
切换后一段时间内,蓝绿两套系统并存,观察蓝色系统确实无问题之后,将其进行删除,将资源回收。
- 优点:两套系统指只需要更改路由或者切换DNS服务器,风险小,效率高。
- 缺点:两套系统并存,占用资源大。
2、案例:实现蓝绿部署
K8S不支持蓝绿部署,需要我们来进行规划,创建不同的Deployment、不同的Service来实现不同流量的切换!
- 创建绿色系统(第一版)YAML如下:
cat green-demo.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: blue-green-demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: green-app
namespace: blue-green-demo
spec:
replicas: 3
selector:
matchLabels:
app: green-app
template:
metadata:
name: green-app
labels:
app: green-app
spec:
containers:
- name: green-app
image: web:v1
imagePullPolicy: IfNotPresent
startupProbe:
tcpSocket:
port: 80
livenessProbe:
httpGet:
port: 80
path: "/index.html"
readinessProbe:
httpGet:
port: 80
path: "/index.html"
创建Service 代理绿色(第一版)系统:
cat blue-green-svc.yaml
---
apiVersion: v1
kind: Service
metadata:
name: blue-green-svc
namespace: blue-green-demo
spec:
type: NodePort
ports:
- port: 80
nodePort: 30010
name: http
selector:
app: green-app
执行YAML文件:
kubectl apply -f green-demo.yaml
kubectl apply -f blue-green-svc.yaml
查看创建资源:
kubectl get pod,svc -n blue-green-demo
浏览器访问 IP:30010
- 创建蓝色系统(第二版)YAML如下:
cat blue-deom.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: blue-app
namespace: blue-green-demo
spec:
replicas: 3
selector:
matchLabels:
app: blue-app
template:
metadata:
name: blue-app
labels:
app: blue-app
spec:
containers:
- name: blue-app
image: web:v2
imagePullPolicy: IfNotPresent
startupProbe:
tcpSocket:
port: 80
livenessProbe:
httpGet:
port: 80
path: "/index.html"
readinessProbe:
httpGet:
port: 80
path: "/index.html"
执行YAML资源清单文件:
kubectl apply -f blue-deom.yaml
- 进行切换
只需要修改 Service 中选择标签即可。Service修改如下:
cat blue-green-svc.yaml
---
apiVersion: v1
kind: Service
metadata:
name: blue-green-svc
namespace: blue-green-demo
spec:
type: NodePort
ports:
- port: 80
nodePort: 30010
name: http
selector:
app: blue-app # 关联蓝色系统Pod标签
执行YAML文件:
kubectl apply -f blue-green-svc.yaml
浏览器刷新访问页面:
回滚也是一样,只需要修改Service更改代理Pod标签即可了!
五、金丝雀(灰度)部署
2、金丝雀部署介绍
金丝雀部署又称为灰度部署,它允许在生产环境中逐步推出新版本,以确保新版本的稳定性和可靠性。在金丝雀发布中,新版本应用程序只会在一小部分用户中进行测试,如果没有问题,就会逐步扩大范围,直到所有用户都在使用新版本。这种方法可以减少新版本应用程序出现问题的风险,同时也可以确保用户的体验不会受到太大影响。
-
优点:灵活、自定义策略,可以根据流量或内容进行金丝雀部署,出现问题不会影响全网用户。
-
缺点:没有覆盖全网用户,出现问题不好排查。
3、案例:实现金丝雀部署
首先创建Deployment资源,使用web:V1
镜像
cat deploy-demo.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-demo
spec:
replicas: 5
selector:
matchLabels:
app: web-nginx
template:
metadata:
name: nginx
labels:
app: web-nginx
spec:
containers:
- name: web-nginx
image: web:v1
imagePullPolicy: IfNotPresent
startupProbe:
tcpSocket:
port: 80
livenessProbe:
httpGet:
port: 80
path: "/index.html"
readinessProbe:
httpGet:
port: 80
path: "/index.html"
---
apiVersion: v1
kind: Service
metadata:
name: deploy-demo-svc
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30011
name: http
selector:
app: web-nginx
执行YAML文件:
kubectl apply -f deploy-demo.yaml
版本更新,进行金丝雀发布 版本更新为V2
,更新的时候使用 pause
暂停更新
kubectl set image deployment deploy-demo web-nginx=web:v2 && kubectl rollout pause deployment deploy-demo
上面命令语法解释:
# 更新镜像为web:v2
kubectl set image deployment {deploy控制器名称} {容器名称}=web:v2
浏览器访问:刷新页面会出现不同的页面,因为只更新了一部分
如果经过测试新版本无问题,可以使用 解除暂停,使其所有都更新为web:v2 版本
kubectl rollout resume deployment deploy-demo
五、总结
-
Deployment高级控制器建立在ReplicaSet之上,每次更新镜像版本,都会生成一个新的ReplicaSet,把旧的ReplicaSet替换掉,多个ReplicaSet同时存在,但只运行一个ReplicaSet。
-
Deployment扩缩容:直接修改
replicas
字段值,重新apply
。 -
Deployment滚动升级:使用字
spec.strategy
段定义升级策略,目前支持两种升级策略:- rollingUpdate滚动更新:批量替换更新,平滑升级,用户无感知。
- Recreate重建试更新:把Pod全部删除,在重新创建,风险很大,不建议使用。
-
Deployment版本回滚:使用
rollout history
查看历史版本,使用rollout undo .... --to-revision=x
指定回滚版本。 -
蓝绿发布:创建两套系统,利用修改Service关联Pod标签负载到对应系统。
-
金丝雀发布:只更新一小部分Pod,如果没问题,在进行全部更新,如果有问题不会影响全部用户。