1、前言
1.1 蓝绿发布
核心思想: 同时维护两个完全相同的生产环境,一个称为“蓝色环境”(当前线上版本),另一个称为“绿色环境”(新版本)。部署时,先将新版本部署到空闲的绿色环境中,经过充分测试后,一次性将流量从蓝色环境全部切换到绿色环境。
工作流程:
- 准备两个环境:蓝色环境(当前生产环境,运行 V1)和绿色环境(空闲环境)。
- 将新版本(V2)部署到绿色环境中。
- 在绿色环境中进行测试、验证,确保一切正常。
- 修改负载均衡器的配置,将所有用户流量从蓝色环境瞬间切换到绿色环境。
- 此时,V2 成为新的线上版本。蓝色环境则变为空闲状态,可以保留用于快速回滚,或者作为下一次发布的目标环境。
1.2 优缺点
| 特性 | 蓝绿发布 |
|---|---|
| 风险控制 | 高。在正式切换前,新版本经过了完整环境的测试,风险较低。但一旦切换,问题会影响全部用户。 |
| 回滚速度 | 极快(秒级)。只需将流量切换回另一个环境即可,几乎无感知。 |
| 用户体验 | 无缝切换。切换过程非常快,用户几乎感觉不到中断。 |
| 真实反馈 | 反馈有限。切换前的测试通常是内部或自动化测试,无法获得大规模真实用户的反馈。 |
| 资源成本 | 非常高。需要维护两套完全相同的生产环境(服务器、数据库等),硬件成本翻倍。 |
| 复杂性 | 中等。部署和切换流程相对清晰,但对基础设施(如负载均衡器)和自动化部署脚本有要求。 |
| 数据库/状态 | 挑战大。需要解决数据迁移和共享的问题。如果新版本修改了数据库结构,必须保证两个环境都能兼容,或者在切换时进行数据迁移,这会增加复杂性和风险。 |
| 发布速度 | 快。一旦新版本部署并测试完毕,切换是瞬间的。 |
1.3 发布场景
1.需要实现零停机发布和秒级回滚:当任何服务中断都不可接受时,蓝绿发布提供了最可靠的保障。
2.应用相对简单,是无状态的:无状态应用使得蓝绿环境的切换非常简单,因为不涉及复杂的数据同步问题。
3.基础设施预算充足:能够承担双倍的服务器和资源成本。
4.希望发布流程清晰、简单:蓝绿发布的“部署-测试-切换”模式非常直观,易于理解和自动化。
5.对数据库的改动不大或可以做到向后兼容。
2、版本备注
2.1 环境镜像
| 镜像版本 | deployment | 备注 |
|---|---|---|
| harbor.test.com/java-dev/demo:blue | dev-demo-blue | 蓝版本,最终不承接流量 |
| harbor.test.com/java-dev/demo:green | dev-demo-green | 绿版本,最终承接所有流量 |
2.2 deployment
2.2.1 blue环境
apiVersion: apps/v1
kind: Deployment
metadata:
name: dev-demo-blue
namespace: devops
spec:
replicas: 2
selector:
matchLabels:
app: dev-demo-blue
template:
metadata:
labels:
app: dev-demo-blue
version: blue ###核心关键标签--blue
spec:
containers:
- name: dev-demo-blue
image: harbor.test.com/java-dev/demo:blue
restartPolicy: Always
dnsPolicy: ClusterFirst
2.2.2 green环境
apiVersion: apps/v1
kind: Deployment
metadata:
name: dev-demo-green
namespace: devops
spec:
replicas: 2
selector:
matchLabels:
app: dev-demo-green
template:
metadata:
labels:
app: dev-demo-green
version: green ###核心关键标签--green
spec:
containers:
- name: dev-demo-green
image: harbor.test.com/java-dev/demo:green
restartPolicy: Always
dnsPolicy: ClusterFirst
2.3 service
apiVersion: v1
kind: Service
metadata:
name: dev-demo
namespace: devops
spec:
selector:
app: dev-demo
version: blue ###svc选择blue/green标签,初始选择blue
ports:
- name: dev-demo-8080
protocol: TCP
port: 8080
targetPort: 8080
2.4 ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dev-ingress
namespace: devops
annotations:
spec:
ingressClassName: nginx
tls:
- hosts:
- mydevweb.local
secretName: mydevweb-secret
rules:
- host: mydevweb.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: dev-demo
port:
number: 8080
3、蓝绿发布
3.1 验证蓝环境(旧环境)
目前蓝绿两个环境都在运行,蓝承接100%流量,所以访问是必达蓝环境
for i in {1..20}; do curl -k -H "Host: mydevweb.local" https://mydevweb.local ;sleep 1;echo -e;done
#连续测试20次,均是蓝环境

3.2 验证green环境(新环境)
3.2.1 方案一:port-fordward
在green上线前,需要确认服务是否正常运行,例如检查端口
# 随机选择一个绿环境的Pod
green_pod=$(kubectl -n devops get pods -l version=green -o jsonpath='{.items[0].metadata.name}')
# 将本地端口转发到该Pod
kubectl -n devops port-forward $green_pod 9090:8080
# 在另一个终端访问本地端口进行测试
curl http://localhost:9090


3.2.2 方案二:创建临时service和ingress
有些服务的验证需求可能要在windows内网端进行,那么可以选择创建临时的svc和ingress供调试
3.3.2.1 svc
apiVersion: v1
kind: Service
metadata:
name: dev-demo-temp ###临时svc的名称
namespace: devops
spec:
selector:
app: dev-demo
version: green ###关键svc标签
ports:
- name: dev-demo-8080
protocol: TCP
port: 8080
targetPort: 8080
3.3.2.2 ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dev-ingress-green-temp ###临时svc的名称
namespace: devops
annotations:
spec:
ingressClassName: nginx
tls:
- hosts:
- mydevweb.local
secretName: mydevweb-secret
rules:
- host: green.mydevweb.local ###临时Host
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: dev-demo-temp ###指向临时svc
port:
number: 8080
3.3.2.4 写入本地Host
linux
#172.16.10.200是loadblance IP或EXTERNAL-IP
echo "172.16.10.200 mydevweb.local" >> /etc/hosts
windows
:: 写入实际的ip和host
set host=172.16.10.200 green.mydevweb.local
set tab=
set file=C:\Windows\System32\drivers\etc\hosts
echo.%tab% >> %file%
echo %host% >> %file%
3.3.2.5 验证

3.3 一键蓝切绿
验证正常后,可以通过一键命令进行切换,也是核心操作
# 使用patch命令,瞬间将selector从blue改为green
kubectl -n devops patch service dev-demo -p '{"spec":{"selector":{"version":"green"}}}'
#测试20次
for i in {1..20}; do curl -k -H "Host: mydevweb.local" https://mydevweb.local ;sleep 1;echo -e;done

3.4 一键绿切蓝(或回退)
下一次再发布时,蓝环境就会成为新的生产环境,
绿切蓝道理同蓝切绿
kubectl -n devops patch service dev-demo -p '{"spec":{"selector":{"version":"blue"}}}'
for i in {1..20}; do curl -k -H "Host: mydevweb.local" https://mydevweb.local ;sleep 1;echo -e;done

3.5 提示
蓝绿环境切换,可能不是瞬时的,会有短暂的新旧流量交替,但对用户而言,几乎不会感知,蓝绿发布也是一个可靠的优雅发布方案

评论区