Deployment控制器
Deployment控制器是建立在rs之上的一个控制器,可以管理多个rs,每次更新镜像版本,都会生成一个新的rs,把旧的rs替换掉,多个rs同时存在,但是只有一个rs运行。
使用Deployment而不直接创建ReplicaSet是因为Deployment对象拥有许多ReplicaSet没有的特性,例如滚动升级、金丝雀发布、蓝绿部署和回滚。
### deployment配置
#Kubernetes在等待设置的时间后才进行升级
#如果没有设置该值,Kubernetes会假设该容器启动起来后就提供服务了
minReadySeconds <integer>
# 暂停,当我们更新的时候创建pod先暂停,不是立即更新
paused <boolean>
# k8s 在升级过程中有可能由于各种原因升级卡住(这个时候还没有明确的升级失败),比如在拉取被墙的镜像,权限不够等错误。那么这个时候就需要有个 deadline ,在 deadline 之内如果还卡着,那么就上报这个情况,这个时候这个 Deployment 状态就被标记为 False,并且注明原因。但是它并不会阻止 Deployment 继续进行卡住后面的操作。完全由用户进行控制。
progressDeadlineSeconds <integer>
replicas <integer> #副本数
revisionHistoryLimit <integer> #保留的历史版本,默认是10
selector <Object> -required- #标签选择器,选择它关联的pod
strategy <Object> #更新策略
template <Object> -required #定义的pod模板
### strategy 配置
rollingUpdate <Object>
# 支持两种更新,Recreate和RollingUpdate
# Recreate是重建式更新,删除一个更新一个,因此不需要填写其他配置。recreate这种更新策略,会把之前的所有pod都删除,再创建新的pod,风险很大。
# RollingUpdate滚动更新,定义滚动更新方式,也就是pod能多几个,少几个
type <string>
Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate.
### 查看Deployment下的spec.strategy.rollingUpdate字段
# 我们更新的过程当中最多允许超出的指定的目标副本数有几个;
# 它有两种取值方式,第一种直接给定数量,第二种根据百分比。
# 和期望的副本数比,超过期望副本数最大比例(或最大值),这个值调的越大,副本更新速度越快
maxSurge <string>
# 和期望的副本数比,不可用副本数最大比例(或最大值),这个值越小,越能保证服务稳定,更新越平滑
maxUnavailable <string>
# 建议配置(平滑更新)
maxUnavailable == 0
maxSurge == 1
假设有5个副本,最多一个不可用,就表示最少有4个可用
replicas: 5
maxSurge: 25% 5*25%=1.25 ->5+2=7
maxUnavailable: 25% 5%25%=1.25 -> 5-1=4
### deployment 配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-v1
spec:
replicas: 2
selector:
matchLabels:
app: myapp
version: v1
template:
metadata:
labels:
app: myapp
version: v1
spec:
containers:
- name: myapp
image: janakiramm/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
startupProbe:
periodSeconds: 5
initialDelaySeconds: 20
timeoutSeconds: 10
httpGet:
scheme: HTTP
port: 80
path: /
livenessProbe:
periodSeconds: 5
initialDelaySeconds: 20
timeoutSeconds: 10
httpGet:
scheme: HTTP
port: 80
path: /
readinessProbe:
periodSeconds: 5
initialDelaySeconds: 20
timeoutSeconds: 10
httpGet:
scheme: HTTP
port: 80
path: /
# 查看delopyment历史版本
kubectl rollout history deployment myapp-v1
# 回滚操作(也是滚动更新) 回滚到version为1的版本
kubectl rollout undo deployment/myapp-v1 --to-revision=1 -n default
# 终端配置策略
kubectl patch deployment myapp-v1 -p '{"spec":{"strategy":{"rollingUpdate": {"maxSurge":1,"maxUnavailable":0}}}}'
蓝绿部署
蓝绿部署中,一共有两套系统:一套是正在提供服务系统,标记为“绿色”;另一套是准备发布的系统,标记为“蓝色”。两套系统都是功能完善的、正在运行的系统,只是系统版本和对外服务情况不同。
开发新版本,要用新版本替换线上的旧版本,在线上的系统之外,搭建了一个使用新版本代码的全新系统。 这时候,一共有两套系统在运行,正在对外提供服务的老系统是绿色系统,新部署的系统是蓝色系统。
优点:
1、更新过程无需停机,风险较少
2、回滚方便,只需要更改路由或者切换DNS服务器,效率较高
缺点:
1、成本较高,需要部署两套环境。如果新版本中基础服务出现问题,会瞬间影响全网用户;如果新版本有问题也会影响全网用户。
2、需要部署两套机器,费用开销大
### 蓝绿部署配置
# 1.创建绿色部署环境
cat > lv.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-v1
namespace: blue-green
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: v2
template:
metadata:
labels:
app: myapp
version: v2
spec:
containers:
- name: myapp
image: janakiramm/myapp:v2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
EOF
# 2.创建namespace
kubectl create ns blue-green
kubectl apply -f lv.yaml
kubectl get pods -n blue-green
# 3.创建前端service
cat > service_lanlv.yaml << EOF
apiVersion: v1
kind: Service
metadata:
name: myapp-lan-lv
namespace: blue-green
labels:
app: myapp
spec:
type: NodePort
ports:
- port: 80
nodePort: 30062
name: http
# 调度指向的是v2,也就是绿色环境的labels
selector:
app: myapp
version: v2
EOF
# 更新服务
kubectl apply -f service_lanlv.yaml
kubectl get svc -n blue-green
# 检查
访问http://k8s-master节点ip:30062
# 创建蓝色部署环境
cat > lan.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-v2
namespace: blue-green
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: v1
template:
metadata:
labels:
app: myapp
version: v1
spec:
containers:
- name: myapp
image: janakiramm/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
EOF
kubectl get pods -n blue-green
# 蓝色pod验证部署成功后,修改service_lanlv.yaml 配置文件,修改标签,让其匹配到蓝程序(升级之后的程序)
apiVersion: v1
kind: Service
metadata:
#
name: myapp-lan
namespace: blue-green
labels:
app: myapp
spec:
type: NodePort
ports:
- port: 80
nodePort: 30062
name: http
# 修改调度,选择到v1,也就是蓝色环境的labels
selector:
app: myapp
version: v1
kubectl apply -f service_lanlv.yaml
kubectl get svc -n blue-green
金丝雀发布(灰度发布)
金丝雀发布(又称灰度发布、灰度更新):金丝雀发布一般先发1台,或者一个小比例,例如2%的服务器,主要做流量验证用,也称为金丝雀 (Canary) 测试 (国内常称灰度测试)。
简单的金丝雀测试一般通过手工测试验证,复杂的金丝雀测试需要比较完善的监控基础设施配合,通过监控指标反馈,观察金丝雀的健康状况,作为后续发布或回退的依据。 如果金丝测试通过,则把剩余的V1版本全部升级为V2版本。如果金丝雀测试失败,则直接回退金丝雀,发布失败。
优点:
灵活,策略自定义,可以按照流量或具体的内容进行灰度(比如不同账号,不同参数),出现问题不会影响全网用户
缺点:
没有覆盖到所有的用户导致出现问题不好排查
# 先运行一个deployment
kubectl apply -f lv.yaml
kubectl get pods -l app=myapp -n blue-green -w
# 金丝雀发布
# 修改deployment的镜像参数,修改为nginx的镜像,创建完成一个pod后进行暂停
kubectl set image deployment myapp-v1 myapp=docker.io/nginx:v1 -n blue-green && kubectl rollout pause deployment myapp-v1 -n blue-green
# 把myapp这个容器的镜像更新到docker.io/xianchao/nginx:v1版本 更新镜像之后,创建一个新的pod就立即暂停,这就是我们说的金丝雀发布;如果暂停几个小时之后没有问题,那么取消暂停,就会依次执行后面步骤,把所有pod都升级。
# 如果出问题,回滚并删除新发布的pod
kubectl rollout undo deployment myapp-v1 -n blue-green
# 如果正常,解除暂停
kubectl rollout resume deployment myapp-v1 -n blue-green
# 查看rs资源,这是会发现出现了两个rs(用作回滚)
kubectl get rs -n blue-green
# 回滚的话,修改yaml文件(主要修改镜像名),重新apply