6.8 KiB
6.8 KiB
tags, create time
| tags | create time | |||||
|---|---|---|---|---|---|---|
|
2026-05-18 00:30 |
K8s 核心概念与 Deployment — 教程
概述
本文档带你从零理解 Kubernetes 的核心对象模型,并掌握 Deployment 这个最常用的工作负载控制器。更多进阶主题(资源配置、服务发现、调度)分散在后续章节中。总览和决策矩阵见 ../02-Kubernetes。
K8s 架构全景
graph TB
subgraph CONTROL["控制面 Control Plane"]
APISERVER["API Server<br/>唯一入口"]
SCHEDULER["Scheduler<br/>调度决策"]
CMGR["Controller Manager<br/>状态协调"]
ETCD["etcd<br/>分布式 KV 存储"]
APISERVER --> SCHEDULER
APISERVER --> CMGR
APISERVER --> ETCD
CMGR --> ETCD
end
subgraph WORKER["工作节点 Worker Node"]
N1["Node A<br/>kubelet + kube-proxy"]
N2["Node B<br/>kubelet + kube-proxy"]
end
APISERVER -.->|监听变动| N1
APISERVER -.->|监听变动| N2
style CONTROL fill:#e3f2fd
style ETCD fill:#c8e6c9
style WORKER fill:#fff3e0
[!question] 为什么 K8s 需要这么多组件?
因为"声明式 API"的设计哲学——用户告诉 K8s 想要什么状态(比如"我要 3 个订单服务实例"),控制面负责让实际状态持续逼近目标状态。任何偏离都会被自动修复,这也就是自愈能力的来源。
核心对象速查表
| K8s 对象 | 用途 | 类比 |
|---|---|---|
| Pod | 最小部署单元,包含一个或多个容器 | 应用实例 |
| Deployment | 管理 Pod 的副本数和滚动更新 | 应用的"模板" |
| Service | 稳定的网络入口,负载均衡 | 内部 VIP → 03-网络与服务发现 |
| ConfigMap | 配置注入(明文) → 02-配置管理 | |
| Secret | 敏感配置注入(base64)→ 02-配置管理 | |
| HPA | 根据指标自动扩缩容 → 04-扩缩容与有状态应用 | |
| StatefulSet | 有状态应用的有序管理 → 04-扩缩容与有状态应用 | |
| NetworkPolicy | L3/L4 网络安全策略 → 06-资源与安全管控 |
Deployment 详解
完整示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
labels:
app: order
version: v1.2.3
spec:
replicas: 3 # 期望副本数
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最多超额 1 个 Pod
maxUnavailable: 0 # 滚动更新期间不允许不可用
selector:
matchLabels:
app: order
template: # Pod 模板
metadata:
labels:
app: order
version: v1.2.3
spec:
containers:
- name: order-service
image: registry.example.com/order:v1.2.3
ports:
- containerPort: 8080
# ========== 资源配置 ==========
resources:
requests: # 调度依据:保证至少有这些
cpu: "250m"
memory: "256Mi"
limits: # 硬上限:超过则 OOMKill/CPU Throttle
cpu: "500m"
memory: "512Mi"
# ========== 探针 ==========
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3 # 连续失败 3 次才重启
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30 # 最长等待 300s (慢启动友好)
# ========== 环境变量 & 挂载 ==========
envFrom:
- configMapRef:
name: order-service-config
- secretRef:
name: order-service-secrets
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 15"] # 优雅退出,给 LB 摘流时间
Probe 选择指南
| 探针类型 | 触发条件 | 动作 | 适用场景 |
|---|---|---|---|
| Liveness | /healthz 返回非 2xx |
重启容器 | 死锁、无法恢复的崩溃 |
| Readiness | /ready 返回非 2xx |
摘除 Service 流量 | 依赖未就绪、热加载中 |
| Startup | 首次成功前持续失败 | 不重启,只等待 | 大模型/JVM 冷启动 |
[!warning] 常见陷阱:Liveness 误杀导致 CrashLoopBackOff
如果 Liveness Probe 因为 DB 连接超时而返回 503,K8s 会认为容器挂了并反复重启它。正确做法:让
/healthz做降级判断(DB 不可用时返回 200),用/ready来摘除流量。
Deployment 更新策略
strategy:
type: RollingUpdate # 逐步替换旧 Pod
rollingUpdate:
maxSurge: 1 # 新 Pod 数量可以超出期望值 1
maxUnavailable: 0 # 更新时不允许有空缺
# 另一种策略:先全部新建再销毁旧的(零停机但需 2x 资源)
# type: Recreate # ❌ 全量替换,会有短暂不可用
[!tip] 如何安全地回滚 Deployment?
kubectl rollout undo deployment/order-service -n production # 回到上一版本 kubectl rollout undo deployment/order-service -n production --to-revision=3 # 回退到指定版本 kubectl rollout status deployment/order-service -n production # 查看进度 kubectl rollout history deployment/order-service -n production # 历史版本对比K8s 自动保留每次 Deployment 变更后的 PodTemplateSpec,因此回滚是瞬时的,不需要手动备份 YAML。
Pod 生命周期简述
stateDiagram-v2
[*] --> Pending: Pod 被创建
Pending --> ContainerCreating: 调度成功,拉取镜像
ContainerCreating --> Running: 容器就绪
Running --> Waiting: Probe 失败或手动暂停
Waiting --> Running: 探针恢复
Running --> Terminating: 删除/更新触发
Terminating --> (*): 完全终止
state Waiting {
CrashLoopBackOff
ImagePullBackOff
}
note right of CrashLoopBackOff: Liveness 连续失败\n或进程异常退出
note right of ImagePullBackOff: 镜像不存在或仓库认证失败
关联笔记
- ../02-配置管理 — ConfigMap / Secret 的配置注入
- ../03-网络与服务发现 — Service / Ingress 网络路由
- ../04-扩缩容与有状态应用 — HPA / StatefulSet
- ../hhs/MS/05-部署运维/01-容器化 — Docker 镜像是 Pod 的基础单元
- ../hhs/MS/05-部署运维/03-CICD与GitOps — GitOps ArgoCD 操作 K8s manifest