实际项目中尝试K8S蓝绿部署

背景

我们有一个前端使用 Angular 的项目,采用 Kubenetes 默认部署方式 rolling updates 发布时,在更新 pod 的阶段有时会出现灰屏的现象,问题源于新旧 pod 的前端静态文件不兼容,想通过 kubernetes 的蓝绿部署(blue-green deployments)解决这个问题。

原理

蓝绿部署听上去高上大,但对 k8s 来说是小菜一碟,就是基于同一个 deployment 配置,以 label 作为区分,创建对应不同应用程序版本(blue和green)的 deployment 资源,通过修改 service 配置中 selectorlabel 选择对应的 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

手动挡蓝绿部署完成。

参考资料

posted @ 2021-02-03 22:06  dudu  阅读(961)  评论(2编辑  收藏  举报