docker compose和k8s deployment文件
很多从 Docker 转型 K8s 的工程师,一上来最容易踩的坑就是试图用写 Docker Compose 的思路去写 K8s YAML。
它们之所以看起来大不相同,是因为 Docker Compose 是“面向容器(命令式)”的,而 Kubernetes 是“面向终态(声明式架构)”的。K8s 为了在生产环境中实现高可用、故障自愈和无缝滚动更新,把原本拧在同一个容器身上的职责,拆分成了多个不同层级的“乐高积木”。
我们把你的 Docker Compose 和 K8s Deployment 拆开来对比,你就能瞬间秒懂 K8s 为什么要这么设计,这也是面试时彰显架构深度的绝对加分项:
# 1. 核心差异:Docker 管理的是“集装箱”,K8s 管理的是“蚕茧 (Pod)”
在你的 Docker Compose 里,一个 service 对应一个具体的容器实体。 但在 K8s 里,你找不到直接操作 Container 的地方。K8s 的基本调度单元叫 Pod。
- 为什么要多套一层 Pod?(面试高频) 因为在生产环境里,多个紧密相连的容器(比如“Hermes 网关”和“日志收集日志 Agent”)需要共享同一个网络 Namespace 和磁盘卷。Pod 就像一个蚕茧(或者说是虚拟的主机),里面可以塞入一个或多个物理容器,让它们天生可以通过
127.0.0.1互相通信。 - 体现在 YAML 里: 你会看到 K8s 的 YAML 嵌套很深,多了一层
template.spec.containers,这就是把容器包裹在 Pod 模板里的写法。
# 2. 架构差异:K8s 引入了“控制器模式(Deployment)”
在 Docker Compose 中,你配置 restart: unless-stopped 是让本地的 Docker 守护进程去死循环监控这个容器。 而 K8s 采用了更高级的声明式控制器(Deployment)。
- 体现在 YAML 里: 你会发现 K8s 多了
replicas: 1和selector.matchLabels。 - 底层原理: Deployment 并不直接管理 Pod,它通过 ReplicaSet(副本集) 控制器去死死盯着集群:“我的期望状态是带有
app: hermes-hr标签的 Pod 必须有 1 个。” 哪怕你在虚拟机node1上把容器删了,K8s 的 Controller Manager(大脑)发现“实际状态(0)不等于期望状态(1)”,就会立刻命令 Scheduler(调度器)在node2上重新捞一个 Pod 起来。这种自愈能力是 Docker Compose 根本不具备的。
# 3. 配置解耦:生产环境的“密码学与可复用性”
在 Docker Compose 示例中,我们贪图方便,把大模型 Key、URL 全部作为明文(Literal)硬编码在了 environment 标签下。 如果在生产环境中,你有 50 个微服务都要用这套小米模型的 Key,一旦 Key 变了,你得去改 50 个 Docker Compose 文件,这在生产环境是灾难性的。
K8s 的解耦艺术: K8s 在架构上推崇配置与代码分离。所以在 K8s YAML 里,你看到的不是明文的
value: sk-xxxx,而是:valueFrom: secretKeyRef: name: hermes-global-secret key: MIMO_API_KEY这行字的意思是:“去集群里找那个叫
hermes-global-secret的公共保险箱,把里面贴着MIMO_API_KEY标签的钥匙拿出来塞进容器里。” 这样做到了资产统一管理。以后改密码、换大模型,只需更新集群里的一个 Secret/ConfigMap 对象,那 50 个服务的拓扑文件(Deployment)连动都不用动!
# 4. 资源配额:生产环境的“防爆盾(Resources)”
你的 Docker Compose 默认没有对 CPU 和内存做强限制(或者只写了基础限制)。在生产 K8s 集群里,如果一个 Agent 出现内存泄漏,如果不加限制,它会疯狂吞噬整台虚拟机(宿主机)的资源,导致同台机器上的其他核心业务陪葬。
- 体现在 K8s YAML 里: 专门多出了
resources.requests和resources.limits。 - 面试加分内幕(QoS 级别):
requests(申请量):这是给 Scheduler(调度器) 调度的参考。调度器一看 Node1 还剩 1.5G 内存,而你的 Pod 申请了 1G(Requests),OK,Node1 放得下,调度过去!limits(限制量):这是给宿主机 Cgroups 设定的硬围墙。一旦这个容器内存真的冲到了 2G(Limits),系统的 OOM Killer 会毫不留情地把这个容器单杀掉,但绝对不会影响宿主机和其他 Pod。
# 💡 总结成一句话:
“Docker Compose 是单机时代的‘容器启动脚本’,把配置和资源拧在了一起;而 Kubernetes Deployment 是云原生时代的‘分布式状态机’,它通过 Pod 封装容器、通过控制器保障副本终态、通过 Secret/ConfigMap 实现配置解耦,并通过 Resources 确立多租户的资源边界。”
# 例子
假如我们有一个docker compose 文件,我们要如何转换成 deploy 文件呢?