1、Docker 入门:Docker 发展史、核心概念、安装与配置
聊到容器技术,我总会想起2014年刚接触 Docker 的场景。那时公司要把 Java 应用部署到几十台服务器上,每次上线都像在拆弹。一个环境配置不对,整个集群就炸了。直到 Docker 出现,嗯,事情才变得简单。
说白了,Docker 就是一个“打包工具”。它把你的应用、依赖、配置、运行环境全部塞进一个标准化的“箱子”里。这个箱子在任何机器上打开,行为完全一致。你想想看,这解决了多大的问题?
1.1 发展史:从 LXC 到云原生标配
Docker 不是凭空冒出来的。2013 年,dotCloud 公司内部有个叫 Solomon Hykes 的工程师,受不了当时 PaaS 平台的部署痛苦,就基于 LXC(Linux Container)搞了个上层工具,叫 Docker。我早期在项目中试过 LXC 裸用,那体验确实不友好——配置复杂,隔离性也差。Docker 把这些糟心事全封装了。
几个关键时间点:
- 2013 年 3 月:Docker 首次公开亮相,PyCon 上的演示引爆了社区。
- 2014 年 6 月:Docker 1.0 发布,开始有商用版本。
- 2015 年:OCI(Open Container Initiative)成立,定义容器运行时和镜像标准。Docker 把核心组件 runC 捐给了社区。
- 2017 年:Docker 拆分出 Moby 项目,社区版正式叫 Docker CE,企业版叫 Docker EE。
- 2020 年至今:Kubernetes 成为容器编排事实标准,Docker 转向以 containerd 为核心的底层运行时。
为什么 Docker 能赢? 不是因为它技术最牛,而是它让“打包-分发-运行”这条链路变得极简。我见过很多技术产品,功能堆得很强,但用户根本用不起来。Docker 恰恰相反——它把复杂性藏了起来。
我记得 2015 年帮客户做微服务迁移,传统虚拟机方案要半小时启动一台,Docker 容器只需 2 秒。这个差异直接让客户拍板换了技术栈。
1.2 核心概念:镜像、容器、仓库
这三个概念可以说是 Docker 的“三驾马车”。理解它们,你就掌握了 Docker 的 80%。
镜像 (Image)
镜像是只读的模板。它里面包含了操作系统基础层、运行时、库、代码、配置等一切。你可以把镜像理解成“虚拟机快照”的轻量版。我经常跟新人说:“镜像是一个打包好的文件系统,加上一些启动参数。”
镜像采用分层存储。每一层都是只读的,构建时通过 Dockerfile 的指令一层层叠加。这样做的好处是——相同层可以复用,拉取快,磁盘占用低。
容器 (Container)
容器是镜像的运行实例。它在镜像层之上加了一层可写层,所有对文件系统的修改都写在这里。容器可以被启动、停止、删除、暂停。每个容器都运行在独立的命名空间里,进程、网络、文件系统全隔离。
你想想看,这就像从同一个安装包(镜像)装出来的多个沙箱。每个沙箱随便玩,玩坏了删掉重来,不影响原包。
仓库 (Registry)
仓库用来存储和分发镜像。Docker Hub 是最大的公共仓库,但生产环境中多数企业都搭建私有仓库,比如 Harbor 或者直接用云厂商的镜像服务。
举个最简单的例子:
docker pull nginx:latest # 从 Docker Hub 拉取 nginx 镜像
docker run -d -p 80:80 nginx # 基于镜像启动一个容器
一个小技巧: 我习惯把镜像名写成 registry/namespace/repo:tag 的格式。比如 mycompany.com/microservice/user-service:v1.2。这样一眼就能看出镜像来源、项目归属和版本。
为了帮你一目了然,我画了张图,把三者的关系捋清楚:
1.3 安装与配置
安装方式有很多种,这里我只推荐最稳妥的——使用官方仓库安装。曾经有个同事从第三方源装了个 Docker,结果版本不对,折腾两天才发现是源的问题。所以,直接用官方的。
在 Ubuntu/Debian 上安装
# 卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc
# 安装依赖
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release
# 添加 Docker 官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 添加稳定版仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装 Docker CE
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
# 将当前用户加入 docker 组,避免每次都 sudo
sudo usermod -aG docker $USER
注意: 加入 docker 组后,必须重新登录才能生效。我曾经见人在这步卡了一下午,一直报权限错误,其实是忘记切会话了。
验证安装
docker --version
# 输出类似:Docker version 24.0.7, build 24.0.7-0ubuntu1
docker run hello-world
# 如果看到 "Hello from Docker!" 就说明成功了
docker run hello-world 这个镜像极小,它只是验证守护进程工作正常。我第一次跑通的时候,感觉像给新电脑装好了系统,踏实。
配置镜像加速器
国内拉取 Docker Hub 镜像经常超时。我建议配置镜像加速器。编辑或创建 /etc/docker/daemon.json:
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
个人习惯: 我会把 max-size 设小一点,默认的日志文件容易撑爆磁盘。曾经在生产环境遇到过容器的日志写满根分区,导致整个宿主机挂掉。从那以后,每个节点我都强制配置日志轮转。
配置好后重启 Docker:
sudo systemctl daemon-reload
sudo systemctl restart docker
验证是否生效:
docker info | grep -A 10 "Registry Mirrors"
# 应该能看到你配置的镜像地址
1.4 快速上手:拉取镜像并运行容器
来个完整的 Demo。假设你要跑一个 Nginx 服务:
# 拉取镜像
docker pull nginx:alpine
# 查看本地镜像
docker images
# 启动容器,将宿主机 8080 端口映射到容器 80 端口
docker run -d --name my-nginx -p 8080:80 nginx:alpine
# 查看运行中的容器
docker ps
# 在容器内执行命令
docker exec -it my-nginx /bin/sh
# 停止并删除容器
docker stop my-nginx
docker rm my-nginx
打开浏览器访问 http://localhost:8080,就能看到 Nginx 欢迎页。整个过程不到 30 秒。如果是传统方式,你得装 Nginx、调配置、开端口、加守护进程……嗯,差距就是这么大。
| 特性 | Docker 容器 | 传统虚拟机 |
|---|---|---|
| 启动速度 | 秒级 | 分钟级 |
| 占用空间 | MB 级 | GB 级 |
| 隔离级别 | 进程级命名空间 | 完整操作系统 |
| 性能损失 | 接近原生 | 有一定损耗 |
一句话总结: Docker 通过镜像保证环境一致性,通过容器提供轻量隔离,通过仓库实现标准化分发。这套组合拳,让它成为现代软件交付的基石。我见过的所有大型互联网公司,没有一家不在用容器技术。