先聊点实际的。我刚入行那会儿,团队里部署一个 Java 服务,从编译到上线得折腾一整天:开发说环境跑不起来,测试说代码没问题,运维说环境又崩了。后来我们逐步把 Docker 和 Kubernetes 引入整个研发链路,迭代节奏直接从“周”压缩到“天”。今天这篇总结,我不打算复述官方文档,而是结合我这些年踩过的坑、调过的参,把 Docker 和 K8s 从“零散概念”串成“完整闭环”,帮助你真正理解它们是什么、怎么配合、实操时该注意什么。文章覆盖了从安装、镜像构建、容器编排到常见问题排查的完整路径,适合正在学习容器化改造的开发者、想要搭建团队 CI/CD 流程的运维,以及所有对云原生技术感兴趣的读者。
1. 整体设计与思路拆解:为什么偏偏是 Docker 和 K8s
1.1 Docker 解决的是“单机环境一致性”问题
很多人第一次接触 Docker,是被“环境不一致”逼疯的。明明代码在本机跑得好好的,一上服务器就报错,要么缺依赖,要么版本不对。Docker 的核心思路非常朴素:把你的应用和它运行所需的一切(代码、运行时、系统工具、库、配置文件)打包成一个标准化的镜像,然后用这个镜像在任意安装了 Docker 的机器上启动容器。容器里的进程直接运行在宿主机的内核之上,但通过 NameSpace 和 Cgroup 实现了文件系统、网络、进程、资源的隔离与限制。
有朋友问,这和虚拟机有什么区别?虚拟机是虚拟出一套完整的硬件,然后在这套虚拟硬件上跑一个完整的操作系统,所以很重,启动也慢。容器则直接复用宿主机内核,只额外打包了应用层和必要依赖,所以镜像体积小,启动速度是毫秒级到秒级。拿搬家的例子类比:虚拟机等于把整个房子搬走,容器等于只带行李箱和随身衣物,轻便得多。
不过,容器虽然解决了“单机”的环境一致性和资源隔离问题,但当你的服务数量多起来,只靠 Docker 命令在单机上一个一个容器去管理,很快就失控了。哪台机器跑哪个容器?容器挂了谁拉起来?流量怎么分发?存储怎么做持久化?这时候,就需要一个更高层的调度和编排平台,也就是 Kubernetes。
1.2 Kubernetes 解决的是“集群调度与服务编排”问题
Kubernetes(简称 K8s,因为首尾字母之间有 8 个字符)本质是一个容器编排平台。它的定位不是“再封装一层 Docker”,而是站在集群的视角,告诉你应该把容器放在哪些节点上、怎么保证副本数量、怎么升级、怎么发现服务、怎么暴露给外部访问。
打个比方:Docker 是单台机器上的“集装箱”,K8s 是管理一万个集装箱的“港口调度中心”。所以 Docker 和 K8s 不是二选一的关系,而是天然的上下游配合关系。K8s 集群里的工作节点(Node)上运行着容器运行时(Container Runtime),目前最常见的就是 containerd,它负责真正启动和管理容器。早期 K8s 直接调用 Docker,后来从 K8s 1.24 版本开始移除了对 Docker 的直接依赖(即 Dockershim 被移除),现在默认用 containerd 作为运行时,但我们在开发调试阶段仍然大量使用 Docker 来构建镜像和跑本地容器。这套组合拳打下来,开发、测试、生产的交付链路就统一了。
所以,我的整体思路是:先学好 Docker,打好镜像构建和容器运行的基础,然后再学 K8s 的抽象模型和核心组件。这个顺序不能反,因为 K8s 里的一切概念(Pod、Deployment、Service 等)最终都要落到容器和镜像之上,容器基础不牢,K8s 学起来会非常吃力。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心概念解析与实操要点:先从 Docker 的几个核心组件说起
2.1 镜像、容器、仓库三者关系
Docker 的三大核心概念是镜像(Image)、容器(Container)和仓库(Repository)。
- 镜像:一个只读的模板,是应用的“图纸”。
- 容器:镜像运行后的实例,是应用的“房子”。
- 仓库:存放镜像的地方,相当于“图纸的档案馆”。
实操中,我们会先写一个 Dockerfile 描述镜像构建步骤,然后使用 docker build 构建出镜像,最后用 docker run 启动容器。如果要把镜像分发到其他机器,可以把镜像 push 到一个仓库,比如 Docker Hub 或者公司内部的 Harbor。
这里的要点是:镜像是分层的。每条构建指令都会生成一个只读层,多个容器共享同一镜像的底层只读层,只有写入时才发生拷贝(Copy-on-Write),这既是镜像体积优化的关键,也是很多怪癖 bug 的来源。比如你在容器里删除了某个文件,镜像层里其实还保留着它,只是在上层加一个白条文件把它遮挡了。
2.2 Dockerfile 编写心得与镜像体积优化
编写 Dockerfile 是我觉得整个 Docker 实操里最需要经验沉淀的部分。新手最容易犯的错是:把 Dockerfile 写成一个一个命令的堆叠,完全不考虑层缓存和最终镜像体积。
一个值得推荐的 Java Spring Boot 项目 Dockerfile 结构:
dockerfile复制# 多阶段构建:先用 maven 镜像编译,再用 jre 镜像运行
FROM maven:3.8.6-eclipse-temurin-17 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offl
