HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • DevOps与CI/CD

    • DevOps & CI/CD实践手册
    • 第1章:CI/CD流程设计
    • 第2章:Jenkins与GitLab CI
    • 第3章:Docker容器化
    • 第4章:Kubernetes编排
    • 第5章:GitOps与自动化部署

第1章:CI/CD流程设计

什么是CI/CD

核心概念

CI(Continuous Integration,持续集成):

开发者频繁地(一天多次)将代码集成到主干分支,
每次集成都通过自动化构建和测试来验证,
从而尽早发现集成错误。

CD(Continuous Delivery,持续交付):

在CI的基础上,确保代码始终处于可部署状态,
可以随时一键部署到生产环境。

CD(Continuous Deployment,持续部署):

在持续交付的基础上,自动将代码部署到生产环境,
无需人工干预。

三者关系

┌──────────────────────────────────────────────────────┐
│                   DevOps 全流程                       │
└──────────────────────────────────────────────────────┘
    ↓                    ↓                    ↓
┌─────────┐       ┌─────────┐       ┌─────────┐
│   CI    │   →   │   CD    │   →   │   CD    │
│持续集成 │       │持续交付 │       │持续部署 │
└─────────┘       └─────────┘       └─────────┘
    │                  │                  │
    ├─ 代码提交        ├─ 自动化测试      ├─ 自动部署
    ├─ 自动构建        ├─ 制品发布        ├─ 无人工干预
    └─ 单元测试        └─ 一键部署        └─ 快速迭代

传统开发 vs CI/CD

传统开发流程:

┌─────────┐
│开发完成 │ (1-2周)
└─────────┘
     ↓
┌─────────┐
│手动构建 │ (1-2小时)
└─────────┘
     ↓
┌─────────┐
│手动测试 │ (1-2天)
└─────────┘
     ↓
┌─────────┐
│手动部署 │ (半天)
└─────────┘

问题:
 反馈周期长(2周后才发现问题)
 人工操作易出错
 部署效率低
 回滚困难

CI/CD流程:

┌─────────┐
│代码提交 │ (实时)
└─────────┘
     ↓
┌─────────┐
│自动构建 │ (5-10分钟)
└─────────┘
     ↓
┌─────────┐
│自动测试 │ (10-20分钟)
└─────────┘
     ↓
┌─────────┐
│自动部署 │ (5分钟)
└─────────┘

优势:
 快速反馈(30分钟内发现问题)
 自动化,减少人为错误
 提高部署频率(每天多次)
 一键回滚

CI/CD核心流程

完整流程图

┌──────────────────────────────────────────────────────────┐
│                     开发阶段                              │
└──────────────────────────────────────────────────────────┘
                          ↓
              ┌──────────────────┐
              │  1. 代码提交      │
              │  git push         │
              └──────────────────┘
                          ↓
┌──────────────────────────────────────────────────────────┐
│                     CI阶段                                │
└──────────────────────────────────────────────────────────┘
                          ↓
              ┌──────────────────┐
              │  2. 触发构建      │
              │  Webhook          │
              └──────────────────┘
                          ↓
              ┌──────────────────┐
              │  3. 代码检出      │
              │  git clone        │
              └──────────────────┘
                          ↓
              ┌──────────────────┐
              │  4. 编译构建      │
              │  go build         │
              └──────────────────┘
                          ↓
              ┌──────────────────┐
              │  5. 单元测试      │
              │  go test          │
              └──────────────────┘
                          ↓
              ┌──────────────────┐
              │  6. 代码质量检查  │
              │  SonarQube        │
              └──────────────────┘
                          ↓
              ┌──────────────────┐
              │  7. 打包制品      │
              │  Docker build     │
              └──────────────────┘
                          ↓
┌──────────────────────────────────────────────────────────┐
│                     CD阶段                                │
└──────────────────────────────────────────────────────────┘
                          ↓
              ┌──────────────────┐
              │  8. 推送镜像      │
              │  Docker push      │
              └──────────────────┘
                          ↓
              ┌──────────────────┐
              │  9. 部署到测试环境│
              │  kubectl apply    │
              └──────────────────┘
                          ↓
              ┌──────────────────┐
              │ 10. 集成测试      │
              │  API测试          │
              └──────────────────┘
                          ↓
              ┌──────────────────┐
              │ 11. 部署到生产    │
              │  kubectl apply    │
              └──────────────────┘
                          ↓
              ┌──────────────────┐
              │ 12. 健康检查      │
              │  Readiness Probe  │
              └──────────────────┘

