容器化已经是后端服务的标配,而 Docker 几乎是入门的"必经之地"。从 2013 年 Docker 公开,到 2017 年 Docker 公司宣布拆分社区版(docker-ce)和企业版(docker-ee),再到 2019 年底 Mirantis 接手 Docker Enterprise 业务、2020 年 Docker 把 buildx 收为官方 CLI 插件、2022 年 Kubernetes 1.24 移除 dockershim 引入 cri-dockerd——九年间,Docker 生态的"安装"二字已经远不止 apt install docker.io 那么简单。
这篇文章把零散的安装笔记、版本对比、配置细节整理成一条"从选型到可用"的完整路径,适合刚接触 Docker、或在新机器上做标准化的同学。
阅读对象:需要在 Linux 服务器上从零部署 Docker 的开发者、运维同学
覆盖范围:docker-ce / docker-ee / docker.io 三种发行版差异 + Debian/Ubuntu/Kali/CentOS 主流安装方式 + 离线部署(含 cri-dockerd、buildx、docker-compose v2)+ daemon.json 关键配置 + 清理卸载 + 常见排障
一、为什么需要 Docker
容器不是"更轻的虚拟机"那么简单。在引入 Docker 之前,团队通常被这些痛点反复折磨:
- 环境漂移:开发用 macOS、测试用 CentOS、生产用 Ubuntu,
works on my machine反复出现 - 资源浪费:一台物理机只跑两三个 Java 应用,资源利用率不足 20%
- 交付链条长:应用 + 运行时 + 依赖 + 配置,要运维一台台机器"对版本"
- 扩缩容难:业务流量上来后,手动扩容几台机器要写一堆脚本
- 与 K8s 集成难:容器运行时直接对接 kubelet 的 dockershim 接口一改,整个集群要重新适配
Docker 把应用 + 运行时 + 依赖打包成"镜像",在装有 Docker 引擎的任意机器上一键运行,保证开发、测试、生产环境的一致性。这正是它被广泛接受的根本原因。
When to use:单体应用拆成多服务时、新人 onboard 需要快速搭建环境时、CI/CD 需要稳定可复现的构建产物时,Docker 几乎是首选解。从 LXC 时代走过来,Docker 通过标准化的镜像格式(OCI 规范)、BuildKit 构建系统和 Compose 编排,把"环境一致性"变成了开箱即用的能力。
二、版本选型:docker-ce / docker-ee / docker.io 的真实差异
2017 年 3 月 Docker 公司宣布将 Docker 拆分为两条产品线:开源的 Docker Community Edition(CE) 和商业的 Docker Enterprise Edition(EE)。这次拆分不是营销行为,而是把"包结构"和"维护承诺"做了明确切割——CE 由 Docker Inc. 维护源码、每月发布一次社区版;EE 在 CE 基础上叠加企业级功能,按"基本/标准/高级"三级订阅。
| 发行版 | 来源 | 特点 | 适用场景 |
|---|---|---|---|
docker.io | Debian / Ubuntu / Kali 官方仓库 | 由发行版包管理器接管依赖,升级时主程序与系统库同步更新;有时版本比 docker-ce 还新 | 服务器首选 Debian / Ubuntu 系列,追求"系统包管一切" |
docker-ce | download.docker.com 官方源 | Docker Inc. 维护源码,用 Go 把依赖尽量静态封装在一个包里,跨发行版一致 | CentOS / RHEL / 任何需要"同一版本跑所有机器"的场景 |
docker-ee | Mirantis 客户专用仓库 | 在 CE 之上叠加 LDAP/AD 集成、RBAC、镜像安全扫描、连续漏洞监控等企业级能力 | 大型企业、需要 Docker Inc. / Mirantis 商业支持的客户 |
历史注脚:2019 年 11 月,Mirantis 收购了 Docker 的企业业务(包括 docker-ee 品牌)。所以现在严格意义上"docker-ee"是 Mirantis 商业产品线,而非 Docker Inc. 的产品。如果用 docker-ee 走商业支持,签合同的对象是 Mirantis。
docker-ce 的"致命缺陷"——依赖管理:
docker-ce 把 Docker 引擎依赖的成百上千个第三方库(glibc、openssl、libseccomp、containerd、runc 等)尽量静态或动态链接到自己的包里。这意味着理论上只要其中一个依赖出 CVE,整套 docker-ce 都得重新打补丁、重建二进制、再分发。反观 docker.io,依赖托管给系统包管理器,只需要升级 docker 主程序、系统的 libseccomp 等库跟随 Debian Security Advisory / USN 自动推补丁。
结论:
- Debian / Ubuntu / Kali 服务器:直接
apt install docker.io,让系统接管一切 - 其他发行版(CentOS / RHEL / Amazon Linux / SUSE):走
docker-ce官方源或get-docker.sh脚本 - 商业场景:评估 docker-ee / Mirantis Container Cloud 的 SLA 与支持响应
三、Debian / Ubuntu / Kali 系安装
3.1 路线 A:apt 安装 docker.io(推荐)
| |
docker.io 包是 Debian / Ubuntu 官方基于 Docker 社区源码封装的版本,特点是把 Docker 的依赖直接转接到主系统。换句话说,系统的 glibc / openssl / libseccomp 升级时,docker.io 自动跟随,不需要 Docker Inc. 单独发版。
3.2 路线 B:apt 安装 docker-ce
如果团队要求"全机器统一 Docker 版本"(比如某条线 CI 必须用 20.10.x),或者 Debian stable 仓库里的 docker.io 太老,就走 docker-ce 源:
| |
注意:从 20.10 起,官方推荐把
buildx和docker-compose作为插件(plugin)安装,文件落在/usr/libexec/docker/cli-plugins/。这是为了和 Docker CLI 解耦,buildx 可以独立升级。
3.3 卸载 Debian/Ubuntu 系
| |
Why 这样卸载:apt remove 只会删主程序二进制,
/var/lib/docker下的镜像、卷、网络、自定义配置都还在;不删干净的话,新装 docker 时旧配置会"莫名生效",排查很痛苦。
四、CentOS / RHEL 系安装
4.1 加 docker-ce 源
| |
4.2 安装
| |
4.3 卸载 CentOS/RHEL
| |
五、官方脚本通用安装
适合任何 Linux 发行版(CentOS、Ubuntu、Debian、Amazon Linux 等),是 Docker 官方最推荐的安装方式之一。
| |
get-docker.sh 会自动检测发行版、加源、装最新稳定版 docker-ce。CentOS 7 系列会自动停用旧版 docker 包,升级到 docker-ce。
六、离线安装
内网 / 无外网环境的标准做法。原理就是先在外网打包好 Docker 的静态二进制 + 依赖 + 配套工具(buildx / docker-compose / cri-dockerd),再传到内网机器解包、注册 systemd unit。
6.1 下载离线包
以 Docker 24.0.7 为例,下载后是一组独立二进制:docker、docker-init、dockerd、runc、ctr、containerd-shim-runc-v2、containerd、docker-proxy。
6.2 解包并安装
| |
2018 时代差异:早期 Docker 还是用
vim /etc/init.d/docker+service docker start+chkconfig docker on三件套。现在统一走 systemd:写/etc/systemd/system/docker.service.d/*.conf覆盖、systemctl daemon-reload、systemctl restart docker。
6.3 配套组件:cri-dockerd(K8s 1.24+ 必装)
Kubernetes 1.24(2022 年 5 月 GA)移除了内置的 dockershim,CRI 改由 containerd / CRI-O 直接对接。如果还想用 Docker 作为 K8s 容器运行时,必须装 cri-dockerd——它把 Docker Engine 重新"翻译"成 CRI 接口给 kubelet 用。
| |
Mirantis 出品:cri-dockerd 是 Mirantis(2019 年接手 Docker Enterprise 的公司)维护的开源项目,所以
Mirantis/cri-dockerd这个 GitHub 路径是规范来源。
6.4 配套组件:buildx(多架构构建)
buildx 是 Docker 公司在 2020 年 9 月推出的 BuildKit CLI 插件,用来取代老的 docker build。它支持:
- 多架构构建:一条命令同时打
linux/amd64和linux/arm64镜像 - 缓存导出:把构建缓存 push 到 registry,下次
docker build直接命中 - BuildKit 高级特性:并发构建、secrets 挂载、SSH 转发
| |
6.5 配套组件:docker-compose v1 / v2 选择
| 版本 | 发布时间 | 形态 | 现状 |
|---|---|---|---|
| Compose v1 | 2014-07 | 独立二进制 docker-compose(Python 写) | 已弃用,2023 年起 Docker Desktop 不再预装 |
| Compose v2 | 2020-08 | Docker CLI 插件 docker compose(空格,无连字符) | 当前推荐,统一走 Go 重写 |
离线安装 Compose v1(如果有遗留项目依赖 v1):
| |
离线安装 Compose v2(推荐):
| |
七、验证安装
任何安装方式,最后都要做这几步验证:
| |
hello-world 能正常打印 “Hello from Docker!” 就算通了。
八、关键配置:daemon.json
/etc/docker/daemon.json 是 Docker Daemon 的主配置文件。90% 的日常配置都在这里。
8.1 推荐模板
| |
8.2 关键字段说明
| 字段 | 作用 | 建议值 |
|---|---|---|
exec-opts.cgroupdriver | cgroup 驱动 | K8s 节点推荐 systemd(与 kubelet 保持一致) |
log-driver | 日志驱动 | 生产环境 json-file 或 journald |
log-opts.max-size | 单个日志文件大小 | 50m 避免撑爆磁盘 |
log-opts.max-file | 保留日志文件数 | 3~5,轮转策略 |
registry-mirrors | 镜像加速器 | 国内服务器必加,否则 docker pull 慢到怀疑人生 |
insecure-registries | 信任的 HTTP 私有仓库 | 内网 registry 才需要,格式 IP:PORT |
live-restore | Daemon 重启时容器不中断 | K8s 节点必须开,否则 kubelet 升级 Docker 就会重启所有 Pod |
storage-driver | 镜像 / 容器分层存储 | overlay2(CentOS 7.4+ / Ubuntu 18.04+ / Debian 10+ 默认) |
8.3 应用配置
| |
进一步可以用 time docker pull nginx:latest 测速,能从几十秒压到几秒就算 mirror 生效。
九、live-restore:K8s 节点的隐藏必修项
Live Restore 是 Docker Daemon 的一项"升级 / 重启不打断容器"的特性。对 K8s 节点来说这是必修项——kubelet 升级、操作系统补丁、daemon 自身重启时,节点上的 Pod 不能因此被重启。
开启方式:
| |
| |
集群环境下,daemon.json 改完用 scp + ssh 推送到所有 master / worker 节点:
| |
十、存储卷(Volume)基础
容器文件系统是分层的、临时的,docker rm 之后容器内的数据就没了。生产数据(数据库、用户上传、配置)必须挂到 volume 上。
| |
-v 挂载用法:
| |
关键警告:
docker volume prune会永久删除未被任何容器引用的卷,里面如果有数据库 / 业务数据,删了就没了——生产环境慎用。删之前先docker volume ls+docker volume inspect逐个确认。
十一、网络模式与网桥清理
11.1 docker0 网桥
Docker 进程启动时,会在主机上创建一个名为 docker0 的虚拟网桥,默认地址 172.17.0.0/16。所有以 Bridge 模式启动的容器都"插"到这个虚拟交换机上,通过 docker0 ↔ 物理网卡 eth0 ↔ 外部网络。
如果想彻底关掉默认网桥(自定义网络场景):
| |
| |
注意:删 docker0 是一次性的——下次 daemon 启动没指定 -b 参数又会自动重建。一般用 daemon.json 里的 bridge: "" 永久关闭更稳妥。
11.2 容器从网桥上摘除
| |
十二、基础清理
跑完一轮测试容器之后,会留下不少"垃圾"。下面是分级清理命令:
| |
核心要点 / 常见坑:
docker system prune --volumes会删未挂载的卷,里面如果残留数据库数据,删了就没了——生产慎用dangling镜像指的是无 tag 的中间层镜像(<none>:<none>),安全可删- 想看"能删多少"先用
docker system df看磁盘占用 docker system df -v还能看到每个 volume / image 占多少空间,方便定位"硬盘杀手"
十三、镜像代理(应对国内拉镜像慢)
拉 Docker Hub / ghcr / gcr / k8s.gcr.io / quay.io 镜像在国内慢到超时是常态。常见做法是用镜像代理做反代。
| 原始 registry | 代理写法(以 dockerproxy.com 为例) |
|---|---|
| Docker Hub | docker pull dockerproxy.com/library/nginx:latest |
| GHCR | docker pull ghcr.dockerproxy.com/username/image:tag |
| GCR | docker pull gcr.dockerproxy.com/username/image:tag |
| k8s.gcr.io / registry.k8s.io | docker pull k8s.dockerproxy.com/coredns:1.6.5 |
| Quay.io | docker pull quay.dockerproxy.com/username/image:tag |
南京大学 GHCR 镜像:
ghcr.nju.edu.cn是国内 GHCR 加速的另一个选择,直接把ghcr.io/xxx替换为ghcr.nju.edu.cn/xxx即可。
如果嫌每个镜像都改前缀麻烦,直接配 daemon.json 的 registry-mirrors(见第八节)就能让所有 docker pull 走代理。
十四、常见问题速查
| 报错 | 原因 | 解决 |
|---|---|---|
permission denied 访问 /var/run/docker.sock | 当前用户不在 docker 组 | sudo usermod -aG docker $USER,重新登录 |
Cannot connect to the Docker daemon | daemon 没起 | systemctl start docker |
WARNING: IPv4 forwarding is disabled | 宿主机没开 ip_forward | echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf,sysctl -p |
unknown or invalid runtime name: docker-runc | 老 docker 升级后 runtime 名变了 | grep -rl 'docker-runc' /var/lib/docker/containers/ | xargs sed -i 's/docker-runc/runc/g',重启 daemon |
K8s 1.24+ 报 failed to create sandbox: cri-dockerd not found | 用了 docker 但没装 cri-dockerd shim | 装 cri-dockerd(见 6.3 节),kubelet 加 --cri-socket=unix:///var/run/cri-dockerd.sock |
kubelet cgroup driver: "cgroupfs" is different from docker: "systemd" | kubelet / docker cgroup driver 不一致 | 双方都改成 systemd:daemon.json 加 "exec-opts": ["native.cgroupdriver=systemd"],kubelet 加 --cgroup-driver=systemd |
image pull failed: toomanyrequests | Docker Hub 匿名拉取限流 | 配 registry-mirrors 走国内 mirror,或登录 Docker Hub 账号 |
十五、小结
把这一篇的要点压缩成 7 条:
- 版本选型:Debian/Ubuntu 优先
docker.io(系统接管依赖),其他发行版走docker-ce官方源,商业场景评估docker-ee/ Mirantis 商业支持 - 离线部署:静态二进制 + systemd unit +
daemon.json,三件套即可;K8s 1.24+ 别忘了cri-dockerd - buildx:2020 年后推荐用
docker buildx,多架构 + 缓存导出 + BuildKit 特性完胜老docker build - Compose v2:用空格
docker compose,v1 已弃用 - 关键配置:
daemon.json的log-driver/log-opts一定要限制大小,否则生产会撑爆磁盘;K8s 节点必须开live-restore - 国内镜像:必须配
registry-mirrors,否则docker pull慢到怀疑人生 - 卸载干净:apt/yum remove 删不干净
/var/lib/docker,重装前手动清掉避免配置残留
下一步:装好 Docker 之后,最常被问到的就是"容器之间怎么通信"、“数据怎么持久化”——这正是下一篇《Docker 进阶与运维:网络模式、存储卷与镜像加速》要展开的内容。
