Kubernetes(K8s)是一个容器编排平台,用于自动化部署、扩缩容和管理容器化应用。
1、核心概念
| 概念 | 中文 | 角色 |
|---|---|---|
| Pod | 豆荚 | 最小调度单位,可含一个或多个共享网络/存储的容器 |
| Node | 节点 | 运行 Pod 的机器(物理机或虚拟机) |
| Deployment | 部署 | 声明应用的期望状态(副本数、镜像版本),K8s 自动维持 |
| Service | 服务 | 为一组 Pod 提供稳定的访问入口(Cluster IP + DNS + 负载均衡) |
| Namespace | 命名空间 | 实现多租户的资源隔离 |
2、各概念之间的关系
bash
用户声明期望状态(Deployment:3 个副本,镜像 v1)
↓
Deployment 创建并管理 Pod
↓
Pod 调度到 Node 上运行
↓
Service 为一组 Pod 提供统一稳定的访问入口
↓
Namespace 将以上资源按租户/项目隔离
核心思想
- 声明式管理:你只描述"想要什么"(如 3 个副本),K8s 负责让实际状态不断逼近期望状态------Pod 挂了自动重建,这就是自愈能力。
- 抽象分层:Pod 管"怎么跑",Service 管"怎么访问",Deployment 管"跑几个、什么版本",Namespace 管"谁可以用"。
3、Docker VS K8S
| Docker 概念 | Kubernetes 概念 | 说明 |
|---|---|---|
| Container | Pod | K8s 增加了一层 Pod 包装 |
| Volume | PersistentVolume | K8s 的存储更加抽象和强大 |
| Network | Service/Ingress | K8s 的网络模型更扁平 |
| Compose | Deployment + Service | 声明式配置的理念是一致的 |
4、节点Node
节点 = 干活的机器,Kubernetes = 指挥这些机器的大脑。
K8s 自己不创建节点,它只管"登记、检查、调度"。
4.1、三大件组件
- kubelet:节点上的"监工",接受调度指令、管 Pod
- 容器运行时:真正跑容器的(containerd / CRI-O,别再记 Docker)
- kube-proxy:管网络流量的
记忆口诀:调度找 kubelet,跑容器靠运行时,通网络用 proxy。
4.2、只看一个条件:Ready
节点状态有一堆 Conditions,但只需要盯住 Ready:
- Ready=True → 节点健康,可以干活
- Ready=Unknown → 心跳丢失,Pod 要被驱逐重调
4.3、别把节点状态和 Pod 状态搞混
- Pending/Running/Succeeded/Failed 这些是 Pod 的生命周期
- 节点用 Conditions(Ready/Pressure...) 描述
- 节点没有 Terminated 状态
4.4、两个必会命令
bash
kubectl cordon 节点 # 不再派新活来(不关存量)
kubectl drain 节点 # 把存量 Pod 也迁走
记住逻辑:先 cordon 关门,再 drain 清场,最后才能安全关机/升级节点。
5、容器组(Pod)
5.1、一句话理解 Pod
Pod = K8s 最小调度单位,是创建、调度、扩缩容的基本单元。
K8s 不直接调度单个容器,而是把一组紧密协作的容器打包成一个 Pod 来管理。
5.2、为什么要 Pod 设计
- 共享资源:同一 Pod 内的容器共享网络(相同 IP 和端口空间)和存储卷,像在一台机器上一样通信。
- 为什么不塞进一个容器跑多个程序:透明化(统一进程/资源管理)、解耦(可独立发布)、方便(不用自己管退出状态)、高效(容器保持轻量)
5.3、典型使用模式
一个 Pod 内可组合多个角色:主应用容器 + Sidecar(日志收集、监控代理、配置同步、数据加载、网桥代理等)。
5.4、存储:卷(Volumes)
- 卷不止用于持久化,还用于 emptyDir 临时交换、ConfigMap/Secret 投射、日志旁路收集
- 跨 Pod 生命周期要保留的数据,必须用 PV/PVC(持久卷机制)
5.5、生命周期:5 个 Phase
| 状态 | 含义 |
|---|---|
| Pending | 已接受但容器还没跑起来(可能在拉镜像) |
| Running | 已调度、容器已启动(至少一个在运行) |
| Succeeded | 所有容器正常退出 |
| Failed | 所有容器终止,且至少一个失败退出 |
| Unknown | 节点失联,集群拿不到状态(与节点 Unknown 对应) |
5.6、重启策略 restartPolicy
| 策略 | 正常退出 | 异常退出 |
|---|---|---|
| Always(默认) | 重启 | 重启 |
| OnFailure | 不重启 | 重启 |
| Never | 不重启 | 不重启 |
Deployment 里的 Pod 只允许 Always;OnFailure/Never 一般用于 Job/CronJob
5.7、故障自愈
- Pod 不直接创建,由 Deployment 等控制器管理 节
- 点故障 → Pod 先 Unknown → 驱逐/转 Failed → 控制器在其他节点自动重建
6、Deployment 与 ReplicaSet
Deployment = 无状态应用的"管家",它确保你指定的 Pod 副本数量始终在线,并负责平滑升级和快速回滚。
它自己不直接管 Pod,而是通过 ReplicaSet 间接管理。
6.1、分层关系
bash
Deployment → 管理 → ReplicaSet → 管理 → Pod → 运行容器
- ReplicaSet(RS):核心职责就一件事------保证副本数达标(少了补、多了删)
- Deployment:站在 RS 之上,提供滚动更新和回滚能力
6.2、Deployment 三大核心能力
| 能力 | 说明 |
|---|---|
| 副本管理 | 始终维持 replicas 个 Pod 运行(如配了 3 个,挂 1 个补 1 个) |
| 滚动更新 | 逐步用新版本 Pod 替换旧版本,零停机 |
| 回滚 | 新版本出问题,一键回到历史版本 |
6.3、关键字段
bash
spec:
replicas: 3 # 期望副本数
selector: # 匹配哪些 Pod 归我管(和 template.labels 必须一致)
template: # Pod 模板(Pod 长什么样在这里定义)
6.4、工作逻辑:一次版本更新发生了什么?
bash
你改镜像 → Deployment 创建新 ReplicaSet
→ 新 RS 逐步拉起新 Pod
→ 旧 RS 逐步缩掉旧 Pod
→ 全部替换完成,旧 RS 保留(用于回滚)
注意:回滚的本质就是重新扩容旧 ReplicaSet。
7、StatefulSet
StatefulSet = 有状态应用的"管家",它为每个 Pod 提供稳定的身份和专属的存储,适合数据库、消息队列这类"有记忆"的应用。
| Deployment | StatefulSet | |
|---|---|---|
| Pod 名称 | 随机哈希(nginx-7d9f8b2c5-x1a2b) | 固定编号(mysql-0, mysql-1, mysql-2) |
| 网络标识 | 变化 | 稳定(配合 Headless Service 有固定 DNS) |
| 存储 | 共享模板,Pod 与 PVC 不绑定 | 每个 Pod 独占一个 PVC(一对一绑定) |
| 创建/删除顺序 | 并发随机 | 按序创建、逆序删除 |
| 典型场景 | Web 服务、API | MySQL、Redis、Kafka、ZooKeeper |
7.1、三大核心特性
- 稳定的网络标识:Pod 按序号编号 + Headless Service → 每个 Pod 有可预测的 DNS 名(如 mysql-1.mysql),重启后名字和地址不变
- 有序部署与删除:先建 mysql-0,再建 mysql-1......删除时反过来(先删 2再删 0)------保证主从关系正确建立
- 持久化存储:volumeClaimTemplates(PVC 模板)为每个 Pod 自动创建独立 PVC,Pod 被重新调度后仍挂载回原来的数据
7.2、故障重建时的行为差异
bash
Deployment:Pod 死了 → 随便找个节点重建 → 名字变了、存储不管
StatefulSet:mysql-1 死了 → 重建的新 Pod 还叫 mysql-1
→ 还是挂载原来的 PVC → 数据不丢、身份不变
稳定身份 + 数据跟随 = 有状态应用能活下来的关键。
8、DaemonSet
DaemonSet = "每个节点跑一份"的控制器,它保证集群里每个节点(或指定节点)上恰好运行一个 Pod 副本。
8.1、典型场景(全部是"节点级基础设施")
| 场景 | 例子 |
|---|---|
| 日志收集 | Fluentd、Filebeat(收集每个节点的 /var/log) |
| 监控代理 | Node Exporter、Prometheus Agent、Datadog Agent |
| 网络插件 | Calico、Cilium、Flannel |
| 存储插件 | CSI 节点插件、cephfs 客户端 |
记忆口诀:"每个节点都需要一份的脏活累活,就交给 DaemonSet"。
8.2、与 Deployment 的关键差异
| Deployment | DaemonSet | |
|---|---|---|
| 调度目标 | 维护 N 个副本 | 每个节点 1 个 |
| 节点挂了 | 去其他节点重建 | Pod 随之消失,节点恢复后回来 |
| 典型应用 | Web 应用、API | 日志/监控/网络代理 |
9、Job 与 CronJob
Job = 跑完就下班的一次性任务,保证任务"成功完成 N 次"后自动收工;CronJob = 定时闹钟,按 cron 表达式周期性创建 Job。
9.1、为什么需要 Job?Deployment 不行吗?
Deployment 的 Pod 是"永远活着"的(restartPolicy 强制 Always);而任务型工作负载追求"完成即退出",需要用 restartPolicy: Never 或 OnFailure 的 Job 来跑。
9.2、Job 两个关键参数
| 参数 | 作用 |
|---|---|
| completions | 需要成功完成的 Pod 数量(默认 1) |
| backoffLimit | 失败重试次数上限(默认 6),超过则整个 Job 标记失败 |
9.3、CronJob:Job 的定时版
bash
spec:
schedule: "0 2 * * *" # 分 时 日 月 周 → 每天凌晨 2 点
jobTemplate:
# ... 和 Job 一样,套了一层壳
10、五大工作负载
| 控制器 | 一句话 | restartPolicy | 场景 |
|---|---|---|---|
| Deployment | 无状态应用,常驻 | Always | Web、API |
| StatefulSet | 有状态,稳定身份+专属存储 | Always | 数据库、MQ |
| DaemonSet | 每节点一个 | Always | 日志、监控、网络插件 |
| Job | 一次性任务,完成即退出 | Never / OnFailure | 数据迁移、批处理 |
| CronJob | 定时创建 Job | Never / OnFailure | 备份、报表、清理 |