一、Docker入门:容器化革命、Docker是什么、Docker与传统虚拟化对比、Docker核心概念

1.1 容器化革命:为什么我们需要它?

说实话,我入行那会儿,最头疼的事就是环境问题。

开发说「我本地跑得好好的」,运维说「服务器上就是起不来」。这种扯皮,我相信每个老工程师都经历过。后来我总结了一句话:「能复现的问题都不是问题,不能复现的问题才是灾难」

容器化革命,说白了就是来解决这个「不能复现」的痛点。

你想想看,一个应用从开发到测试再到生产,要经过多少环境?开发机、测试服务器、预发布环境、生产集群……每个环境的操作系统版本、依赖库、配置文件都可能不一样。哪怕差一个 glibc 的小版本,都可能让你通宵加班。

容器化做了什么?它把应用和它所有的依赖打包在一起,形成一个「不可变」的单元。这个单元在哪儿跑都一样——你的笔记本、同事的电脑、公司的服务器、云上的集群。嗯,这就是我常说的「一次构建,到处运行」。

我个人习惯把容器比作「集装箱」。没有集装箱之前,货物运输乱七八糟,到了港口还得重新分拣。有了集装箱,货物标准化了,装卸效率翻了几倍。Docker 就是软件世界的集装箱。

核心观点:容器化不是技术噱头,而是解决「环境不一致」这个根本矛盾的工程实践。我经历过太多因为环境差异导致的线上事故,所以对这一点感触特别深。

1.2 Docker是什么?

Docker 是一个开源的容器化平台。但这么说太官方了,我换个说法。

Docker 就是一个「打包工具」+「运行环境」。它把你的应用、配置、依赖全部打包成一个镜像,然后你可以在任何安装了 Docker 的机器上把这个镜像跑起来,变成一个容器。

我记得第一次接触 Docker 是在 2015 年,当时公司要做一个微服务改造项目。传统方式部署十几个服务,光配置环境就花了两天。后来用了 Docker,整个流程压缩到半小时。说实话,当时我就觉得这东西要火。

Docker 的核心组件其实就三个:

  • Docker 客户端:你敲命令的那个终端
  • Docker 守护进程:后台真正干活的进程
  • Docker 镜像仓库:存放镜像的地方,类似 GitHub 但存的是镜像

你执行 docker run 的时候,客户端把指令发给守护进程,守护进程检查本地有没有镜像,没有就去仓库拉,拉下来启动容器。就这么简单。

小技巧:刚开始学 Docker,别急着研究底层原理。先学会怎么用 docker rundocker psdocker images 这三个命令,能解决 80% 的日常问题。

1.3 Docker与传统虚拟化对比

这个问题我经常被问到。很多人觉得容器就是轻量级的虚拟机,其实不完全对。

咱们直接看对比:

对比维度 传统虚拟化 Docker 容器
启动速度 分钟级(要启动完整操作系统) 秒级(直接启动进程)
资源占用 每个 VM 有完整 OS,占用 GB 级 共享宿主机内核,占用 MB 级
隔离级别 硬件级虚拟化,强隔离 进程级隔离(namespace + cgroups)
部署密度 一台物理机跑几个 VM 就差不多了 一台物理机跑几十上百个容器很常见
镜像大小 GB 级(包含完整 OS) MB 级(只包含应用和依赖)

为什么会这样?因为虚拟机是在硬件层面做虚拟化,每个 VM 都要跑一个完整的操作系统。而容器直接共享宿主机的操作系统内核,只隔离进程和文件系统。

我曾经在项目中做过一个压力测试:同样一台 16 核 32G 的服务器,跑虚拟机最多能起 10 个实例,跑容器轻松起了 80 个,而且性能损耗几乎可以忽略不计。

注意:容器虽然轻量,但隔离性不如虚拟机。如果你需要强隔离(比如运行不可信代码),还是得用虚拟机。我见过有人把容器当虚拟机用,结果一个容器把宿主机内核搞崩了……嗯,这是个教训。

1.4 Docker核心概念

这部分是基础中的基础,我建议你反复理解。说白了就四个概念:

1.4.1 镜像(Image)

镜像是一个只读的模板,包含了运行应用所需的一切:代码、运行时、库、环境变量、配置文件。你可以把它理解成「类」——是一个定义,不是实例。

我习惯用 docker pull 从仓库拉镜像,就像从 GitHub 拉代码一样。拉下来之后用 docker images 查看本地有哪些镜像。

# 拉取一个 Nginx 镜像
docker pull nginx:latest

# 查看本地镜像
docker images

1.4.2 容器(Container)

容器是镜像的运行实例。镜像启动后就变成容器,你可以对容器进行启动、停止、删除等操作。容器就像「对象」——是镜像这个类的实例。

这里有个关键点:容器是可写的。你在容器里做的任何修改(比如写日志、改文件),都只存在于这个容器中。一旦容器被删除,这些修改就没了。

避坑指南:我曾经犯过一个错误——在容器里直接修改配置文件,然后容器挂了重启,配置全丢了。后来学乖了,要么用数据卷(volume),要么把配置写在镜像里。

1.4.3 仓库(Repository)

仓库就是存放镜像的地方。Docker Hub 是官方的公共仓库,类似 GitHub。你也可以搭建私有仓库,很多公司都是这么干的。

常用的仓库命令:

# 从仓库拉取镜像
docker pull ubuntu:20.04

# 推送镜像到仓库
docker push yourname/yourimage:tag

1.4.4 Dockerfile

Dockerfile 是一个文本文件,里面写了如何构建镜像的指令。这是 Docker 最核心的文件,没有之一。

一个简单的 Dockerfile 示例:

# 基于哪个基础镜像
FROM python:3.9-slim

# 设置工作目录
WORKDIR /app

# 复制依赖文件
COPY requirements.txt .

# 安装依赖
RUN pip install -r requirements.txt

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 5000

# 启动命令
CMD ["python", "app.py"]

你看,这个文件把整个应用的构建过程都描述清楚了。任何人拿到这个 Dockerfile,都能构建出完全一样的镜像。这就是「可复现」的力量。

小结

这一章我们聊了容器化革命的背景、Docker 是什么、它和传统虚拟化的区别,以及四个核心概念。说实话,这些内容看起来简单,但真正理解透了,后面的学习会顺畅很多。

下一章我会带你亲手写一个 Dockerfile,把应用容器化。到时候你会发现,原来部署可以这么简单。

一句话总结:Docker 不是魔法,它只是把「环境一致性」这件事做到了极致。你只要记住「镜像构建、容器运行、仓库存储」这个三角关系,就抓住了 Docker 的精髓。