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,到底发生了什么
这条链你要会讲。
典型链路
- 开发写代码
- Dockerfile 构建镜像
- 镜像推到仓库
- 发布系统更新 Deployment 的镜像版本
- apiserver 接收变更
- controller-manager 发现期望状态变化
- scheduler 选择节点
- kubelet 在节点上拉镜像并启动 Pod
- 探针通过后才开始接流量
- Service / Ingress 把流量导过去
- 如果异常,再走回滚
如果你能把这条线讲顺,面试官会明显感觉你不是在背散点知识。
九、如果你不是平台 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,这样讲也足够体现我理解它们到底在解决什么问题。