6727 字
34 分钟
从 Docker 到 Kubernetes:概念对照
2026-11-15

先说结论:你缺的不是技术,是翻译#

学 Docker 的人第一次打开 Kubernetes(以下简称 K8s)文档,普遍会有一种被背叛的感觉:镜像还是那个镜像,容器还是那个容器,可满屏的 Pod、Deployment、Service、Ingress、ConfigMap 全是生词,YAML 一写就是上百行,跑个最简单的应用比写业务代码还累。很多人卡在这里,不是因为 K8s 本身有多难,而是因为没人把新概念翻译回他们已经懂的语言。

这篇文章就是来做这件翻译工作的。主线很简单:

  1. 先泼一盆冷水,讲清 K8s 的真实定位和成本,帮你判断自己到底需不需要它;
  2. 用一张核心概念对照大表,把 K8s 的每个核心对象映射回 Docker 和 Compose 里的对应物;
  3. 拿一个完整的 Compose 例子,逐段翻译成 K8s 的 YAML,让你亲眼看到「同一件事的两种写法」;
  4. 给一份 kubectl 生存命令对照表、一条本地体验路线和一张选型判断表。

读完你不一定会立刻去搭集群,但至少再看 K8s 的文章和文档时,每个名词你都能在脑子里对上号。至于 Compose 本身的进阶用法(环境变量、健康检查、多环境),可以先看本系列的 Docker Compose 进阶,那是理解这篇的全部前置知识。

一、心态先行:K8s 不是更高级的 Docker#

最常见的误解,是把 K8s 理解成「Docker 的高级版」或者「更强的 Compose」。这个定位从一开始就错了:

K8s 不是更高级的 Docker,而是一套集群操作系统。Docker 解决的是「在一台机器上怎么把应用装进容器跑起来」,K8s 解决的是「在几十上百台机器组成的集群里,怎么调度、编排、自愈、扩缩这些容器」。两者的抽象层级完全不同:Docker 面对的是一台机器,K8s 面对的是一个机房。

这个区别决定了 K8s 的一切「繁琐」都有出处:

  • 你只有一台机器时,「容器挂了重启一下」是一句 restart: unless-stopped;在集群里,机器本身都可能整台宕机,应用必须能自动漂移到别的机器上,这就需要调度器、控制器、健康探针一整套机制;
  • 你只有一台机器时,服务发现就是「容器名当主机名」;在集群里,容器的 IP 天天变,必须有一层稳定的访问入口,这就是 Service 存在的理由;
  • 你只有一台机器时,配置就是 .env 文件;在集群里,配置要能统一下发、滚动更新、区分敏感与非敏感,于是有了 ConfigMap 和 Secret。

所以先把成本算清楚。单机个人项目上 K8s,成本清单大概是这样的:

成本项单机 Docker/Compose单机硬上 K8s
部署一个应用的配置量一个 compose 文件,几十行Deployment、Service、Ingress 等多个 YAML,上百行
集群本身的资源占用无额外开销控制平面组件常驻,先吃掉一部分 CPU 和内存
出问题时的排查链路看容器日志基本够了要分清是 Pod、节点、网络插件还是存储的问题
升级维护换镜像、重建容器还要管 K8s 自身的版本升级与组件兼容
学习曲线一两天上手概念体系庞大,摸到门道要以周计
WARNING

个人单机、两三台小服务器的场景,硬上 K8s 属于典型的用运维复杂度换根本用不上的能力:你为高可用、自愈、弹性扩缩付出了全部学习与维护成本,而你的流量和规模根本触发不了这些能力。先把 Compose 用透,收益高得多。

泼冷水不是劝退。K8s 是当下云原生生态的事实标准,托管服务、CI/CD、监控、服务网格全都围着它转,理解它的概念对任何做后端和运维的人都只有好处。但「理解它」和「在自己的小服务器上养一套它」是两回事。这篇的态度就是:先用对照法把概念学明白,什么时候真该上,后文有明确的判断表。

二、核心概念对照大表#

先上全篇最重要的一张表。建议先通读一遍有个整体印象,后面每一节都会展开其中几行。