Pipeline配置示例

GitLab CI配置(.gitlab-ci.yml):

# .gitlab-ci.yml
stages:
  - build      # 构建阶段
  - test       # 测试阶段
  - package    # 打包阶段
  - deploy     # 部署阶段

variables:
  IMAGE_NAME: myapp
  DOCKER_REGISTRY: harbor.example.com

# 1. 构建阶段
build:
  stage: build
  image: golang:1.21
  script:
    - go mod download
    - go build -o bin/myapp ./cmd/myapp
  artifacts:
    paths:
      - bin/myapp
    expire_in: 1 hour
  only:
    - main
    - develop

# 2. 单元测试
unit-test:
  stage: test
  image: golang:1.21
  script:
    - go test -v -cover ./...
  coverage: '/coverage: \d+.\d+% of statements/'
  only:
    - main
    - develop

# 3. 代码质量检查
code-quality:
  stage: test
  image: sonarsource/sonar-scanner-cli:latest
  script:
    - sonar-scanner
      -Dsonar.projectKey=myapp
      -Dsonar.sources=.
      -Dsonar.host.url=$SONAR_HOST_URL
      -Dsonar.login=$SONAR_TOKEN
  only:
    - main
    - develop

# 4. 构建Docker镜像
docker-build:
  stage: package
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker login $DOCKER_REGISTRY -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
    - docker build -t $DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA .
    - docker tag $DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA $DOCKER_REGISTRY/$IMAGE_NAME:latest
    - docker push $DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA
    - docker push $DOCKER_REGISTRY/$IMAGE_NAME:latest
  only:
    - main

# 5. 部署到测试环境
deploy-test:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    - kubectl set image deployment/myapp myapp=$DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA -n test
    - kubectl rollout status deployment/myapp -n test
  environment:
    name: test
    url: https://test.example.com
  only:
    - develop

# 6. 部署到生产环境(手动触发)
deploy-prod:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    - kubectl set image deployment/myapp myapp=$DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA -n production
    - kubectl rollout status deployment/myapp -n production
  environment:
    name: production
    url: https://example.com
  when: manual  # 需要手动触发
  only:
    - main

分支策略

1. Git Flow

流程图:

main (生产)    ─────●─────────────●───────────●────
                    │             │           │
                    │             │           │
release (预发)      └─────●───────┘           │
                          │                   │
                          │                   │
develop (开发)  ──●───────┴─────────●─────────┴────
                  │                 │
                  │                 │
feature (功能)    └───●─────●───────┘
                      │     │
                    开发  合并

分支说明:

main:    生产环境分支,只接受合并,不直接提交
release: 预发布分支,用于发布前测试
develop: 开发主分支,日常开发的集成分支
feature: 功能分支,从develop拉取,开发完成后合并回develop
hotfix:  紧急修复分支,从main拉取,修复后合并到main和develop

工作流程:

# 1. 创建功能分支
git checkout develop
git pull
git checkout -b feature/user-login

# 2. 开发功能
git add .
git commit -m "feat: add user login"
git push origin feature/user-login

# 3. 创建Merge Request,合并到develop
# (触发CI/CD,自动部署到测试环境)

# 4. 从develop创建release分支
git checkout develop
git checkout -b release/v1.2.0

# 5. 测试通过后,合并到main
git checkout main
git merge release/v1.2.0
git tag v1.2.0
git push origin main --tags

# 6. 同时合并回develop
git checkout develop
git merge release/v1.2.0

优劣分析:

优点:
 流程清晰,职责明确
 适合大型团队
 支持多版本并行开发

缺点:
 分支复杂,学习成本高
 合并冲突多
 发布周期长

2. GitHub Flow

流程图:

main (生产)  ──●─────────────●─────────────●────
               │             │             │
               │             │             │
feature        └───●─────●───┘             │
                   │     │                 │
                 开发  合并               │
                                          │
hotfix                                    └───●───
                                              │
                                            修复

工作流程:

