04 - 大厂 K8s 最佳实践
阿里巴巴 / 蚂蚁集团
阿里是国内 K8s 实践最深入的公司之一,数万节点规模。
集群架构
- 多集群联邦:不把所有鸡蛋放一个篮子,按业务线/地域拆分集群
- 集群规模控制:单集群不超过 5000 节点(超过后 etcd 和 API Server 压力大)
- 控制面高可用:etcd 3~5 节点,API Server 多副本 + SLB
资源管理
yaml
# 阿里云实践:requests 设为实际使用的 P50,limits 设为 P99
resources:
requests:
cpu: "500m" # 正常负载
memory: "512Mi"
limits:
cpu: "2" # 峰值 4 倍
memory: "1Gi" # 峰值 2 倍- 资源画像:通过监控数据自动推荐 requests/limits(VPA 推荐模式)
- 成本分账:按命名空间统计资源使用,分摊成本到业务线
- 弹性伸缩:HPA + Cluster Autoscaler + 弹性节点池
发布策略
- 灰度发布:先发 1% 流量到新版本,观察指标,逐步放量
- 蓝绿部署:两套完整环境,切换流量
- A/B 测试:基于 Ingress header/cookie 路由不同版本
yaml
# Nginx Ingress 金丝雀发布
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10" # 10% 流量到新版
spec:
ingressClassName: nginx
rules:
- host: myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-v2
port:
number: 80Google / GKE
Google 是 K8s 的发源地(Borg → K8s),实践最为成熟。
SRE 理念
- SLO 驱动:定义 Service Level Objectives(如 99.9% 可用性),用 error budget 决定发布节奏
- Toil 消除:自动化一切可重复的运维操作
工作负载管理
yaml
# Google 推荐:每个 Pod 必须包含
# 1. Resource requests/limits
# 2. Liveness + readiness probes
# 3. PodDisruptionBudget
# 4. Anti-affinity(高可用)
# 5. SecurityContext
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 3
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0 # 零停机更新
template:
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
affinity:
podAntiAffinity: # 分散到不同节点
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: web
topologyKey: topology.kubernetes.io/zone # 跨可用区
topologySpreadConstraints: # 均匀分布
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: web
containers:
- name: app
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
memory: "512Mi"
# CPU limits 不设置(Google 推荐)
# 只设 requests,让 Pod 在空闲时可以超用多集群和多可用区
- 拓扑感知:
topologySpreadConstraints确保 Pod 均匀分布在可用区 - 多集群 Gateway API:跨集群流量管理
- Workload Identity:Pod 使用 GCP IAM 角色(类似 ACK 的 RRSA)
Netflix
Netflix 是云原生微服务的标杆。
微服务治理
- 单一代码库 → 单一镜像 → 单一 Deployment
- 每个微服务独立的 K8s namespace
- 严格的 API 契约和版本管理
弹性工程
yaml
# 核心理念:为失败而设计
# 1. 重试 + 超时 + 熔断
# 通过 Service Mesh (Envoy/Istio) 实现
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
spec:
http:
- route:
- destination:
host: recommendation-service
timeout: 3s
retries:
attempts: 3
perTryTimeout: 1s
retryOn: 5xx,reset,connect-failure
# 2. 优雅降级
# 服务不可用时返回缓存/默认值,而不是报错
# 3. 混沌工程(Chaos Engineering)
# 随机杀 Pod / 注入延迟 / 模拟故障
# 工具:Chaos Mesh、LitmusChaos观测体系
- Metrics: Prometheus + Atlas(Netflix 自研)
- Logging: ELK + 集中日志平台
- Tracing: 全链路追踪,请求 ID 贯穿所有服务
- Dashboard: 每个服务有标准化的 Grafana 仪表盘
字节跳动
超大规模集群
- 单集群 2 万+ 节点(通过定制 etcd 和 API Server)
- 自研调度器(优化 Pod 调度效率)
- 自研 CNI(高性能网络)
在离线混部
┌─────────────────────────────────────────┐
│ 同一节点上混合运行 │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 在线服务 │ │ 离线任务 │ │
│ │ (高优先级) │ │ (低优先级) │ │
│ │ Web/API │ │ 大数据/训练 │ │
│ │ 保证资源 │ │ 用空闲资源 │ │
│ └──────────────┘ └──────────────┘ │
│ │
│ 资源利用率: 20-30% → 60-70% │
└─────────────────────────────────────────┘实现方式:
- PriorityClass:区分在线和离线任务优先级
- Resource Quota:限制离线任务资源上限
- Preemption:在线任务资源不足时抢占离线任务
yaml
# 高优先级(在线服务)
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: online-high
value: 1000000
globalDefault: false
preemptionPolicy: PreemptLowerPriority
---
# 低优先级(离线任务)
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: offline-batch
value: 100
preemptionPolicy: Never
---
# 在线服务 Pod
spec:
priorityClassName: online-high
---
# 离线训练 Pod
spec:
priorityClassName: offline-batch通用大厂实践总结
1. 命名规范
yaml
# 命名空间
<team>-<env> # ml-team-prod, backend-staging
# Deployment
<app>-<component> # order-api, user-service
# Service
<app>-<component>-svc # order-api-svc
# ConfigMap/Secret
<app>-<type> # order-config, order-secrets
# 标签
app.kubernetes.io/name: order-api
app.kubernetes.io/version: "2.1.0"
app.kubernetes.io/component: api
app.kubernetes.io/part-of: order-system
team: backend
env: production2. GitOps 工作流
开发者 Push 代码
│
▼
CI Pipeline (GitHub Actions / Jenkins)
│ 构建镜像 → 推送到 ACR
│ 更新 K8s manifests (Helm values / Kustomize)
│
▼
Git 仓库 (manifests)
│
▼
ArgoCD / FluxCD (持续监听 Git 变更)
│
▼
自动同步到 K8s 集群
# ArgoCD 安装
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml核心原则:
- Git 是唯一的真相源(Single Source of Truth)
- 所有变更通过 Git PR 审核
- 禁止直接
kubectl apply(生产环境) - 自动化漂移检测和修复
3. 多环境管理(Kustomize)
base/
├── deployment.yaml
├── service.yaml
└── kustomization.yaml
overlays/
├── dev/
│ ├── kustomization.yaml # replicas: 1, 低资源
│ └── patch-resources.yaml
├── staging/
│ ├── kustomization.yaml # replicas: 2
│ └── patch-resources.yaml
└── prod/
├── kustomization.yaml # replicas: 5, 高资源
└── patch-resources.yamlyaml
# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namespace: production
patches:
- path: patch-resources.yaml
images:
- name: myapp
newTag: v2.1.0bash
# 应用
kubectl apply -k overlays/prod/4. Secret 管理
永远不要把 Secret 明文提交到 Git
| 方案 | 说明 | 复杂度 |
|---|---|---|
| Sealed Secrets | 加密后可以提交到 Git | 低 |
| External Secrets | 从外部系统同步(Vault/KMS) | 中 |
| HashiCorp Vault | 完整的密钥管理 | 高 |
| 阿里云 KMS | ACK 原生集成 | 中 |
yaml
# External Secrets 示例
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: aliyun-kms
kind: ClusterSecretStore
target:
name: db-secret
data:
- secretKey: password
remoteRef:
key: /prod/db/password5. 网络安全(零信任)
yaml
# 默认拒绝所有流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# 只开放必要的通信路径
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-to-db
spec:
podSelector:
matchLabels:
app: database
ingress:
- from:
- podSelector:
matchLabels:
app: api
ports:
- port: 54326. 成本优化矩阵
| 策略 | 节约比例 | 适用场景 |
|---|---|---|
| 正确设置 requests | 20-40% | 所有工作负载 |
| 使用抢占式/Spot 实例 | 60-90% | 批处理、训练、非关键服务 |
| Cluster Autoscaler | 30-50% | 波动型负载 |
| 在离线混部 | 30-50% | 同时有在线+离线负载 |
| 使用 ARM 实例 | 20-30% | 计算密集型 |
| Reserved Instance | 30-60% | 稳定运行的基础负载 |
大厂面试常问
| 问题 | 关键点 |
|---|---|
| K8s Pod 启动流程? | API Server → etcd → Scheduler → kubelet → Container Runtime |
| Service 如何实现负载均衡? | kube-proxy + iptables/IPVS |
| 如何实现零停机更新? | Rolling Update + readiness probe + PDB |
| 如何排查 Pod CrashLoopBackOff? | logs --previous → describe → events |
| HPA 扩容延迟怎么办? | 调低 stabilizationWindow,配合 KEDA |
| 如何保证集群高可用? | 多 AZ 部署 + PDB + 反亲和 + 自动修复 |
| etcd 数据丢失怎么办? | 定期快照备份 + 灾备恢复流程 |
| 微服务通信有几种方式? | REST/gRPC(同步) + MQ(异步) + Service Mesh(sidecar) |
