一、了解一下蓝绿部署
# Kubernetes蓝绿部署详解
## 什么是蓝绿部署
蓝绿部署(Blue-Green Deployment)是一种应用程序发布策略,它通过维护两个完全相同的生产环境(通常称为"蓝"环境和"绿"环境)来实现无缝的应用更新和回滚。
## 蓝绿部署的核心原理
1. **两个并行环境**:同时存在两个独立的生产环境,一个活跃(服务真实流量),一个闲置
2. **流量切换**:通过负载均衡器或服务网格控制流量流向
3. **零停机更新**:新版本先部署到闲置环境,测试无误后切换流量
4. **快速回滚**:如果新版本有问题,只需将流量切回旧环境
## 在Kubernetes中实现蓝绿部署
### 主要实现方式
1. **使用Service和Label选择器**:
- 为蓝绿环境创建不同的Deployment
- 使用相同Service,通过修改label selector切换流量
2. **使用Ingress控制器**:
- 配置Ingress规则将流量导向不同版本
- 通过修改Ingress规则实现流量切换
3. **使用服务网格(如Istio)**:
- 利用虚拟服务和目标规则控制流量分配
- 支持更复杂的流量管理策略
### 具体实施步骤示例
1. **准备蓝环境(当前生产版本)**:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-blue
labels:
app: myapp
version: blue
```
2. **部署绿环境(新版本)**:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-green
labels:
app: myapp
version: green
```
3. **创建Service(初始指向蓝环境)**:
```yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
version: blue
ports:
- protocol: TCP
port: 80
targetPort: 8080
```
4. **测试绿环境**:
- 可以通过临时修改Service selector或直接访问Pod进行测试
5. **切换流量到绿环境**:
```yaml
# 更新Service的selector
spec:
selector:
app: myapp
version: green
```
6. **回滚(如有问题)**:
- 只需将Service selector改回指向蓝环境
## 蓝绿部署的优势
1. **零停机部署**:用户不会感知到部署过程
2. **快速回滚**:发现问题可立即切换回旧版本
3. **降低风险**:新版本完全测试后再接收生产流量
4. **简化运维**:部署和回滚过程标准化
5. **并行测试**:可以在生产环境中并行测试新旧版本
## 蓝绿部署的挑战
1. **资源需求**:需要双倍的基础设施资源
2. **数据一致性**:需要处理数据库迁移和兼容性问题
3. **会话保持**:需要确保用户会话在切换时不中断
4. **测试覆盖**:需要全面的测试策略验证新环境
## 适用场景
1. 关键业务系统需要高可用性
2. 对停机时间有严格要求的应用
3. 需要确保新版本稳定性的场景
4. 需要快速回滚能力的系统
## 最佳实践
1. 自动化部署和切换过程
2. 实施全面的监控和告警
3. 做好数据迁移和回滚计划
4. 考虑使用渐进式流量切换(如金丝雀发布结合)
5. 确保有足够的资源支持两个环境
蓝绿部署是Kubernetes中实现高可用、低风险部署的重要策略之一,特别适合对稳定性要求高的生产环境。
二、实战应用
[root@master ~]# cat test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: green
namespace: green-blue
spec:
replicas: 3
selector:
matchLabels:
color: green
template:
metadata:
labels:
color: green
spec:
containers:
- name: green
imagePullPolicy: IfNotPresent
image: docker.io/janakiramm/myapp:v2
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: green-port
namespace: green-blue
spec:
type: NodePort
ports:
- name: test
nodePort: 30082
port: 80
targetPort: 80
selector:
color: green
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: blue
namespace: green-blue
spec:
replicas: 3
selector:
matchLabels:
color: blue
template:
metadata:
labels:
color: blue
spec:
containers:
- name: blue
imagePullPolicy: IfNotPresent
image: docker.io/janakiramm/myapp:v1
ports:
- containerPort: 80
这个 YAML 文件定义了一个 **Kubernetes 蓝绿部署(Blue-Green Deployment)** 的配置,包含两个 Deployment(`green` 和 `blue`)和一个 Service(`green-port`),全部部署在 `green-blue` 命名空间下。以下是详细解析:
---
### **1. `green` Deployment(绿色环境)**
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: green
namespace: green-blue
spec:
replicas: 3 # 启动3个Pod副本
selector:
matchLabels:
color: green # 选择标签为color=green的Pod
template:
metadata:
labels:
color: green # 给Pod打上color=green的标签
spec:
containers:
- name: green
imagePullPolicy: IfNotPresent # 如果本地有镜像则不拉取
image: docker.io/janakiramm/myapp:v2 # 使用v2版本的镜像
ports:
- containerPort: 80 # 容器暴露80端口
```
- **作用**:部署一个名为 `green` 的应用,使用镜像 `myapp:v2`,运行3个副本。
- **关键点**:
- 标签 `color: green` 用于后续 Service 流量路由。
---
### **2. `green-port` Service(流量入口)**
```yaml
apiVersion: v1
kind: Service
metadata:
name: green-port
namespace: green-blue
spec:
type: NodePort # 通过节点端口暴露服务
ports:
- name: test
nodePort: 30082 # 外部访问的端口号(范围默认30000-32767)
port: 80 # Service的端口
targetPort: 80 # 转发到Pod的端口
selector:
color: green # 选择标签为color=green的Pod
```
- **作用**:将外部流量通过节点端口 `30082` 路由到 `green` Deployment 的 Pod。
- **关键点**:
- 访问方式:`http://<节点IP>:30082`。
- 当前流量全部指向 `green`(v2版本)。
---
### **3. `blue` Deployment(蓝色环境)**
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: blue
namespace: green-blue
spec:
replicas: 3 # 启动3个Pod副本
selector:
matchLabels:
color: blue # 选择标签为color=blue的Pod
template:
metadata:
labels:
color: blue # 给Pod打上color=blue的标签
spec:
containers:
- name: blue
imagePullPolicy: IfNotPresent
image: docker.io/janakiramm/myapp:v1 # 使用v1版本的镜像
ports:
- containerPort: 80
```
- **作用**:部署一个名为 `blue` 的应用,使用镜像 `myapp:v1`,运行3个副本。
- **关键点**:
- 这是旧版本(v1)的备份环境,当前没有流量进入(Service 未选择它)。
---
### **整体逻辑:蓝绿部署(Blue-Green Deployment)**
1. **当前流量**:
- Service `green-port` 的 `selector` 指向 `color: green`,所有外部请求(通过 `30082` 端口)会被路由到 `green`(v2版本)。
- `blue`(v1版本)作为备用环境,无流量。
2. **切换流程**:
- 如果需要回滚到旧版本(v1),只需修改 Service 的 `selector` 为 `color: blue`:
```bash
kubectl patch svc green-port -n green-blue -p '{"spec":{"selector":{"color":"blue"}}}'
```
- 此时流量会立即切换到 `blue` Deployment(v1版本)。
3. **优势**:
- 零停机时间发布/回滚。
- 新旧版本同时在线,便于测试和快速切换。
---
### **验证方法**
1. 查看 Pod 状态:
```bash
kubectl get pods -n green-blue -o wide --show-labels
```
2. 访问应用:
```bash
curl http://<节点IP>:30082
```
- 应返回 `myapp:v2` 的内容(因为当前 Service 指向 `green`)。
3. 切换流量到 `blue`(v1):
```bash
kubectl edit svc green-port -n green-blue
```
修改 `selector` 为:
```yaml
selector:
color: blue
```
再次访问 `30082` 端口,会看到 `myapp:v1` 的内容。
---
### **总结**
- **`green`(v2)**:当前生产环境,接收流量。
- **`blue`(v1)**:备用环境,随时可切换。
- **Service**:通过 `nodePort: 30082` 控制流量方向。
这是一个典型的蓝绿部署模式,适合需要无缝切换版本的场景。