# 1. 从main创建功能分支
git checkout main
git pull
git checkout -b feature/add-payment

# 2. 开发并推送
git add .
git commit -m "feat: add payment feature"
git push origin feature/add-payment

# 3. 创建Pull Request
# (触发CI/CD,自动部署到预览环境)

# 4. Code Review通过后,合并到main
# (自动部署到生产环境)

# 5. 删除功能分支
git branch -d feature/add-payment

优劣分析:

优点:
 流程简单,易于理解
 适合持续部署
 减少分支管理成本

缺点:
 不适合多版本并行
 需要强大的CI/CD支持
 要求代码质量高

3. Trunk-Based Development

流程图:

main (主干)  ──●──●──●──●──●──●──●──●──●────
               │  │  │  │  │  │  │  │  │
             开发者直接提交到main
             每次提交触发CI/CD

工作流程:

# 1. 拉取最新代码
git checkout main
git pull

# 2. 开发(使用Feature Flag控制未完成功能)
# main.go
func main() {
    if featureFlag.IsEnabled("new_payment") {
        // 新功能
    } else {
        // 旧功能
    }
}

# 3. 提交到main
git add .
git commit -m "feat: add payment (behind feature flag)"
git push origin main

# 4. 自动触发CI/CD,部署到生产

优劣分析:

优点:
 极简流程
 持续集成
 减少合并冲突

缺点:
 需要Feature Flag
 要求极高的代码质量
 需要完善的自动化测试

分支策略选择

选择Git Flow:
 大型团队(> 20人)
 需要维护多个版本
 发布周期较长(每月/每季度)

选择GitHub Flow:
 中小型团队(< 20人)
 持续部署
 快速迭代

选择Trunk-Based:
 极致DevOps团队
 高度自动化
 超快速迭代(每天多次部署)

构建工具

1. Go项目构建

Makefile:

# Makefile
APP_NAME := myapp
VERSION := $(shell git describe --tags --always --dirty)
BUILD_TIME := $(shell date -u '+%Y-%m-%d_%H:%M:%S')
COMMIT := $(shell git rev-parse --short HEAD)

LDFLAGS := -ldflags "-X main.Version=$(VERSION) -X main.BuildTime=$(BUILD_TIME) -X main.GitCommit=$(COMMIT)"

.PHONY: all build test clean docker

all: test build

# 构建
build:
	@echo "Building $(APP_NAME)..."
	CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o bin/$(APP_NAME) ./cmd/$(APP_NAME)

# 测试
test:
	@echo "Running tests..."
	go test -v -cover ./...

# 清理
clean:
	@echo "Cleaning..."
	rm -rf bin/

# 构建Docker镜像
docker:
	@echo "Building Docker image..."
	docker build -t $(APP_NAME):$(VERSION) .

# 本地运行
run:
	@echo "Running $(APP_NAME)..."
	go run ./cmd/$(APP_NAME)

# 依赖管理
deps:
	go mod download
	go mod tidy

使用:

# 构建
make build

# 测试
make test

# 构建Docker镜像
make docker

# 本地运行
make run

2. Java项目构建(Maven)

pom.xml:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>myapp</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <properties>
        <java.version>17</java.version>
        <spring-boot.version>3.1.0</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

构建命令:

# 清理
mvn clean

# 编译
mvn compile

# 测试
mvn test

# 打包
mvn package

# 跳过测试打包
mvn package -DskipTests

# 安装到本地仓库
mvn install

# 部署到远程仓库
mvn deploy

3. Node.js项目构建(npm)

package.json:

{
  "name": "myapp",
  "version": "1.0.0",
  "scripts": {
    "build": "webpack --mode production",
    "test": "jest",
    "lint": "eslint src/",
    "start": "node dist/index.js",
    "dev": "webpack-dev-server --mode development"
  },
  "dependencies": {
    "express": "^4.18.0"
  },
  "devDependencies": {
    "webpack": "^5.88.0",
    "jest": "^29.0.0",
    "eslint": "^8.45.0"
  }
}

构建命令:

# 安装依赖
npm install

# 构建
npm run build

# 测试
npm test

# 代码检查
npm run lint

# 本地运行
npm run dev

制品管理

1. 制品类型

二进制制品:
- JAR/WAR(Java)
- Executable(Go)
- Wheel(Python)

