DevOps & Platform Engineering Engine
完整的系统,用于构建、部署、操作和监控生产软件。涵盖整个DevOps生命周期——不仅仅是CI/CD,不仅仅是一个云。
第一阶段:代码库和分支策略
Git流程决策矩阵
| 团队规模 | 发布节奏 | 策略 | 分支 |
|---|---|---|---|
| 1-3 | 持续 | 主干开发 | main + 短期功能/ |
| 4-15 | 每周/双周 | GitHub Flow | main + 功能/ + PR |
| 15+ | 计划发布 | Git Flow | main + 开发 + 功能/ + 发布/ + 热修复/ |
| 受监管 | 审核发布 | Git Flow + 标签 | 上述 + 签名标签 + 审核轨迹 |
分支保护规则(应用这些)
# branch-protection.yml — 文档化你的规则
main:
required_reviews: 2
dismiss_stale_reviews: true
require_codeowners: true
require_status_checks:
- ci/test
- ci/lint
- ci/security
require_linear_history: true # 无合并提交
restrict_pushes: true # 仅限PR
require_signed_commits: false # 受监管时启用
develop:
required_reviews: 1
require_status_checks:
- ci/test
提交约定
格式:<type>(<scope>): <description>
类型:feat, fix, docs, style, refactor, perf, test, build, ci, chore
重大变更:feat!: remove legacy API 或页脚 BREAKING CHANGE: description
使用commitlint + husky (Node) 或预提交钩子强制执行。
第二阶段:CI/CD管道架构
管道设计原则
- 构建一次,部署到任何地方 — 相同的构件通过开发→测试→生产
- 快速失败 — 最便宜的检查首先(lint→单元→集成→端到端)
- 密封构建 — 没有外部状态,从提交SHA可复制
- 不可变构件 — 构建后永不修改;用git SHA标记
- 并行化独立阶段 — 同时进行测试/lint/security扫描
通用管道模板
# pipeline-stages.yml — 适应你的CI系统
stages:
# 第1阶段:质量门(并行,<2分钟)
lint:
run: lint
parallel: true
timeout: 2m
typecheck:
run: tsc --noEmit
parallel: true
timeout: 2m
security_scan:
run: trivy, snyk, 或 semgrep
parallel: true
timeout: 3m
# 第2阶段:测试(按类型并行,<10分钟)
unit_tests:
run: test --unit
parallel: true
coverage_threshold: 80%
timeout: 5m
integration_tests:
run: test --integration
parallel: true
needs: [database_service]
timeout: 10m
# 第3阶段:构建(<5分钟)
build:
needs: [lint, typecheck, unit_tests]
outputs: [docker_image, release_artifact]
tag: "${GIT_SHA}"
cache: [node_modules, .next/cache, target/]
# 第4阶段:部署到测试环境(自动)
deploy_staging:
needs: [build]
environment: staging
strategy: rolling
smoke_test: true
auto: true
# 第5阶段:在测试环境进行端到端测试(<15分钟)
e2e_tests:
needs: [deploy_staging]
timeout: 15m
retry: 1
artifacts: [screenshots, videos]
# 第6阶段:部署到生产环境(手动门或自动)
deploy_prod:
needs: [e2e_tests]
environment: production
strategy: canary # 或蓝绿
approval: required # 手动门
rollback_on_failure: true
monitoring_window: 15m
CI平台备忘单
| 特性 | GitHub Actions | GitLab CI | CircleCI | Jenkins |
|---|---|---|---|---|
| 配置文件 | .github/workflows/*.yml |
.gitlab-ci.yml |
.circleci/config.yml |
Jenkinsfile |
| 并行性 | jobs.<id> (自动) |
stages + parallel |
workflows |
parallel 步骤 |
| 缓存 | actions/cache |
cache: 键 |
save_cache/restore_cache |
Stash/unstash |
| 机密 | 设置 → 机密 | 设置 → CI/CD → 变量 | 项目设置 → 环境 | 凭据插件 |
| 矩阵构建 | strategy.matrix |
parallel:matrix |
matrix 在工作流中 |
matrix 在管道中 |
| 自托管 | runs-on: self-hosted |
GitLab Runner | resource_class |
默认 |
| OIDC/无密钥 | permissions: id-token: write |
id_tokens: |
OIDC上下文 | 插件 |
缓存策略
# 缓存键模式(按特定性排序)
cache_keys:
# 首先精确匹配
- "deps-{{ runner.os }}-{{ hashFiles('**/lockfile') }}"
# 部分匹配回退
- "deps-{{ runner.os }}-"
# 按栈缓存什么
node: [node_modules, .next/cache, .turbo]
python: [.venv, .mypy_cache, .pytest_cache]
rust: [target/, ~/.cargo/registry]
go: [~/go/pkg/mod, ~/.cache/go-build]
docker: [/tmp/.buildx-cache] # BuildKit层缓存
GitHub Actions特定模式
# 可重用工作流(跨仓库DRY)
# .github/workflows/reusable-deploy.yml
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
DEPLOY_KEY:
required: true
# 调用者工作流
jobs:
deploy:
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: production
secrets: inherit
# 基于路径的触发器(单体仓库)
on:
push:
paths:
- 'packages/api/**'
- 'shared/**'
# 跳过仅文档更改的CI
pull_request:
paths-ignore:
- '**.md'
- 'docs/**'
# 并发(新推送时取消进行中的)
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
第三阶段:容器策略
Dockerfile最佳实践
# 多阶段构建模板
# 第1阶段:构建
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --production=false # 安装所有构建依赖
COPY . .
RUN npm run build
# 第2阶段:生产
FROM node:20-alpine AS production
RUN addgroup -g 1001 app && adduser -u 1001 -G app -s /bin/sh -D app
WORKDIR /app
COPY --from=builder --chown=app:app /app/dist ./dist
COPY --from=builder --chown=app:app /app/node_modules ./node_modules
COPY --from=builder --chown=app:app /app/package.json ./
USER app
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/index.js"]
镜像大小缩减清单
- [ ] 使用alpine或distroless基础镜像
- [ ] 多阶段构建(构建依赖不在最终镜像中)
- [ ]
.dockerignore排除:.git,node_modules,*.md, 测试,文档 - [ ] 合并RUN命令(更少的层)
- [ ] 在同一RUN中清理包管理器缓存(
rm -rf /var/cache/apk/*) - [ ] 生产阶段不包含开发依赖
- [ ] 固定基础镜像SHA:
FROM node:20-alpine@sha256:abc123...
容器安全扫描
# Trivy(推荐 — 免费,快速)
trivy image myapp:latest --severity HIGH,CRITICAL
trivy fs . --security-checks vuln,secret,config
# CI中推送前扫描
# 如果发现CRITICAL漏洞则失败管道
trivy image --exit-code 1 --severity CRITICAL myapp:${GIT_SHA}
本地开发Docker Compose
# docker-compose.yml — 本地开发栈
services:
app:
build:
context: .
target: builder # 使用构建阶段进行热重载
volumes:
- .:/app
- /app/node_modules # 不覆盖node_modules
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/app
- REDIS_URL=redis://cache:6379
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: app
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 5s
timeout: 3s
retries: 5
cache:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
pgdata:
第四阶段:基础设施即代码
IaC决策矩阵
| 工具 | 最适合 | 状态 | 语言 | 学习曲线 |
|---|---|---|---|---|
| Terraform/OpenTofu | 多云,云中立 | 远程(S3, GCS) | HCL | 中等 |
| Pulumi | 开发者偏好真实代码 | 远程 | TS/Python/Go | 如果你编码则低 |
| AWS CDK | 仅限AWS商店 | CloudFormation | TS/Python | 中等 |
| Ansible | 配置管理,服务器设置 | 无状态 | YAML | 低 |
| Helm | Kubernetes部署 | Tiller/OCI | YAML+Go模板 | 中等 |
Terraform项目结构
infrastructure/
├── modules/ # 可重用组件
│ ├── vpc/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── ecs-service/
│ └── rds/
├── environments/
│ ├── dev/
│ │ ├── main.tf # 使用dev参数调用模块
│ │ ├── terraform.tfvars
│ │ └── backend.tf # 开发状态存储桶
│ ├── staging/
│ └── prod/
├── .terraform-version # 固定Terraform版本
└── .tflint.hcl
Terraform安全规则
- 总是
plan在apply之前 — 审查每个更改 - 带有锁定的远程状态 — S3 + DynamoDB或GCS + 锁定
- 状态永远不在git中 — 包含机密(数据库密码,密钥)
- 导入现有资源之前管理它们 — 不要重新创建
- 在关键资源上使用
prevent_destroy(数据库,S3桶) - 标记一切 —
environment,team,cost-center,managed-by: terraform - **
terraform fmt**在CI中 — 一致的格式化
# backend.tf — 带有锁定的远程状态
terraform {
backend "s3" {
bucket = "mycompany-terraform-state"
key = "prod/main.tfstate"
region = "eu-west-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
# 保护关键资源
resource "aws_rds_instance" "main" {
# ...
lifecycle {
prevent_destroy = true
}
}
环境晋升模式
┌──────────────────┐
terraform plan ──►│ Review in PR │
└────────┬─────────┘
│ merge
┌────────▼─────────┐
自动应用 ──────►│ Dev │──► 烟雾测试
└────────┬─────────┘
│ 提升
┌────────▼─────────┐
手动批准 ──►│ Staging │──► 集成测试
└────────┬─────────┘
│ 提升(手动门)
┌────────▼─────────┐
手动批准 ──►│ Production │──► 监控窗口
└──────────────────┘
第五阶段:Kubernetes操作
K8s资源模板
# deployment.yml — 生产就绪模板
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
labels:
app: myapp
version: "1.0.0"
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0 # 零停机时间
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
containers:
- name: myapp
image: myregistry/myapp:abc123 # Git SHA标签
ports:
- containerPort: 3000
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: myapp-secrets
key: database-url
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
# hpa.yml — 自动缩放
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 5分钟冷却
policies:
- type: Pods
value: 1
periodSeconds: 60 # 每分钟最多缩小1个pod
Helm图表清单
- [ ]
values.yaml带有合理的默认值(开箱即用) - [ ] 设置资源请求和限制
- [ ] 定义健康/就绪探针
- [ ] PodDisruptionBudget(minAvailable: 1或maxUnavailable: 25%)
- [ ] NetworkPolicy(拒绝所有,允许特定)
- [ ] ServiceAccount(不是默认)
- [ ] 通过external-secrets-operator或sealed-secrets管理Secrets(不是明文)
- [ ] CI中的
helm lint和helm template - [ ] NOTES.txt带有安装后说明
kubectl备忘单
# 调试
kubectl get pods -l app=myapp -o wide # Pod状态+节点
kubectl describe pod <pod> # 事件,条件
kubectl logs <pod> --tail=100 -f # 流日志
kubectl logs <pod> --previous # 崩溃容器日志
kubectl exec -it <pod> -- /bin/sh # 进入pod的shell
kubectl top pods -l app=myapp # 资源使用情况
# 部署
kubectl rollout status deployment/myapp # 观察部署
kubectl rollout history deployment/myapp # 修订历史
kubectl rollout undo deployment/myapp # 回滚到上一个
kubectl rollout undo deployment/myapp --to-revision=3 # 特定
# 缩放
kubectl scale deployment/myapp --replicas=5 # 手动缩放
kubectl autoscale deployment/myapp --min=3 --max=10 --cpu-percent=70
# 上下文管理
kubectl config get-contexts # 列出集群
kubectl config use-context prod-cluster # 切换
kubectl config set-context --current --namespace=myapp # 设置命名空间
第六阶段:部署策略
策略决策矩阵
| 策略 | 风险 | 速度 | 回滚 | 成本 | 最适合 |
|---|---|---|---|---|---|
| 滚动 | 低-中 | 快 | 慢(重新滚动) | 无 | 标准部署 |
| 蓝绿 | 低 | 即时 | 即时(开关) | 2倍基础设施 | 关键服务,零停机时间 |
| 金丝雀 | 非常低 | 慢 | 即时(路由0%) | 最小 | 高流量,风险变更 |
| 功能标志 | 非常低 | 即时 | 即时(切换) | 无 | 逐步推出,A/B测试 |
| 重新创建 | 高 | 快 | 慢 | 无 | 开发/测试,有状态应用 |
金丝雀部署工作流程
1. 部署金丝雀(1个新版本的pod)
2. 路由5%流量→金丝雀
3. 监控5分钟:
- 错误率<基线+0.1%?
- p99延迟<基线+50ms?
- 没有新的错误类型?
4. 如果健康→25%→监控10分钟
5. 如果健康→50%→监控10分钟
6. 如果健康→100%(完全推出)
7. 如果任何检查失败→路由0%到金丝雀→回滚→警报
自动化:Argo Rollouts, Flagger, 或Istio +自定义控制器
回滚清单
当部署出现问题时:
- 立即:将流量从新版本路由走(金丝雀→0%,蓝绿→开关)
- 如果滚动:
kubectl rollout undo或重新部署上一个SHA - 检查:数据库迁移是否向后兼容?(如果不是,你有更大的问题)
- 验证:回滚成功?检查错误率,延迟
- 沟通:在#incidents发布,更新状态页面
- 调查:在找到根本原因之前不要重新部署
数据库迁移安全
规则:迁移必须与前一个版本向后兼容。
(因为在滚动部署期间,两个版本同时运行)
安全迁移模式:
v1:添加新列(可空,默认值)
v2:回填数据,开始写入新列
v3:使新列必填,停止写入旧列
v4:删除旧列(在v3完全部署后)
永远不要在一个部署中:
❌ 重命名列
❌ 更改列类型
❌ 删除仍然由当前版本读取的列
❌ 添加NOT NULL无默认值
第七阶段:可观测性栈
三大支柱+奖金
| 支柱 | 什么 | 工具 | 优先级 |
|---|---|---|---|
| 指标 | 随时间变化的数值测量 | Prometheus, Datadog, CloudWatch | 1(从这里开始) |
| 日志 | 事件记录 | ELK, Loki, CloudWatch Logs | 2 |
| 追踪 | 跨服务的请求流 | Jaeger, Tempo, X-Ray, Honeycomb | 3 |
| 分析 | CPU/内存热点路径 | Pyroscope, Parca | 4(优化时) |
关键指标跟踪
# RED方法(请求驱动服务)
rate: # 每秒请求数
errors: # 每秒失败请求数
duration: # 延迟分布(p50, p95, p99)
# USE方法(基础设施/资源)
utilization: # 资源使用百分比(CPU, 内存, 磁盘)
saturation: # 队列深度,待处理工作
errors: # 资源错误(OOM, 磁盘已满)
# 商业指标(最重要的!)
signups_per_hour:
checkout_completion_rate:
api_calls_by_customer:
revenue_per_minute:
告警规则
# alerting-rules.yml
alerts:
# 基于症状(好的 — 告诉你用户受到影响)
- name: HighErrorRate
condition: "error_rate_5xx > 1% for 5m"
severity: critical
runbook: docs/runbooks/high-error-rate.md
notify: [pagerduty, slack-incidents]
- name: HighLatency
condition: "p99_latency > 2s for 5m"
severity: warning
runbook: docs/runbooks/high-latency.md
notify: [slack-incidents]
# 基于原因(补充 — 帮助诊断)
- name: PodCrashLooping
condition: "pod_restart_count increase > 3 in 10m"
severity: warning
notify: [slack-platform]
- name: DiskSpaceWarning
condition: "disk_usage > 80%"
severity: warning
notify: [slack-platform]
- name: CertificateExpiring
condition: "cert_expiry_days < 14"
severity: warning
notify: [slack-platform]
# 告警规则:
# 1. 每个告警必须有运行手册链接
# 2. 每个告警必须是可操作的(如果你不能做任何事情,删除它)
# 3. 严重=叫醒某人。警告=下个工作日检查。
# 4. 每月审查告警 — 归档未使用的,调整嘈杂的
结构化日志标准
{
"timestamp": "2026-02-16T05:00:00.000Z",
"level": "error",
"service": "api",
"trace_id": "abc123",
"span_id": "def456",
"method": "POST",
"path": "/api/orders",
"status": 500,
"duration_ms": 342,
"user_id": "usr_789",
"error": {
"type": "DatabaseError",
"message": "connection timeout",
"stack": "..."
},
"context": {
"order_id": "ord_123",
"payment_method": "card"
}
}
日志级别指南:
error: 某事失败,需要关注warn: 意外但已处理(重试成功,回退使用)info: 商业事件(下订单,用户注册,部署开始)debug: 技术细节(执行查询,缓存命中/未命中) — 生产环境中关闭
仪表板模板
每个服务仪表板应该包括:
第1行:流量概览
- 请求率(每个端点)
- 错误率(4xx, 5xx分开)
- 活跃用户/连接数
第2行:性能
- p50, p95, p99延迟
- 吞吐量
- Apdex得分
第3行:资源
- CPU利用率(每个pod/实例)
- 内存使用量(与限制相比)
- 磁盘I/O / 网络I/O
第4行:业务
- 每分钟收入(如果适用)
- 转化漏斗
- 队列深度/处理延迟
第5行:依赖项
- 数据库查询延迟+连接池
- 外部API延迟+错误率
- 缓存命中率
第八阶段:事件响应
严重性级别
| 级别 | 定义 | 响应时间 | 示例 |
|---|---|---|---|
| SEV-1 | 完全中断,收入影响 | 15分钟 | 网站关闭,支付失败 |
| SEV-2 | 主要功能损坏,存在替代方案 | 30分钟 | 搜索损坏,结账缓慢 |
| SEV-3 | 次要功能损坏,低影响 | 4小时 | 管理面板错误,非关键API |
| SEV-4 | 外观/无用户影响 | 下一个冲刺 | 错别字,次要UI问题 |
事件工作流程
1. 检测(自动或报告)
→ 告警触发/用户报告问题
→ 创建事件频道:#inc-YYYY-MM-DD-description
2. 分类(前5分钟)
→ 分配事件指挥官(IC)
→ 确定严重性级别
→ 在频道中发布初步评估
→ 更新状态页面(如果面向客户)
3. 缓解(专注于停止出血)
→ 我们可以回滚吗?→ 做它
→ 我们可以扩展吗?→ 做它
→ 我们可以功能标志禁用吗?→ 做它
→ 现在不要调试根本原因 — 首先恢复服务
4. 解决
→ 确认服务恢复(指标,客户报告)
→ 向利益相关者通报解决方案
→ 更新状态页面
5. 事后分析(48小时内)
→ 无责任 — 专注于系统,而不是人
→ 事件时间线
→ 根本原因分析(5个为什么)
→ 行动项目,负责人和截止日期
→ 与团队分享
事后分析模板
# 事件事后分析:[标题]
**日期:** YYYY-MM-DD
**持续时间:** Xh Ym
**严重性:** SEV-X
**事件指挥官:** [名称]
**作者:** [名称]
## 摘要
[1-2句话总结发生了什么以及影响]
## 影响
- 用户受影响:[数量/百分比]
- 收入影响:[如果适用]
- 持续时间:[开始到完全解决]
## 时间线(所有时间UTC)
| 时间 | 事件 |
|------|-------|
| 14:00 | 部署v2.3.1开始 |
| 14:05 | 错误率飙升至15% |
| 14:07 | 告警触发,IC呼叫 |
| 14:12 | 回滚启动 |
| 14:15 | 服务恢复 |
## 根本原因
[技术解释 — 什么实际上坏了,为什么]
## 促成因素
- [因素1 — 例如,迁移没有用生产数据量进行测试]
- [因素2 — 例如,金丝雀部署没有为这个服务配置]
## 进展顺利
- [快速检测 — 告警在2分钟内触发]
- [清晰的运行手册 — IC知道回滚程序]
## 进展不顺利
- [没有金丝雀 — 直接到100%部署]
- [迁移不向后兼容]
## 行动项目
| 行动 | 所有者 | 截止日期 | 优先级 |
|--------|-------|-----|----------|
| 添加金丝雀到部署 | @engineer | YYYY-MM-DD | P1 |
| 添加迁移向后兼容检查 | @engineer | YYYY-MM-DD | P1 |
| 更新此服务的运行手册 | @sre | YYYY-MM-DD | P2 |
## 经验教训
[团队的关键收获]
在职最佳实践
on_call:
rotation: weekly
handoff: Monday 10:00 (与前一个重叠1小时)
escalation:
- primary: 15分钟内响应
- secondary: 如果15分钟内没有确认,则自动呼叫
- manager: 如果30分钟内没有确认,则自动呼叫
expectations:
- 随身携带笔记本电脑+互联网
- 在15分钟内响应呼叫
- 首先遵循运行手册,其次即兴发挥
- 早期升级 — "我不知道"可以
- 在活跃事件期间每15分钟更新一次事件频道
wellness:
- 4周内不超过1周在职
- 在重大事件后补偿时间
- 劳作预算:<30%的在职时间应用于劳作
- 季度审查:我们是否呼叫太多?
第九阶段:安全强化
安全检查表(CI管道)
security_gates:
# 提交前
- tool: gitleaks / trufflehog
what: 代码中的秘密检测
block: true
# 构建
- tool: semgrep / CodeQL
what: 静态分析(SAST)
block: 严重发现
- tool: npm audit / pip audit / cargo audit
what: 依赖项漏洞(SCA)
block: 严重/高
# 容器
- tool: trivy / grype
what: 镜像漏洞扫描
block: 严重
- tool: hadolint
what: Dockerfile最佳实践
block: 错误级别
# 部署
- tool: checkov / tfsec
what: IaC安全扫描
block: 高发现
# 运行时
- tool: falco / sysdig
what: 运行时异常检测
alert: true
机密管理决策
| 方法 | 安全性 | 复杂性 | 最适合 |
|---|---|---|---|
| CI/CD环境变量 | 基础 | 低 | 小型团队,非关键 |
| AWS Secrets Manager / GCP Secret Manager | 高 | 中等 | 云原生应用 |
| HashiCorp Vault | 非常高 | 高 | 多云,严格合规 |
| SOPS + git | 好 | 低 | GitOps工作流 |
| External Secrets Operator | 高 | 中等 | Kubernetes + 云机密 |
规则:
- 至少每90天旋转机密
- 每个环境不同的机密(开发≠测试≠生产)
- 审计所有机密访问
- 永远不要记录机密 — CI输出中遮蔽
- 尽可能使用OIDC/无密钥身份验证(无长期令牌)
网络安全基线
1. 默认拒绝所有 — 明确允许所需的
2. 到处使用TLS — 包括内部服务到服务
3. 内部服务没有公共IP — 使用负载均衡器/API网关
4. 公共端点上的WAF — 至少OWASP前10条规则
5. 所有API的速率限制 — 防止滥用和DDoS
6. DNS服务发现 — 永远不要硬编码IP
7. VPN或零信任用于管理访问 — 没有从互联网SSH
8. K8s中的网络策略 — pod不能与所有内容通信
9. 服务的出站控制 — 服务只能到达它们需要的
10. 证书自动续订 — cert-manager或ACM
第十阶段:SRE实践
SLO框架
# 为每个面向用户的服务定义SLO
service: checkout-api
slos:
availability:
target: 99.95% # 每年4.38小时停机时间
window: 30d滚动
measurement: "successful_requests / total_requests"
latency:
target: 99% # 99%的请求低于阈值
threshold: 500ms # p99 < 500ms
window: 30d滚动
freshness:
target: 99.9% # 数据在SLA内更新
threshold: 5m
window: 30d滚动
error_budget:
monthly_budget: 0.05% # ~21.6分钟
burn_rate_alert:
fast: 14.4x # 1小时内预算消耗完毕 → 呼叫
slow: 3x # 10小时内预算消耗完毕 → 工单
policy:
budget_exhausted:
- 冻结非关键部署
- 将工程努力转移到可靠性
- 在每周SRE同步中审查
减少劳作
劳作 = 手动的,重复的,可自动化的,反应性的,没有持久价值
跟踪劳作:
- 记录2周的手动干预
- 分类:部署,缩放,证书续订,数据修复,权限
- 优先级:频率×时间×挫折感
目标:<30%的工程时间用于劳作
如果劳作>50%:停止功能工作,自动化前3个劳作项目
常见的劳作自动化:
手动部署 → CI/CD管道
证书续订 → cert-manager / ACM
上下扩展 → HPA / 自动缩放组
权限请求 → 自助服务IAM与批准
数据修复 → 管理API/脚本
依赖项更新 → Renovate / Dependabot
不稳定测试管理 → 自动隔离+工单
容量规划
capacity_review:
frequency: monthly
inputs:
- current_utilization: "CPU, memory, disk, network per service"
- growth_rate: "request rate trend over 90 days"
- planned_events: "launches, marketing campaigns, seasonal peaks"
- headroom_target: 30% # 不要超过70%的持续运行
formula:
needed_capacity: "current_usage × (1 + growth_rate) × (1 + headroom)"
lead_time: "14天用于云,60+天用于硬件"
actions:
- "如果利用率>70%:在2周内计划缩放"
- "如果利用率>85%:立即紧急缩放"
- "如果利用率<30%:缩减(节省资金)"
第十一阶段:成本优化
云成本规则
1. 首先正确尺寸 — 大多数实例都过度配置
检查:实际CPU/内存使用量与配置(CloudWatch, Datadog)
行动:缩小到下一个保持70%余量的层级
2. 为基线保留容量 — 突发/抢占性用于突发
模式:60%保留+30%按需+10%抢占
节省:保留与按需相比节省40-70%
3. 尽可能自动缩放到零
- 开发/测试环境:在夜晚+周末缩小
- 无服务器用于突发工作负载(Lambda, Cloud Functions)
4. 每月删除僵尸资源
- 未附加的EBS卷
- 旧的快照(>90天,没有标记为保留)
- 未使用的负载均衡器
- 孤儿弹性IP
5. 存储分层
- 热:SSD(频繁访问)
- 暖:HDD(每月访问)
- 冷:S3 Glacier / 存档(每年访问)
- S3桶上的自动生命周期策略
6. 标记一切 — 未标记=未跟踪=浪费
必需标签:环境,团队,服务,成本中心
每周报告:按标签成本,突出未标记资源
每月成本审查模板
## 云成本审查 — [月份 YYYY]
### 摘要
- 总支出:$X,XXX(与预算相比:$X,XXX)
- 月度变化:+X%($XXX)
- 前3大成本驱动因素:[service1, service2, service3]
### 按服务
| 服务 | 成本 | 总成本% | 月度变化 | 行动 |
|---------|------|-----------|------------|--------|
| EKS | $XXX | XX% | +X% | 正确尺寸节点组 |
| RDS | $XXX | XX% | 0% | 考虑保留 |
| S3 | $XXX | XX% | +X% | 添加生命周期规则 |
### 本月采取的优化行动
- [行动1]:每月节省$XXX
- [行动2]:每月节省$XXX
### 下个月行动
- [ ] [行动与估计节省]
DevOps成熟度评估
评估你的团队(每个维度1-5分):
| 维度 | 1(临时) | 3(定义) | 5(优化) |
|---|---|---|---|
| CI/CD | 手动部署 | 自动化管道,手动门 | 全自动带金丝雀,<15分钟到生产 |
| IaC | 点击操作控制台 | 一些Terraform,手动调整 | 100% IaC,GitOps,漂移检测 |
| 监控 | 破坏时检查 | 仪表板+基本警报 | SLOs,错误预算,自动补救 |
| 事件 | 恐慌+SSH | 运行手册,在职轮换 | 无责任事后分析,混沌工程 |
| 安全 | 年度审计 | CI扫描,机密管理器 | 左移,运行时检测,零信任 |
| 成本 | 意外账单 | 月度审查,一些保留 | 实时跟踪,自动优化 |
得分解释:
- 6-12: 需要基础 — 专注于CI/CD和基本监控
- 13-20: 成长中 — 添加IaC和事件流程
- 21-26: 成熟 — 通过SRE实践和成本管理进行优化
- 27-30: 精英 — 专注于混沌工程和开发者体验