实际项目中尝试K8S蓝绿部署
背景
我们有一个前端使用 Angular 的项目,采用 Kubenetes 默认部署方式 rolling updates 发布时,在更新 pod 的阶段有时会出现灰屏的现象,问题源于新旧 pod 的前端静态文件不兼容,想通过 kubernetes 的蓝绿部署(blue-green deployments)解决这个问题。
原理
蓝绿部署听上去高上大,但对 k8s 来说是小菜一碟,就是基于同一个 deployment
配置,以 label
作为区分,创建对应不同应用程序版本(blue和green)的 deployment
资源,通过修改 service
配置中 selector
的 label
选择对应的 deployment
资源,将流量在 blue 与 green 之间切换。
准备配置文件与部署脚本
在 deployment 配置文件中添加基于环境变量的 version
配置项,用它区分蓝绿版本
apiVersion: apps/v1
kind: Deployment
metadata:
name: i-web-${VERSION}
spec:
template:
metadata:
labels:
app: i-web
version: "${VERSION}"
编写部署绿色(green)版的脚本 deploy-green.sh
export VERSION=$2
for filename in deployments/$1/*.yaml
do
envsubst < $filename | kubectl apply -f -
done
在 service 配置文件中添加 version
配置项,用于在蓝色(blue)版与绿色(green)版之间切换流量。
apiVersion: v1
kind: Service
metadata:
name: i-web
spec:
type: NodePort
selector:
app: i-web
version: "${VERSION}"
编写切换蓝绿版的脚本 toggle.sh
export VERSION=$2
for filename in services/$1/*.yaml
do
envsubst < $filename | kubectl apply -f -
done
编写删除蓝色版的脚本 remove-blue.sh
kubectl delete deployment/$1-web-$2
进行一次蓝绿发布
当前 blue 版本
$ kubectl get pods -l app=i-web
NAME READY STATUS RESTARTS AGE
i-web-2.1.54-69cbb6cdbd-6glzq 1/1 Running 0 174m
用下面的命令获取当前 blue 版的版本号
$ kubectl get service i-web -o=json | jq '.spec.selector.version' | tr -d '"'
2.1.54
部署 green 版,版本号是 2.1.55(对应的容器镜像已生成)
./deploy-green.sh i 2.1.55
查看部署结果,等 green 版 pod 启动成功
kubectl get pods -l app=i-web
NAME READY STATUS RESTARTS AGE
i-web-2.1.54-69cbb6cdbd-6glzq 1/1 Running 0 3h11m
i-web-2.1.55-5d5dbd7f7d-hvp44 1/1 Running 1 4m55s
green 版已部署成功,blue 版与 green 版的 pod 都在运行
将流量切换到 green 版
./toggle.sh i 2.1.55
切换之后如果有问题,切回 blue 版
./toggle.sh i 2.1.54
如果没有问题,等一段时间,删除 blue 版
./remove-blue.sh i 2.1.54
手动挡蓝绿部署完成。