容器镜像:
- Docker镜像
- OCI镜像

前端制品:
- npm包
- 静态资源(HTML、CSS、JS)

2. 制品仓库选择

对比表:

仓库类型优势适用场景
Nexus通用支持多种格式(Maven、npm、Docker)企业级
HarborDocker安全扫描、签名验证容器化
JFrog Artifactory通用功能最全大型企业
Docker HubDocker公共镜像开源项目

3. Harbor私有镜像仓库

安装Harbor:

# 1. 下载Harbor
wget https://github.com/goharbor/harbor/releases/download/v2.9.0/harbor-offline-installer-v2.9.0.tgz
tar xzvf harbor-offline-installer-v2.9.0.tgz
cd harbor

# 2. 配置harbor.yml
cp harbor.yml.tmpl harbor.yml
vim harbor.yml

# harbor.yml
hostname: harbor.example.com
http:
  port: 80
https:
  port: 443
  certificate: /path/to/cert.crt
  private_key: /path/to/cert.key
harbor_admin_password: Harbor12345
database:
  password: root123

# 3. 安装
sudo ./install.sh

# 4. 访问
# https://harbor.example.com
# 用户名: admin
# 密码: Harbor12345

推送镜像到Harbor:

# 1. 登录Harbor
docker login harbor.example.com
Username: admin
Password: Harbor12345

# 2. 构建镜像
docker build -t myapp:v1.0.0 .

# 3. 打标签
docker tag myapp:v1.0.0 harbor.example.com/myproject/myapp:v1.0.0

# 4. 推送
docker push harbor.example.com/myproject/myapp:v1.0.0

4. 制品版本管理

语义化版本(Semantic Versioning):

格式:MAJOR.MINOR.PATCH

示例:
- 1.0.0:初始版本
- 1.0.1:Bug修复(PATCH)
- 1.1.0:新功能,向后兼容(MINOR)
- 2.0.0:破坏性变更(MAJOR)

Git Tag:
git tag v1.0.0
git push origin v1.0.0

Docker镜像版本管理:

# 多标签策略
docker build -t myapp:v1.2.3 .
docker tag myapp:v1.2.3 myapp:v1.2
docker tag myapp:v1.2.3 myapp:v1
docker tag myapp:v1.2.3 myapp:latest

# 推送所有标签
docker push myapp:v1.2.3
docker push myapp:v1.2
docker push myapp:v1
docker push myapp:latest

环境管理

1. 环境划分

┌──────────────┐
│   开发环境   │  Development(dev)
│  本地开发    │  - 开发者本地机器
└──────────────┘  - 快速迭代
       ↓
┌──────────────┐
│   测试环境   │  Testing(test)
│  功能测试    │  - 自动化测试
└──────────────┘  - 手动测试
       ↓
┌──────────────┐
│   预发环境   │  Staging(staging)
│  生产镜像    │  - 与生产环境一致
└──────────────┘  - 最终验证
       ↓
┌──────────────┐
│   生产环境   │  Production(prod)
│  真实用户    │  - 实际运行环境
└──────────────┘  - 高可用

2. 环境配置管理

方案1:环境变量:

# .env.dev
DATABASE_URL=postgres://localhost:5432/myapp_dev
REDIS_URL=redis://localhost:6379/0
LOG_LEVEL=debug

# .env.prod
DATABASE_URL=postgres://prod-db.example.com:5432/myapp
REDIS_URL=redis://prod-redis.example.com:6379/0
LOG_LEVEL=info

方案2:配置文件:

# config/dev.yaml
database:
  host: localhost
  port: 5432
  name: myapp_dev

redis:
  host: localhost
  port: 6379

log:
  level: debug

# config/prod.yaml
database:
  host: prod-db.example.com
  port: 5432
  name: myapp

redis:
  host: prod-redis.example.com
  port: 6379

log:
  level: info

方案3:Kubernetes ConfigMap:

# configmap-dev.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: myapp-config
  namespace: dev
data:
  DATABASE_URL: postgres://localhost:5432/myapp_dev
  REDIS_URL: redis://localhost:6379/0
  LOG_LEVEL: debug

---
# configmap-prod.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: myapp-config
  namespace: production
