Docker 和 K8s 到底在解决什么问题

这篇是给“我知道这两个名词,但其实并没有真正理解”的状态准备的。

如果你现在的感觉是:

  • Docker、K8s 我都听过
  • 但问深一点我就会乱
  • 不知道怎么把这些名词讲成一条线

那就用这篇来补。

这篇的目标不是把你变成平台专家,而是让你达到:

  • 能听懂这套体系在解决什么问题
  • 能在面试里讲清主要原理
  • 能把它挂回真实项目和工程价值

一、先把最核心的一句话记住

Docker 解决的是应用标准化交付,K8s 解决的是大量容器实例的集群治理。

如果只能记一句,就记这句。


二、为什么会先有 Docker,再有 K8s

1. 最早的痛点不是什么

最早的痛点不是:

  • 程序写不出来

而是:

  • 环境不一致
  • 部署方式不统一
  • 应用依赖太复杂
  • 机器一多,发布和回滚就很痛苦

所以第一阶段大家最需要解决的是:

应用怎么被标准化交付。

这就是 Docker 的舞台。

2. Docker 把什么先解决了

Docker 先把这几个问题做了标准化:

  • 应用和依赖怎么打包
  • 程序怎么启动
  • 环境怎样尽量一致
  • 服务怎样用统一方式交付

所以在 Docker 这一层,你更关心的是:

  • 镜像
  • 容器
  • Dockerfile
  • 镜像仓库

3. 为什么后来还不够

当服务越来越多时,新的问题又出现了:

  • 不是一个服务,而是几十个服务
  • 不是一个实例,而是很多副本
  • 不是一台机器,而是一个集群
  • 发布、回滚、探针、扩缩容都要自动化

这时候问题已经从“怎么交付一个应用”,升级成:

怎么治理很多服务和很多实例。

这就是 K8s 的舞台。


三、Docker 到底在解决什么

1. Docker 的本质

Docker 的本质不是某个命令,而是一套标准化交付方式。

它的价值在于:

  • 把应用和依赖打包成镜像
  • 用容器作为运行实例
  • 让程序在不同环境里尽量保持一致

2. 为什么镜像和容器一定要分清

  • 镜像:静态模板
  • 容器:运行实例

这个区分很重要,因为工程上很多动作落在不同层:

  • 构建镜像
  • 推送镜像
  • 拉取镜像
  • 启动容器
  • 删除容器

3. Dockerfile 为什么是核心

因为 Dockerfile 决定的是:

  • 这个应用如何被构建
  • 基础环境是什么
  • 依赖怎么装
  • 启动命令是什么

所以 Dockerfile 本质是在定义:

应用如何被标准化打包。

4. 底层靠什么做到容器化

最少要知道三个词:

  • namespace
  • cgroup
  • union filesystem

更通俗一点:

  • namespace:让容器看起来像彼此隔离
  • cgroup:让容器资源使用可控
  • union filesystem:支持镜像分层

所以容器不是魔法,本质上还是 Linux 提供的能力。


四、为什么说 Docker 解决的是“交付”,不是“治理”

这点很关键。

你有了 Docker 之后,可以比较容易地做到:

  • 同一套方式打包服务
  • 同一套方式启动服务
  • 部署更标准化

但 Docker 不会天然帮你解决:

  • 多副本怎么保持数量
  • 服务挂了谁补起来
  • 流量怎么转发给多个实例
  • 发布怎么滚动进行
  • 出问题怎么回滚
  • 集群资源怎么调度

所以它更像:

  • 把每个服务先变成标准零件

但零件多了以后,还是缺一个“总调度系统”。


五、K8s 到底在解决什么

1. K8s 的核心不是“起容器”

K8s 真正的重点是:

  • 调度
  • 编排
  • 发布
  • 服务发现
  • 故障恢复
  • 扩缩容
  • 配置管理

所以它更像:

  • 集群里的操作系统
  • 或者大规模容器应用的治理系统

2. K8s 最核心的思想

这句一定要讲顺:

你告诉它想要什么状态,它持续把实际状态往期望状态拉齐。

比如你说:

  • 我要 3 个副本
  • 镜像版本是 v2
  • 探针通过后才能接流量

K8s 就会一直去维持这个目标,而不是执行一次命令就不管了。

这就是它和“单纯运行容器”的根本区别。


六、K8s 为什么要拆成这么多对象

这是很多新手最困惑的点。

为什么不能一个对象全管?

因为现实问题本来就分层。

1. Pod

解决的是:

  • 最小运行单元怎么定义

为什么不是直接一个容器?

因为有时一个业务单元需要:

  • 主容器
  • sidecar
  • 代理
  • 日志采集容器

所以 Pod 代表的是:

  • 协同运行单元

2. Deployment

解决的是:

  • 我要多少副本
  • 用哪个版本
  • 怎么滚动更新
  • 出问题怎么回滚

3. Service

解决的是:

  • Pod IP 不稳定怎么办
  • 服务之间怎么稳定访问

4. Ingress

