177 lines
5.5 KiB
Markdown
177 lines
5.5 KiB
Markdown
---
|
||
tags: [microservice, cicd, gitops, github-actions, argocd]
|
||
create time: 2026-05-05
|
||
---
|
||
|
||
# CI/CD 与 GitOps
|
||
|
||
## 概述
|
||
|
||
微服务需要**独立部署**。上百个服务的手工发布是不可想象的——必须用自动化流水线保证每次变更都能安全、快速地推送到生产环境。
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
CODE["代码提交"] --> TEST["测试 & 静态分析"]
|
||
TEST --> SCAN["安全扫描"]
|
||
SCAN --> BUILD["构建镜像"]
|
||
BUILD --> PUSH["推送仓库"]
|
||
PUSH --> STAGING["Staging 验证"]
|
||
STAGING -->|"人工审批"| PROD["Production 部署"]
|
||
|
||
style CODE fill:#e3f2fd
|
||
style TEST fill:#fff3e0
|
||
style SCAN fill:#fce4ec
|
||
style BUILD fill:#e8f5e9
|
||
style PUSH fill:#f3e5f5
|
||
style STAGING fill:#e0f7fa
|
||
style PROD fill:#c8e6c9
|
||
```
|
||
|
||
## CI/CD 设计原则
|
||
|
||
| 原则 | 说明 |
|
||
|------|------|
|
||
| **一次构建,多处部署** | 镜像不随环境重新编译,只改 K8s ConfigMap/环境变量 |
|
||
| **语义化版本** | 镜像 tag 用 `v1.2.3`,tag 即版本溯源 |
|
||
| **路径过滤** | 只对相关服务的代码变更触发构建 |
|
||
| **Commit SHA 作为镜像 tag** | 保证精确回滚 |
|
||
| **分阶段部署** | Staging → Production 的审批关卡不可跳过 |
|
||
|
||
## GitHub Actions Pipeline 实战
|
||
|
||
```yaml
|
||
# .github/workflows/deploy.yml
|
||
name: Deploy order-service
|
||
on:
|
||
push:
|
||
branches: [main]
|
||
paths:
|
||
- "services/order/**"
|
||
|
||
env:
|
||
REGISTRY: registry.example.com
|
||
IMAGE: order-service
|
||
|
||
jobs:
|
||
# ========== Stage 1: Build & Test ==========
|
||
build-and-test:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Run tests
|
||
run: make test
|
||
|
||
- name: Security scan
|
||
uses: aquasecurity/trivy-action@master
|
||
with:
|
||
scan-type: 'fs'
|
||
severity: 'CRITICAL,HIGH'
|
||
|
||
- name: Build Docker image
|
||
run: |
|
||
docker build -t ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ github.sha }} \
|
||
-t ${{ env.REGISTRY }}/${{ env.IMAGE }}:v${{ github.run_number }} \
|
||
-f services/order/Dockerfile \
|
||
services/order
|
||
|
||
- name: Push to registry
|
||
run: |
|
||
echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login -u ${{ secrets.REGISTRY_USER }} --password-stdin
|
||
docker push ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ github.sha }}
|
||
docker push ${{ env.REGISTRY }}/${{ env.IMAGE }}:v${{ github.run_number }}
|
||
|
||
# ========== Stage 2: Deploy to Staging ==========
|
||
deploy-staging:
|
||
needs: build-and-test
|
||
runs-on: ubuntu-latest
|
||
environment: staging
|
||
steps:
|
||
- name: Deploy to staging
|
||
run: |
|
||
kubectl set image deployment/order-service \
|
||
order=${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ github.sha }} \
|
||
--namespace=staging
|
||
kubectl rollout status deployment/order-service \
|
||
--namespace=staging --timeout=120s
|
||
|
||
# ========== Stage 3: Deploy to Production ==========
|
||
deploy-production:
|
||
needs: deploy-staging
|
||
runs-on: ubuntu-latest
|
||
environment: production
|
||
steps:
|
||
- name: Canary release (10% → 50% → 100%)
|
||
run: |
|
||
kubectl patch canary order-service --type merge \
|
||
-p '{"spec":{"weight":10}}'
|
||
|
||
# ... 等待监控确认,逐步放大流量
|
||
echo "Monitor metrics before proceeding..."
|
||
```
|
||
|
||
## GitOps 工作流
|
||
|
||
GitOps 的核心思想:**K8s 集群的状态 = Git 仓库中声明式配置的当前状态。**
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
Dev["开发者 PR"] -->|"修改 K8s manifest"| Git[(Git Repo)]
|
||
|
||
subgraph Cluster["K8s Cluster"]
|
||
Argo["ArgoCD / Flux"] -->|同步| K8sState["Pod/Service/ConfigMap"]
|
||
end
|
||
|
||
Git -.->|Webhook| Argo
|
||
|
||
Argo -->|"检测到差异"| Diff{"状态一致?"}
|
||
Diff -- 否 --> Sync["自动同步到 K8s ✅"]
|
||
Diff -- 是 --> OK["已一致 ⏸️"]
|
||
|
||
style Git fill:#e3f2fd
|
||
style Argo fill:#fff3e0
|
||
style K8sState fill:#e8f5e9
|
||
```
|
||
|
||
### 与传统 CI/CD 的区别
|
||
|
||
| 维度 | 传统 CI/CD | GitOps |
|
||
|------|-----------|--------|
|
||
| **部署驱动** | CI 服务器主动推送 | Git 仓库变动触发拉取 |
|
||
| **状态源** | CI pipeline 的历史记录 | Git commit history |
|
||
| **回滚方式** | 回到上一次的 pipeline | `git revert` + 自动同步 |
|
||
| **漂移检测** | 通常无 | 持续比对,自动修复不一致 |
|
||
| **代表工具** | Jenkins / GitLab CI / GitHub Actions | ArgoCD / Flux |
|
||
|
||
### GitOps 的优势
|
||
|
||
1. **审计完整** — 所有变更都在 Git 中可追溯
|
||
2. **回滚简单** — `git revert` 就是回滚操作
|
||
3. **自修复** — ArgoCD 持续监测并修复集群状态偏离
|
||
4. **多人协作** — 通过 PR Review 流程管控配置变更
|
||
|
||
## Helm — K8s 的包管理
|
||
|
||
当每个服务都有几十行 YAML 时,Helm 能大幅简化部署:
|
||
|
||
```bash
|
||
# 创建 Chart 模板
|
||
helm create order-service
|
||
|
||
# 使用 values.yaml 参数化部署
|
||
helm upgrade --install order-service ./charts/order-service \
|
||
--set image.tag=v1.2.3 \
|
||
--set replicas=3 \
|
||
--namespace=production
|
||
```
|
||
|
||
> [!tip] 为什么需要 Helm?
|
||
>
|
||
> 没有 Helm 时,每个服务都要手动维护 Deployment、Service、Ingress、ConfigMap 等几十个 YAML 文件。Helm 允许你把通用模板抽出来,只在 values.yaml 里改差异化配置。
|
||
|
||
## 关联笔记
|
||
|
||
- [[05-部署运维/容器化/README]] — Docker 镜像构建是 CI/CD 的第一步
|
||
- [[05-部署运维/Kubernetes/README]] — K8s 是部署的目标平台
|
||
- [[05-部署运维/SRE实践/README]] — 错误预算影响发布策略
|