从 Docker 到 Kubernetes:一张图看懂云原生编排(附最小示例)

会 Docker 的人很多,但"为什么需要 Kubernetes"能讲清楚的不多。这篇文章用最直观的方式,讲明白容器和编排的关系,以及 K8s 到底解决了什么问题。

一、背景:Docker 解决了什么,又留下了什么

Docker 把应用和依赖打包成镜像,解决了"在我机器上能跑"的难题。但当你需要:

  • 跑 10 个实例扛流量
  • 某台机器挂了自动恢复
  • 滚动升级不停机
  • 根据负载自动扩缩容

Docker 单机版就无能为力了——这就是容器编排要解决的问题,而 Kubernetes 是事实标准。

二、核心原理:期望状态 vs 实际状态

K8s 最核心的思想是声明式管理:你告诉它"我要 3 个副本",它负责让实际状态永远等于期望状态。

期望状态: 3 个副本,镜像 v1.2
    ↓(控制器持续对账)
实际状态: 3 个副本运行中 ✅
(某副本挂了 → 控制器自动拉起新的,保持 3 个)

这个"对账循环"(Reconcile Loop)是 K8s 的灵魂——所有控制器(Deployment、Service 等)都基于这个模式。

三、代码实战:最小对账循环模拟

import numpy as np

class ReconcileController:
    def __init__(self, desired=3):
        self.desired = desired          # 期望状态
        self.actual = 0                 # 实际状态
    
    def reconcile(self):
        """对账:让实际状态收敛到期望状态"""
        if self.actual < self.desired:
            diff = self.desired - self.actual
            self.actual += min(diff, 2)  # 每轮最多拉起 2 个
        elif self.actual > self.desired:
            self.actual -= 1             # 过多则缩容
        return self.actual

# 模拟:启动、故障、恢复
ctrl = ReconcileController(desired=3)
print("初始:", ctrl.reconcile(), ctrl.reconcile(), "→ 收敛到 3")
ctrl.actual = 1   # 模拟节点故障,2 个副本挂了
print("故障后第1轮:", ctrl.reconcile())
print("故障后第2轮:", ctrl.reconcile(), "→ 自动恢复")

输出演示了 K8s 控制器的核心行为:无论实际状态如何偏离,控制器总会把它拉回期望状态

四、关键经验(避坑)

  1. 先理解 Pod 再碰 YAML:Pod 是最小调度单位,不是容器
  2. 不要手工操作:用 kubectl apply -f 声明式管理,别用命令式硬改
  3. 探针必配:liveness(存活)+ readiness(就绪)探针是稳定性的底线
  4. 资源限制必设:不设 requests/limits 的 Pod 是生产事故的种子
  5. 本地学习用 K3s:轻量发行版,几分钟装好,适合练习

五、完整系列推荐

本文选自《云原生实战:从容器到 Kubernetes》100 期系统教程,覆盖容器原理、K8s 核心、Service Mesh、可观测性、云原生存储、GitOps、Serverless、AI 云原生,每期配可运行 Python 仿真。

该系列及 65+ 技术知识库已在 ima 知识号发布,搜索「Kruptos」即可订阅。

8 款 AI 技能已上线 ima 技能广场,搜索即装。


作者:Kruptos(西电毕业,13 年无线通信/DSP/嵌入式科研,现深耕 AI 与云原生)
原创内容,转载注明出处。

更多推荐