你已经会的东西K8s 里的对应物关键区别说明
镜像 ImageImage(完全同名同物)没有任何区别,K8s 用的就是 Docker 镜像格式,从同样的仓库拉取
容器 ContainerPod 里的一个容器容器在 K8s 里不是最小单位,它被装进 Pod 里运行
docker run 起一个容器PodPod 是最小调度单位,可以装一个或多个容器
Compose 的一个 serviceDeployment + ServiceDeployment 管「跑几个副本、怎么更新」,Service 管「怎么被访问」,一个职责拆成两个对象
docker-compose.yml一堆 YAML 文件(或一个文件多段)每个对象一段 YAML,用 --- 分隔,靠 kubectl apply 一起提交
数据卷 VolumePV(持久卷)+ PVC(持久卷声明)多了一层抽象:PVC 是「我要一块 10Gi 的盘」的申请,PV 是集群实际供给的那块盘
Docker 自定义网络+容器名互访Service + 集群 DNS容器名换成 Service 名,跨命名空间还能带后缀,原理还是 DNS 解析
Nginx 反向代理Ingress + Ingress ControllerIngress 只是规则声明,真正干活的 Controller(如 ingress-nginx)要自己装
.env 环境变量ConfigMap存非敏感配置,键值对形式,可挂成环境变量或文件
写在 compose 里的密码Secret存敏感配置,Base64 编码存储(注意:只是编码,不是加密)
restart: unless-stopped控制器自愈(Deployment 托管 Pod)不是容器自己重启,而是控制器发现副本数不对,重新拉起新 Pod
docker compose up -dkubectl apply -f xxx.yaml都是声明「我要什么」,让系统去达成
docker pskubectl get pods看的不是容器列表,而是 Pod 列表

逐行说几个容易卡住的点。

**镜像是唯一零成本迁移的东西。**你在 Dockerfile 里构建的镜像、在私有仓库里存的镜像,到了 K8s 里原样使用,一个字都不用改。这是整个迁移里最让人安心的一点:你的构建资产全部保值。

**Compose 的一个 service,在 K8s 里被拆成了两个对象。**这是初学者最困惑的地方。Compose 里写一个 service,运行和访问两件事都齐了;K8s 把它拆开:Deployment 只负责「这个应用跑几个副本、镜像是哪个版本、挂了怎么补」,Service 只负责「给这组副本一个稳定的访问地址」。拆开的原因是职责确实不同:一组 Pod 可以被多个 Service 暴露(对内一个、对外一个),一个应用也可以只跑不被访问(后台任务)。理解了这个拆分,K8s 一半的对象就通了。

**存储多了一层「申请与供给」。**Docker 里写个 volumes 映射,盘就是你的。K8s 里应用只能提需求(PVC:我要 10Gi、可读写),至于这块盘最终是云盘、NFS 还是本地目录,由集群的 PV 供给机制决定。应用不关心盘从哪来,这正是集群抽象的意义:换个集群,YAML 一行不用改。

**Ingress 本身不干活。**这点和很多人想的不一样:Ingress 只是一份「域名+路径 → 转发给哪个 Service」的规则声明,集群里必须额外装一个 Ingress Controller(最常见的是 ingress-nginx)来读规则并真正做反向代理。类比一下:Ingress 相当于你写好的 Nginx 配置文件,Controller 相当于 Nginx 进程本身,光有配置文件,没有进程读它,什么都不会发生。

WARNING

Secret 只是 Base64 编码,不是加密。任何能读到 Secret 的人都能一条命令解出明文。把 Secret 当保险箱、把含 Secret 的 YAML 随手提交到公开仓库,属于把密码明文发到全世界。生产环境要配合 RBAC 权限控制,有条件再上外部密钥管理或静态加密。

三、Pod 为什么要多一层#

对照表里最核心的新概念就是 Pod。它是 K8s 的最小调度单位,理解了它为什么存在,其余概念都是顺水推舟。

在 Docker 的世界里,容器就是最小单位,你想跑什么就 docker run 什么。K8s 在容器外面包了一层 Pod,主要为了解决两个问题:

**第一,同 Pod 内容器共享网络。**同一个 Pod 里的所有容器共用一个网络命名空间,也就是共享同一个 IP 地址和端口空间,彼此之间用 localhost 就能互访。这意味着一组必须「贴身协作」的容器可以当成一个整体调度:它们永远落在同一台机器上,生一起生、死一起死,不会出现主容器在这台机器、辅助容器在另一台机器的尴尬。

**第二,同 Pod 内容器共享存储。**Pod 可以定义卷,挂给 Pod 内的多个容器共同读写,适合主进程写日志、辅助进程收集日志这类配合。

