云原生应用
00:00
云原生应用设计、12-Factor方法论、容器化最佳实践、Kubernetes编排、服务网格集成、GitOps工作流。
1. 云原生定义与演进
1.1 CNCF 定义
云原生技术赋能组织在公有云、私有云和混合云等动态环境中构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、不可变基础设施和声明式 API。
云原生技术栈全景:
┌──────────────────────────────────────────────────────────┐
│ 应用层 │
│ Serverless / Batch / Streaming / ML Pipeline │
├──────────────────────────────────────────────────────────┤
│ 平台层 │
│ Kubernetes / Service Mesh / CI-CD / Observability │
├──────────────────────────────────────────────────────────┤
│ 基础设施层 │
│ Container Runtime / IaC / Cloud Provider APIs │
└──────────────────────────────────────────────────────────┘
1.2 云原生成熟度模型
| 阶段 | 描述 | 关键特征 |
|---|---|---|
| Level 0 | 传统部署 | 手动部署,无容器化 |
| Level 1 | 容器化 | 应用容器化,手动编排 |
| Level 2 | 编排化 | K8s 部署,自动伸缩 |
| Level 3 | 声明式 | GitOps,IaC,自动配置 |
| Level 4 | 自服务 | 平台工程,开发者门户 |
| Level 5 | 智能化 | AIOps,自适应优化 |
2. 12-Factor 方法论
2.1 十二因素详解
| # | 因素 | 核心原则 | 云原生实践 |
|---|---|---|---|
| 1 | 代码库 | 一份代码库,多次部署 | 单仓库 / 多仓库 + 共享库 |
| 2 | 依赖 | 显式声明并隔离依赖 | Dockerfile、go.mod、package.json |
| 3 | 配置 | 在环境中存储配置 | ConfigMap、Secret、环境变量 |
| 4 | 后端服务 | 将后端服务当作附加资源 | Service Binding、CSI |
| 5 | 构建/发布/运行 | 严格分离构建和运行 | CI → 镜像仓库 → CD |
| 6 | 进程 | 无状态进程 | 无状态 Pod + 外部状态存储 |
| 7 | 端口绑定 | 通过端口绑定提供服务 | Service + Ingress |
| 8 | 并发 | 通过进程模型扩展 | HPA + Pod 水平扩展 |
| 9 | 易处理 | 快速启动和优雅终止 | 健康检查 + 优雅关闭 |
| 10 | 开发/生产一致 | 尽可能保持一致 | 容器镜像统一环境 |
| 11 | 日志 | 将日志视为事件流 | stdout → Fluentd → ES |
| 12 | 管理进程 | 一次性管理进程 | Job / CronJob |
2.2 扩展因素(15-Factor)
在 12-Factor 基础上的扩展:
- 13. API First:API 优先设计,契约驱动开发
- 14. Telemetry:可观测性内置,指标/日志/追踪三合一
- 15. Security:安全左移,SBOM、漏洞扫描、签名验证
3. 容器化最佳实践
3.1 镜像优化
多阶段构建:
# 构建阶段
FROM golang:1.22 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o server .
# 运行阶段
FROM gcr.io/distroless/static:nonroot
COPY --from=builder /app/server /server
USER nonroot:nonroot
ENTRYPOINT ["/server"]
镜像大小优化策略:
| 策略 | 效果 | 示例 |
|---|---|---|
| 使用精简基础镜像 | 减少 80-90% | alpine、distroless、scratch |
| 多阶段构建 | 仅保留运行时产物 | 编译型语言必用 |
| 合并层 | 减少层数 | && 合并 RUN 指令 |
| .dockerignore | 排除无关文件 | 排除 .git、node_modules |
| 镜像压缩 | 减小传输大小 | docker-slim、crane |
3.2 安全最佳实践
- 非 root 运行:
USER nonroot:nonroot - 只读文件系统:
readOnlyRootFilesystem: true - 最小权限:仅安装必要包,删除包管理器缓存
- 镜像签名:Cosign / Notary 签名验证
- 漏洞扫描:Trivy / Grype 集成 CI
- SBOM:生成软件物料清单
3.3 健康检查
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 10
三种探针的区别:
| 探针 | 用途 | 失败后果 |
|---|---|---|
| livenessProbe | 检测死锁/无响应 | 重启容器 |
| readinessProbe | 检测是否可接收流量 | 从 Service 移除 |
| startupProbe | 检测启动是否完成 | 在成功前阻止其他探针 |
4. Kubernetes 编排进阶
4.1 工作负载管理
| 资源 | 用途 | 特点 |
|---|---|---|
| Deployment | 无状态应用 | 滚动更新、回滚 |
| StatefulSet | 有状态应用 | 稳定网络标识、有序部署 |
| DaemonSet | 节点守护进程 | 每节点一个 Pod |
| Job | 一次性任务 | 完成即退出 |
| CronJob | 定时任务 | Cron 表达式调度 |
4.2 调度策略
节点选择器与亲和性:
# 节点选择器(简单)
nodeSelector:
disktype: ssd
# 节点亲和性(高级)
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values: [us-east-1a, us-east-1b]
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
preference:
matchExpressions:
- key: node.kubernetes.io/instance-type
operator: In
values: [m6i.large, m6i.xlarge]
# Pod 反亲和性(分散部署)
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: my-service
topologyKey: kubernetes.io/hostname
4.3 资源管理
请求与限制:
resources:
requests: # 调度依据,保证最低资源
cpu: '250m' # 0.25 核
memory: '256Mi'
limits: # 硬上限,超限 OOMKill 或 Throttle
cpu: '500m' # 0.5 核
memory: '512Mi'
CPU Throttle 原理:容器在 100ms 周期内使用完 CPU 配额后会被限流:
QoS 等级:
| QoS | 条件 | 驱逐优先级 |
|---|---|---|
| Guaranteed | requests == limits(CPU+内存) | 最后被驱逐 |
| Burstable | requests < limits | 中等 |
| BestEffort | 无 requests/limits | 最先被驱逐 |
4.4 自动伸缩
HPA(水平 Pod 伸缩):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
spec:
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: '1000'
伸缩算法:
VPA(垂直 Pod 伸缩):自动调整 Pod 的 CPU/内存请求和限制。
Cluster Autoscaler:根据 Pod 调度失败自动增减节点。
5. GitOps 工作流
5.1 GitOps 核心原则
- 声明式:系统所有配置声明式描述
- 版本控制:所有声明存储在 Git 中
- 自动拉取:系统自动从 Git 拉取期望状态
- 持续协调:软件代理持续对比实际状态与期望状态
5.2 GitOps 工具对比
| 工具 | 推模型 | 拉模型 | 多集群 | 生态 |
|---|---|---|---|---|
| ArgoCD | CNCF Graduated | |||
| Flux | CNCF Graduated | |||
| Rancher Fleet | SUSE 生态 |
5.3 ArgoCD 工作流
开发者推送代码 → CI 构建镜像 → 更新 Git 仓库中的镜像标签
│
▼
ArgoCD 检测到 Git 变更 → 生成 Diff → 自动/手动同步 → K8s 应用更新
│
▼
ArgoCD 持续对比 Git 状态与集群状态 → 检测漂移 → 自动修正
Application 清单:
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
project: default
source:
repoURL: https://github.com/org/k8s-manifests
targetRevision: main
path: overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
6. 云原生可观测性
6.1 三大支柱
┌──────────────────────────────────────────────────┐
│ 可观测性 │
├────────────┬──────────────┬──────────────────────┤
│ 指标 │ 日志 │ 追踪 │
│ (Metrics) │ (Logs) │ (Traces) │
├────────────┼──────────────┼──────────────────────┤
│ Prometheus │ Fluentd │ OpenTelemetry │
│ Grafana │ Loki │ Jaeger │
│ Datadog │ Elasticsearch│ Tempo │
└────────────┴──────────────┴──────────────────────┘
6.2 OpenTelemetry 统一标准
OpenTelemetry 统一了指标、日志和追踪的采集与传输:
应用代码 → OTel SDK → OTel Collector → 后端(Prometheus/Jaeger/Loki)
│
├── Trace(W3C Trace Context)
├── Metrics(OTLP)
└── Logs(OTLP)
W3C Trace Context 传播:
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
│ │ │ │ │
版本 trace-id span-id 采样标志
6.3 SLO/SLI/SLA
| 概念 | 含义 | 示例 |
|---|---|---|
| SLA | 服务等级协议(商业合同) | 99.9% 可用性,违约退款 |
| SLO | 服务等级目标(内部目标) | 99.95% 可用性 |
| SLI | 服务等级指标(度量值) | 成功请求 / 总请求 |
错误预算:
| SLO | 月度允许宕机 | 年度允许宕机 |
|---|---|---|
| 99.9% | 43.8 分钟 | 8.76 小时 |
| 99.95% | 21.9 分钟 | 4.38 小时 |
| 99.99% | 4.38 分钟 | 52.6 分钟 |
| 99.999% | 26 秒 | 5.26 分钟 |