data:
  DATABASE_URL: postgres://prod-db.example.com:5432/myapp
  REDIS_URL: redis://prod-redis.example.com:6379/0
  LOG_LEVEL: info

3. 环境隔离

网络隔离:

┌──────────────────────────────────────┐
│          VPC (10.0.0.0/16)           │
│                                      │
│  ┌────────────────────────────────┐ │
│  │  开发环境 (10.0.1.0/24)        │ │
│  │  - dev-k8s-cluster             │ │
│  └────────────────────────────────┘ │
│                                      │
│  ┌────────────────────────────────┐ │
│  │  测试环境 (10.0.2.0/24)        │ │
│  │  - test-k8s-cluster            │ │
│  └────────────────────────────────┘ │
│                                      │
│  ┌────────────────────────────────┐ │
│  │  生产环境 (10.0.3.0/24)        │ │
│  │  - prod-k8s-cluster            │ │
│  └────────────────────────────────┘ │
│                                      │
└──────────────────────────────────────┘

Kubernetes命名空间隔离:

# 创建命名空间
kubectl create namespace dev
kubectl create namespace test
kubectl create namespace staging
kubectl create namespace production

# 部署到不同环境
kubectl apply -f deployment.yaml -n dev
kubectl apply -f deployment.yaml -n production

面试问答

什么是CI/CD?有什么优势?

答案:

定义:

CI(持续集成):
频繁地将代码集成到主干,每次集成通过自动化构建和测试验证。

CD(持续交付):
确保代码始终处于可部署状态,可随时一键部署。

CD(持续部署):
自动将代码部署到生产环境,无需人工干预。

优势:

1. 快速反馈:
   - 传统:2周后才发现问题
   - CI/CD:30分钟内发现问题

2. 提高质量:
   - 自动化测试覆盖
   - 代码质量检查
   - 减少人为错误

3. 加快交付:
   - 部署频率:从每月→每天多次
   - 减少部署时间:从半天→5分钟

4. 降低风险:
   - 小批量发布
   - 快速回滚
   - 减少故障影响

Git Flow和GitHub Flow有什么区别?如何选择?

答案:

对比:

维度Git FlowGitHub Flow
分支5种(main、develop、feature、release、hotfix)2种(main、feature)
复杂度高低
发布周期长(每月/每季度)短(每天/每周)
适合团队大型团队中小型团队
适合场景多版本并行持续部署

选择建议:

选择Git Flow:
 大型团队(> 20人)
 需要维护多个版本(如SaaS多租户)
 发布周期较长
 严格的质量控制

选择GitHub Flow:
 中小型团队(< 20人)
 单一版本
 快速迭代
 强大的CI/CD支持

选择Trunk-Based:
 极致DevOps团队
 高度自动化
 超快速迭代

如何设计一个完整的CI/CD流水线?

答案:

完整流水线设计:

# .gitlab-ci.yml
stages:
  - build      # 构建
  - test       # 测试
  - security   # 安全
  - package    # 打包
  - deploy     # 部署

# 1. 构建
build:
  stage: build
  script:
    - go build -o bin/myapp

# 2. 单元测试
unit-test:
  stage: test
  script:
    - go test -cover ./...
  coverage: '/coverage: \d+.\d+%/'

# 3. 集成测试
integration-test:
  stage: test
  script:
    - docker-compose up -d
    - go test -tags=integration ./...

# 4. 代码质量
code-quality:
  stage: security
  script:
    - sonar-scanner

# 5. 安全扫描
security-scan:
  stage: security
  script:
    - trivy image myapp:latest

# 6. 构建镜像
docker-build:
  stage: package
  script:
    - docker build -t myapp:$CI_COMMIT_SHA .
    - docker push myapp:$CI_COMMIT_SHA

# 7. 部署测试环境
deploy-test:
  stage: deploy
  script:
    - kubectl set image deployment/myapp myapp=myapp:$CI_COMMIT_SHA -n test

# 8. 部署生产(手动触发)
deploy-prod:
  stage: deploy
  script:
    - kubectl set image deployment/myapp myapp=myapp:$CI_COMMIT_SHA -n production
  when: manual

关键要素:

1. 构建阶段:
    编译代码
    生成制品

2. 测试阶段:
    单元测试
    集成测试
    代码覆盖率