最常见的多容器模式叫 sidecar(边车):主容器跑业务,旁边挂一个辅助容器干杂活,比如收集日志、做代理转发、同步配置。像服务网格里的流量代理,就是以 sidecar 形式注入到每个业务 Pod 里的。

当然,绝大多数情况下一个 Pod 里就一个容器。单容器 Pod 你完全可以近似理解成「K8s 版的容器」,只是外面多了一层壳,多了标签、注解、探针这些集群管理需要的元数据。下面看一个最简单的 Pod 长什么样:

apiVersion: v1
kind: Pod
metadata:
name: my-nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80

对照着 Docker 看:image 还是那个镜像,containerPort 就是你熟悉的容器端口,containers 是个列表——这就是为多容器留的位置。实际工作中你很少直接写裸 Pod,因为裸 Pod 挂了没人管,真正用的是下一节的 Deployment。

四、声明式思维:从「过程」到「期望状态」#

如果说 Pod 是概念上最核心的新东西,那声明式就是思想上最核心的新东西。

Compose 其实已经是半声明式了:你写「我要跑这三个服务」,docker compose up 负责把现状调整成文件里写的样子。但 Compose 的自愈能力到容器级为止:容器挂了靠 restart 策略原地重启,机器挂了,上面的一切都没了。

K8s 是彻底的声明式。你提交 YAML,描述的是期望状态:我要这个应用跑 3 个副本,用这个镜像,对外暴露这个端口。集群里的控制器会持续地对比「期望状态」和「实际状态」,发现不一致就动手修正,永远向期望靠拢。你不需要写任何「如果挂了就重启」的逻辑,因为自愈不是某个功能,而是声明式的自然结果。

这个差别,光说不如动手看一遍。下面这条演示命令链,建议你在本地体验环节亲手跑一次,冲击力比看十篇文章都强:

Terminal window
# 部署一个 3 副本的应用
kubectl create deployment demo --image=nginx:1.27 --replicas=3
# 查看 Pod,可以看到 3 个副本都在运行
kubectl get pods
# 手动删掉其中一个 Pod(模拟它突然崩溃)
kubectl delete pod <上面任意一个Pod的名字>
# 立刻再看:一个新的 Pod 已经被自动创建出来补位
kubectl get pods
# 查看副本数,始终维持在 3
kubectl get deployment demo

你删掉的那个 Pod 没有「重启」,而是 Deployment 控制器发现「期望 3 个、实际 2 个」,立刻新建了一个补上。注意新 Pod 的名字和 IP 都变了——在 K8s 的世界里,Pod 是随时可替换的消耗品,身份不重要,数量和状态才重要。也正因为 Pod 朝生暮死,才必须有 Service 这一层稳定入口兜底,否则调用方根本追不上天天变的 Pod IP。

理解了这一点,很多 K8s 的设计就都顺理成章了:滚动更新是「逐步把旧 Pod 换成新 Pod 并维持期望副本数」,扩缩容是「改一个数字,控制器去增删 Pod」,节点宕机恢复是「控制器发现一整台机器的 Pod 没了,在别的机器上重建」。全是同一套机制的不同表现。

五、完整对照实战:把一个 Compose 例子翻译成 K8s#

下面进入全篇的重头戏。先看一个你已经很熟悉的 Compose 例子:一个后端应用加一个 Nginx 前置,Nginx 把流量反代给后端。

Compose 版本(docker-compose.yml):

services:
web:
image: nginx:1.27
ports:
- "8080:80"
depends_on:
- app
app:
image: myapp:1.0
environment:
- APP_ENV=prod
deploy:
replicas: 2

翻译成 K8s,需要三个对象:app 的 Deployment、app 的 Service、web(Nginx)的 Deployment 加对外 Service。逐段来。

第一段,app 的 Deployment,对应 Compose 里 app 的「跑什么、跑几个」:

apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: myapp:1.0
ports:
- containerPort: 8080
env:
- name: APP_ENV
value: "prod"

对照着看:replicas: 2 就是 Compose 里的副本数;template 里描述的就是 Pod 本人,image、containerPort、env 全部是你认识的东西,只是组织方式变了。selector.matchLabels 和 template.metadata.labels 这对标签是 Deployment 认领 Pod 的凭据,两边必须一致,这是新手最常写错的地方之一,记住「控制器靠标签找自己的孩子」就行。