解决的是:

  • 外部流量怎么进来
  • 域名和路径怎么路由
  • TLS 怎么统一管理

5. ConfigMap / Secret

解决的是:

  • 配置不能写死进镜像
  • 敏感信息要和普通配置分开

6. Namespace

解决的是:

  • 集群里的逻辑隔离

所以这些对象不是“平台爱搞复杂”,而是:

不同问题本来就需要不同职责对象。


七、readiness、liveness、扩缩容这些为什么老被问

因为这些体现的是:

  • 你到底理解没理解“治理”两个字

1. readiness

回答的是:

  • 现在能不能接流量

2. liveness

回答的是:

  • 这个实例是不是已经坏了,需要被拉起

3. 为什么它们这么重要

因为服务“活着”和“能接流量”不是一回事。

很多系统启动了,但:

  • 还没预热完
  • 下游连接还没建好
  • 缓存还没准备好

这时如果直接接流量,就容易出问题。

4. 扩缩容为什么也老被问

因为扩容不是简单加机器,而是:

  • 指标是否可信
  • 下游会不会成为瓶颈
  • 服务是否无状态
  • 限流和熔断有没有配好

所以扩缩容本质上也是系统治理。


八、从代码到线上 Pod,到底发生了什么

这条链你要会讲。

典型链路

  1. 开发写代码
  2. Dockerfile 构建镜像
  3. 镜像推到仓库
  4. 发布系统更新 Deployment 的镜像版本
  5. apiserver 接收变更
  6. controller-manager 发现期望状态变化
  7. scheduler 选择节点
  8. kubelet 在节点上拉镜像并启动 Pod
  9. 探针通过后才开始接流量
  10. Service / Ingress 把流量导过去
  11. 如果异常,再走回滚

如果你能把这条线讲顺,面试官会明显感觉你不是在背散点知识。


九、如果你不是平台 owner,面试怎么答才真实又不虚

你完全没必要把自己讲成:

  • K8s 平台深度 owner

那样很容易被追穿。

更稳的说法是:

我不是平台侧最深的 owner,但我理解 Docker 解决的是应用标准化交付,K8s 解决的是多服务、多副本、多环境下的部署治理。我能讲清镜像、容器、Pod、Deployment、Service、Ingress、探针、扩缩容这些对象分别在解决什么问题,也知道它们最终是为稳定发布、回滚、资源治理和服务发现服务的。

这样既真实,也足够过大多数面试。


十、最容易踩的 5 个坑

1. 把 Docker 和 K8s 当成一个东西

不对。

一个偏交付,一个偏治理。

2. 把 Pod 直接当容器

不对。

Pod 是调度单元,容器是运行组件。

3. 觉得探针只是“配个接口”

不对。

探针直接影响:

  • 流量是否进来
  • 故障实例是否重启
  • 发布是否稳定

4. 以为扩 Pod 一定能扛住流量

不对。

如果瓶颈在数据库、第三方接口、锁竞争、单点热点,扩 Pod 也没用。

5. 觉得“我不会平台,所以这块没法答”

也不对。

你不一定要会搭集群,但必须知道它们在解决什么问题。


十一、30 秒版怎么答

Docker 解决的是应用标准化交付,把代码、依赖和启动方式打包成镜像,再以容器运行;K8s 解决的是这些容器在集群里的调度、发布、服务发现、故障恢复和扩缩容。所以一个偏交付,一个偏治理。

十二、1 分钟版怎么答

我会把 Docker 和 K8s 分成两层理解。Docker 主要解决镜像、容器、Dockerfile、环境一致性这些问题,核心是把应用交付标准化;K8s 进一步解决多服务、多副本、多环境下的治理问题,比如 Pod、Deployment、Service、Ingress、探针、扩缩容和回滚。它的核心思想是声明式配置和持续收敛,也就是你告诉系统想要什么状态,它持续把实际状态往目标状态拉齐。

十三、3 分钟版怎么答

我理解 Docker 和 K8s 不是一回事,而是两层不同的问题。Docker 解决的是单个应用怎么被标准化交付,它通过镜像、容器、Dockerfile 和镜像仓库,把应用、依赖和启动方式收敛成统一运行单元,底层依赖 namespace、cgroup 和分层文件系统来实现隔离和资源控制。这样能解决环境不一致、部署方式不统一的问题。

但服务一多,就会遇到副本管理、服务发现、滚动发布、故障恢复、配置管理、扩缩容这些问题,这时候 Docker 还不够,K8s 才真正上场。K8s 的核心不是帮你起容器,而是用声明式管理和持续收敛的方式,把 Pod、Deployment、Service、Ingress、ConfigMap、Secret、探针、调度和控制器这些能力组织起来,持续维持你声明的目标状态。

如果结合项目来讲,我会把重点落在它们带来的工程价值上:交付更标准、发布回滚更稳定、服务发现更清晰、资源治理更可控。即使我不是平台侧最深的 owner,这样讲也足够体现我理解它们到底在解决什么问题。