3. 质量阶段:
    代码质量检查(SonarQube)
    安全扫描(Trivy)
    依赖检查

4. 打包阶段:
    构建Docker镜像
    推送到镜像仓库
    生成版本标签

5. 部署阶段:
    自动部署到测试环境
    手动部署到生产环境
    健康检查

如何优化CI/CD流水线的速度?

答案:

优化策略:

1. 并行执行:

# 并行执行测试
stages:
  - test

unit-test:
  stage: test
  script:
    - go test ./internal/...

integration-test:
  stage: test
  script:
    - go test -tags=integration ./...

e2e-test:
  stage: test
  script:
    - npm run test:e2e

# 三个测试并行执行,节省时间

2. 缓存依赖:

build:
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - vendor/      # Go依赖
      - node_modules/ # Node依赖
      - .m2/         # Maven依赖
  script:
    - go build

3. 增量构建:

build:
  script:
    - |
      if git diff --name-only $CI_COMMIT_BEFORE_SHA $CI_COMMIT_SHA | grep -q "^frontend/"; then
        echo "前端代码变更,构建前端"
        npm run build
      fi
    - |
      if git diff --name-only $CI_COMMIT_BEFORE_SHA $CI_COMMIT_SHA | grep -q "^backend/"; then
        echo "后端代码变更,构建后端"
        go build
      fi

4. Docker多阶段构建:

# 多阶段构建,减少镜像大小
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

FROM alpine:latest
COPY --from=builder /app/myapp /myapp
CMD ["/myapp"]

5. 使用更快的Runner:

build:
  tags:
    - docker
    - high-performance  # 使用高性能Runner

效果对比:

优化前:
- 构建:10分钟
- 测试:15分钟
- 打包:5分钟
- 总计:30分钟

优化后:
- 并行构建+测试:8分钟(并行)
- 缓存依赖:节省3分钟
- 增量构建:节省5分钟
- 总计:10分钟

提速:3倍

如何保证生产环境部署的安全性?

答案:

安全措施:

1. 手动审批:

deploy-prod:
  stage: deploy
  script:
    - kubectl apply -f deployment.yaml -n production
  when: manual  # 需要手动点击才会部署
  only:
    - main

2. 四眼原则(Four-Eyes Principle):

deploy-prod:
  stage: deploy
  script:
    - kubectl apply -f deployment.yaml
  environment:
    name: production
    action: prepare  # 需要另一个人批准
  only:
    - main

3. 部署时间窗口:

deploy-prod:
  stage: deploy
  script:
    - |
      HOUR=$(date +%H)
      if [ $HOUR -lt 10 ] || [ $HOUR -gt 18 ]; then
        echo "只允许在10:00-18:00部署生产环境"
        exit 1
      fi
    - kubectl apply -f deployment.yaml

4. 金丝雀部署:

# 先部署10%流量
deploy-canary:
  script:
    - kubectl apply -f canary-deployment.yaml  # replicas: 1
    - sleep 300  # 观察5分钟

# 观察无问题,全量部署
deploy-prod:
  script:
    - kubectl apply -f production-deployment.yaml  # replicas: 10
  when: manual

5. 自动回滚:

deploy-prod:
  script:
    - kubectl apply -f deployment.yaml
    - kubectl rollout status deployment/myapp
    - |
      # 健康检查
      for i in {1..30}; do
        if curl -f http://myapp/health; then
          echo "部署成功"
          exit 0
        fi
        sleep 10
      done
      echo "健康检查失败,自动回滚"
      kubectl rollout undo deployment/myapp
      exit 1

6. 蓝绿部署:

# 1. 部署新版本(绿)
kubectl apply -f deployment-v2.yaml

# 2. 验证新版本
kubectl exec -it test-pod -- curl http://myapp-v2/health

# 3. 切换流量(修改Service selector)
kubectl patch service myapp -p '{"spec":{"selector":{"version":"v2"}}}'

# 4. 观察,如有问题立即切回
kubectl patch service myapp -p '{"spec":{"selector":{"version":"v1"}}}'

参考资料

  • Continuous Integration - Martin Fowler
  • Git Flow
  • GitHub Flow
  • Trunk Based Development
  • The Twelve-Factor App
Prev
DevOps & CI/CD实践手册
Next
第2章:Jenkins与GitLab CI