第二段,app 的 Service,对应 Compose 里「别的服务用名字 app 就能访问它」这件事:

apiVersion: v1
kind: Service
metadata:
name: app
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080

Service 靠 selector 标签选中 app 的那组 Pod,给它们一个稳定的虚拟 IP 和 DNS 名。集群内任何地方访问 http://app 都会被转到某个 app Pod 的 8080 端口——和 Compose 里用服务名互访是一模一样的体验,只是实现从 Docker 内置 DNS 换成了集群 DNS + Service 转发。

第三段,Nginx 前置。Compose 里 Nginx 既是应用又负责对外发布端口,K8s 里照样拆成 Deployment + Service 两件:

apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
type: LoadBalancer
selector:
app: web
ports:
- port: 80
targetPort: 80

这里的 Service 用了 type: LoadBalancer,对应 Compose 里的 ports: "8080:80" 对外发布:在云厂商的托管 K8s 上,它会自动给你配一个云负载均衡器和公网 IP;在本地 kind/minikube 里这个类型拿不到真正的外部 IP,后文体验环节会说明替代办法。另外,Nginx 反代后端的配置里,upstream 写 http://app 即可,和 Compose 里写服务名的习惯无缝衔接。

三段 YAML 放进一个文件(段与段之间用 --- 分隔),一条命令提交:

Terminal window
kubectl apply -f app.yaml
kubectl get pods,svc

把两边并排总结一下,翻译关系就彻底清楚了:

Compose 里的写法K8s 里的对应写法
services.app.imageDeployment 的 template.spec.containers[].image
deploy.replicasDeployment 的 spec.replicas
environment容器 env 字段,或抽到 ConfigMap/Secret 引用
ports: "8080:80"Service 的 port/targetPort,对外则选 LoadBalancer 或 Ingress
服务名互访(http://app)Service 名互访(http://app),机制换成集群 DNS
depends_on无直接对应,靠应用自己重试或初始化容器解决
docker compose up -dkubectl apply -f

最后一行值得多说一句:depends_on 在 K8s 里没有对应物,这不是功能缺失,而是设计哲学不同——集群环境里依赖的服务随时可能重启漂移,应用必须自己具备「连不上就重试」的能力,而不是指望编排工具保证启动顺序。往 K8s 迁移时,这是应用代码层面最常见的改造点。

六、kubectl 生存命令对照表#

操作层面,kubectl 就是 K8s 的 docker 命令行。下面这张表覆盖日常九成的动作,左边是你已经会的,右边是对应写法:

你想干什么Docker/ComposeKubernetes
看运行中的实例docker pskubectl get pods
看所有资源概览docker compose pskubectl get all
部署/更新docker compose up -dkubectl apply -f app.yaml
看详细信息docker inspect <容器>kubectl describe pod <名字>
看日志docker logs -f <容器>kubectl logs -f <Pod>
进容器执行命令docker exec -it <容器> shkubectl exec -it <Pod> -- sh
扩缩容docker compose up -d --scale app=3kubectl scale deployment app --replicas=3
更新镜像版本改 compose 文件后 up -dkubectl set image deployment/app app=myapp:2.0
看滚动更新状态无(直接替换)kubectl rollout status deployment/app
回滚版本改回旧镜像再 up -dkubectl rollout undo deployment/app
删掉一个实例docker rm -f <容器>kubectl delete pod <名字>(托管 Pod 会自动补新)
删除整套应用docker compose downkubectl delete -f app.yaml
看资源占用docker statskubectl top pods(需装 metrics-server)
把本地端口转发到服务靠 ports 发布kubectl port-forward svc/web 8080:80
看配置文件原文cat docker-compose.ymlkubectl get deployment app -o yaml

有三个差异点要特别适应一下:

第一,kubectl 的一切操作都围绕「资源对象」而不是「容器」。你 describe 的是 Pod、Deployment、Service,日志、执行命令也是先定位到 Pod。刚开始会觉得隔了一层,用久了会发现按对象思考正是集群管理的方式。

第二,kubectl delete pod 对新手是个陷阱:删掉 Deployment 托管的 Pod,它立刻补一个新的出来,看起来像「删不掉」。这恰恰是自愈在工作。要真正停掉应用,删的是 Deployment 或者把副本数调到 0。反过来,这也意味着在生产集群里随手 delete pod 是危险动作,你以为在清理,它以为在故障恢复,流量可能被打到刚启动还没就绪的新 Pod 上。

第三,kubectl port-forward 是本地调试的神器:它能把集群里任意 Service 或 Pod 的端口转发到你本机,效果类似临时做了一条 SSH 隧道,不用为了调试就把服务暴露到公网。

七、本地体验路线:先在自己电脑上玩起来#

理解 K8s 的正确姿势是先在本地起一个玩具集群,把第五节的 YAML 真跑一遍。本地工具有两个主流选择,二选一即可:

工具特点适合
kind把集群节点跑在 Docker 容器里,轻量、起停快、贴合 CI 场景已经装好 Docker、想快速反复重建的人
minikube功能全,支持多种驱动,自带仪表盘和插件生态想顺带体验插件、Ingress 等完整功能的人

本系列读者都装了 Docker,所以推荐 kind。完整体验流程如下:

Terminal window
# 1. 安装 kind(Linux 示例,其他系统去 kind 官网看对应方式)
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.24.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
# 2. 创建一个单节点集群(节点本身就是个 Docker 容器)
kind create cluster --name learn
# 3. 确认 kubectl 能连上
kubectl cluster-info
kubectl get nodes
# 4. 跑一遍第四节的自愈演示
kubectl create deployment demo --image=nginx:1.27 --replicas=3
kubectl get pods -w
# 5. 把第五节的 app.yaml 存好并部署
kubectl apply -f app.yaml
kubectl get pods,svc
# 6. web 的 Service 是 LoadBalancer 类型,本地没有云厂商给它分配外部 IP
# 改用端口转发在本机访问验证
kubectl port-forward svc/web 8080:80
# 浏览器打开 http://localhost:8080 即可
# 7. 玩完销毁集群,不留任何残留
kind delete cluster --name learn

跑这一圈时重点观察三件事:一是删 Pod 自动补位的全过程,二是 kubectl describe 一个 Pod 时里面记录的事件(调度到哪个节点、镜像拉取进度、探针结果都在里面,这是 K8s 最主要的排障入口),三是 Service 的 DNS 名在容器内真实可用——可以 kubectl exec 进任意 Pod 用 curl http://app 验证。

如果本地机器配置紧张,也完全可以直接用云厂商的托管 K8s 试用集群练手,概念完全一致,只是别忘了练完释放资源。

八、选型判断:什么时候该上,什么时候别上#

学归学,真到给自己的项目做选型时,用下面这张表对照着判断:

判断维度Compose 就够了该考虑 Swarm该考虑 K8s
机器数量1 台2–5 台5 台以上,或弹性伸缩的云环境
应用数量十几个服务以内十几个到几十个几十上百个服务、多团队共用
高可用要求单机挂了人工恢复可接受希望单机故障自动漂移要求节点级、可用区级容灾
发布频率一天几次以内每天多次多团队高频发布、需要灰度/金丝雀
运维人力个人或兼职一两个人有专职平台/运维团队,或买托管版
生态需求基本没有基本没有需要服务网格、精细监控、云厂商深度集成

三条经验线可以直接套用:

  • 个人项目、自用服务、一台小服务器:Compose 就是最优解,别犹豫。这也是本系列前十几篇一直在深耕 Compose 的原因——它覆盖了绝大多数个人和小团队场景。
  • 有三五台机器、想要基本的故障漂移和滚动更新,但没人愿意养 K8s:可以看看 Docker Swarm,它和 Compose 共用一套心智模型,学习成本几乎为零,代价是生态和上限都有限。
  • 团队规模、多台机器、发布频繁、且有人能专职维护(或者愿意为托管版付费):K8s 的投入开始回本。特别是用云厂商托管 K8s 时,控制平面不用你管,成本会降一大截,这是现在大多数团队上 K8s 的实际姿势。
WARNING

最忌讳的选型理由是「简历上好看」和「别人都在用」。K8s 的复杂度是真金白银的日常成本:每一次排障、每一次升级、每一个新同事入职都要为它付费。规模没到、团队没到,上了 K8s 等于给自己请了个全职麻烦。反过来,规模真的到了还硬扛 Compose,人工运维的成本同样会反噬。选型没有高下,只有匹配与否。

九、排障小节:新手最常撞的几个坑#

**Pod 一直是 Pending 状态。**意思是调度器找不到能放它的节点。先 kubectl describe pod <名字> 看 Events,常见原因是集群资源不够(本地 kind 只有一个节点,副本开太多、资源请求写太大就会这样),或者 PVC 没有可用的 PV 供给,Pod 在等存储。

**Pod 反复重启,状态是 CrashLoopBackOff。**Pod 起来了但进程立刻退出,K8s 按退避策略反复拉起。用 kubectl logs <Pod> 看当前日志、kubectl logs <Pod> --previous 看上一次崩溃的日志,九成是应用本身的问题:配置错、依赖连不上、启动命令写错。记住这不是 K8s 的故障,是你的应用在集群里把在 Docker 里也会犯的错又犯了一遍,只是换了个状态名。

**ImagePullBackOff 拉不到镜像。**同样先看 describe 的 Events。常见原因:镜像名或标签写错、私有仓库没配拉取凭证(imagePullSecrets)、本地 kind 集群里用了只存在于你本机 Docker 的镜像——kind 需要用 kind load docker-image <镜像> --name learn 把本地镜像灌进集群节点,这是本地体验时最容易卡住的一步。

**Service 访问不通。**按链路逐段查:kubectl get svc 确认 Service 存在,kubectl get endpoints <Service名> 确认它背后挂上了 Pod(为空说明 selector 标签和 Pod 标签对不上,这是最常见的原因),再确认 Service 的 targetPort 和容器实际监听端口一致。整条链路就是「DNS 名 → Service → 标签选 Pod → 端口转发」,断在哪段查哪段。

**apply 了 YAML 却没生效。**先确认改的是同一个对象(名字、命名空间是否一致,kubectl 默认操作 default 命名空间,跨命名空间要用 -n 指定),再用 kubectl get <资源> -o yaml 把集群里的实际状态拉出来和文件逐字段对。声明式的好处是状态可查,别靠猜。

十、学习路线图#

最后给一条不折腾的进阶路线,按顺序走,每一步都能在前一步的基础上小步验证:

  1. 概念期:吃透这篇的对照表,特别是 Pod、Deployment、Service、Ingress、ConfigMap/Secret 这六个对象的职责边界。能对着一张架构图说清每个对象干什么,这一期就毕业了。
  2. 本地期:用 kind 把第七节的流程完整跑两遍,第二遍试着自己改副本数、换镜像版本、删 Pod 看自愈、给应用加上 ConfigMap 管理配置。把第六节的 kubectl 命令都亲手敲过一遍。
  3. 托管期:在任意云厂商开一个最小规格的托管 K8s,把一个自己真实的小项目迁上去,完整经历域名解析、Ingress 配 HTTPS、镜像仓库凭证这些「玩具集群里没有的真实问题」。
  4. 进阶期:再往后才是 Helm(包管理)、探针与资源配额调优、监控告警体系、灰度发布这些话题。每一个都是大题目,按需学,不要提前囤。
WARNING

千万别一上来就啃 K8s 源码或者试图自建生产集群。控制平面的组件(API Server、etcd、Scheduler、Controller Manager)各自都是一门学问,在没跑过托管版之前自建集群,学到的主要是踩坑而不是概念。先当好使用者,再决定要不要当建设者。

小结#

  • K8s 不是更高级的 Docker,而是面向集群的操作系统;它的全部复杂度,都是为「多机调度、自愈、弹性」付的账,规模没到就不要替它买单。
  • 翻译关系记住三条主线:Pod 是容器的壳,Compose 的一个 service 拆成 Deployment(管运行)+ Service(管访问),存储多了一层 PVC 申请、PV 供给。
  • 声明式是 K8s 的灵魂:你只描述期望状态,控制器负责无限逼近它,自愈、滚动更新、扩缩容都是同一机制的表现。
  • kubectl 的操作对象是资源而不是容器,describe 看事件、logs 看日志、apply 提交期望,是日常排障的铁三角。
  • 选型只看匹配度:单机个人项目用 Compose,三五台机器求轻量集群看 Swarm,规模与团队都到位再上 K8s,且优先托管版。

把这篇的对照表存好,下次再看到任何 K8s 名词,先回表里查它对应你熟悉的哪个东西——发怵的感觉,基本就消了。

从 Docker 到 Kubernetes:概念对照
https://blog.anexns.com/posts/docker-to-kubernetes/
作者
Anexns
发布于
2026-11-15
许可协议
CC BY-NC-SA 4.0