Linux服务器离线安装Docker完整指南:从原理到实战避坑
1. 项目概述:为什么需要离线安装Docker?
在Linux服务器运维和项目部署的日常工作中,我们常常会遇到一个看似简单却颇为棘手的问题:生产环境或内网服务器无法连接互联网。无论是出于安全策略的硬性规定,还是机房物理隔离的客观条件,这些服务器都处于“离线”状态。此时,如果你需要部署一套基于容器化的应用,比如一个微服务项目,或者一个数据采集系统,安装Docker就成了第一道坎。
“离线安装Docker”这个需求,正是为了解决这个核心矛盾。它不是一个简单的“下载安装包”的过程,而是一个涉及依赖分析、版本匹配、环境准备和手动配置的系统性工程。很多新手运维或者开发者在第一次面对这个问题时,往往会感到无从下手,要么是下载的包版本不对,要么是依赖缺失导致安装失败,要么是安装后服务无法启动。我自己在早期也踩过不少坑,比如在CentOS 7上费劲下载了一堆RPM包,结果因为glibc版本不匹配而前功尽弃。
所以,这篇文章的目的,就是为你梳理出一套清晰、可靠、可复现的Linux环境离线安装Docker的完整方案。我会从原理讲起,告诉你离线安装的本质是什么,然后手把手带你完成从准备离线包到最终验证的每一个步骤,并分享我积累下来的那些“血泪教训”和避坑技巧。无论你面对的是CentOS、Ubuntu还是其他主流的Linux发行版,这套思路都是通用的。
2. 核心原理与准备工作拆解
2.1 理解离线安装的本质:依赖链的本地化
在线安装之所以简单,是因为包管理器(如
yum
、
apt
)帮我们自动解决了依赖关系。你只需要一个命令,它就会从配置好的镜像源拉取Docker安装包及其所有依赖包。而离线安装,就是把这个“拉取”的动作提前,在能联网的机器上模拟一次完整的安装过程,把所有需要的文件(主包、依赖包、配置文件)全部下载到本地,然后打包转移到目标离线服务器上,再通过本地路径进行安装。
这个过程的关键在于 依赖的完整性 。Docker CE(社区版)的依赖可能包括:
-
容器运行时
:如
containerd.io,这是Docker的核心组件之一,负责管理容器的生命周期。 -
Docker引擎
:
docker-ce本身。 -
命令行工具
:
docker-ce-cli。 -
系统依赖
:如
libseccomp(安全计算模式库)、特定版本的systemd或iptables等。
不同的Linux发行版和版本,其软件包格式和依赖树完全不同。例如,CentOS/RHEL及其衍生版(如Rocky Linux、AlmaLinux)使用RPM包,而Debian/Ubuntu使用DEB包。这是准备工作前必须明确的第一点。
2.2 环境侦察与工具选型
在开始之前,你必须像侦察兵一样摸清“敌情”。这包括:
-
目标服务器信息确认 :
-
操作系统及版本
:执行
cat /etc/os-release或lsb_release -a查看。例如,是CentOS Linux 7.9还是Ubuntu 22.04 LTS。 -
系统架构
:执行
uname -m查看。最常见的是x86_64(即AMD64),也可能是aarch64(ARM架构,常见于国产化环境或树莓派)。 -
内核版本
:Docker对内核有要求(一般3.10以上),执行
uname -r查看。虽然离线包不直接依赖内核包,但确保内核支持是前提。
-
操作系统及版本
:执行
-
准备一台同构的联网跳板机 :
- 这是整个流程的基石。你需要一台 能够连接互联网 ,并且 操作系统发行版、主版本号、系统架构与目标离线服务器完全一致 的机器。例如,目标机是CentOS 7.9 x86_64,跳板机也必须是CentOS 7.9 x86_64。这是保证下载的软件包100%兼容的关键。用虚拟机临时搭建一个是最稳妥的办法。
-
选择Docker版本 :
-
访问Docker官方文档,确定一个稳定、兼容的版本。对于生产环境,不建议使用最新的
edge版本,而是选择一个经过考验的稳定版。例如,在写这篇文章时,20.10.x或24.0.x系列都是不错的选择。你可以通过yum list docker-ce --showduplicates(联网环境下)来查看所有可用版本。
-
访问Docker官方文档,确定一个稳定、兼容的版本。对于生产环境,不建议使用最新的
注意 :版本选择上有个小技巧,如果你的应用对Docker版本有特定要求(例如某些旧版编排工具),那就遵循应用要求;如果没有,选择比最新稳定版稍旧一个次版本的版本,通常社区里遇到的坑和解决方案会更多,更稳妥。
3. 实战演练:分步构建离线安装包
接下来,我们以
CentOS 7.x x86_64
系统为例,演示完整的离线包制作与安装过程。Ubuntu/Debian系的思路完全一致,只是包管理命令从
yum
换成了
apt
。
3.1 阶段一:在联网跳板机上操作
这个阶段的目标是创建一个包含所有必要文件的离线包。
3.1.1 环境初始化与仓库配置
首先,在跳板机上清理旧Docker版本(如果有),并添加Docker官方CE仓库。
# 1. 卸载旧版本(如果存在)
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 2. 安装yum工具集,`yum-utils` 提供了 `yumdownloader` 这个关键工具
sudo yum install -y yum-utils
# 3. 添加Docker官方CE仓库
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
3.1.2 下载Docker及其所有依赖
这是核心步骤。我们使用
yumdownloader
命令,它不仅能下载指定的RPM包,还能通过
--resolve
参数自动下载所有依赖。
# 创建一个目录来存放所有下载的包
mkdir -p /opt/docker-offline-packages
cd /opt/docker-offline-packages
# 使用 yumdownloader 下载指定版本的docker-ce, docker-ce-cli, containerd.io 及其所有依赖
# 假设我们选择安装 docker-ce-20.10.24
sudo yumdownloader --resolve docker-ce-20.10.24 docker-ce-cli-20.10.24 containerd.io
执行完上述命令后,当前目录下会多出几十个
.rpm
文件。这些就是Docker运行所需的所有软件包。
实操心得 :
yumdownloader默认会下载当前仓库中最新版本的包。如果你不指定版本,比如只写docker-ce,那么下载的就是最新的。在生产环境中, 强烈建议指定具体版本号 ,这样可以确保离线环境和后续扩容环境的一致性,避免因版本差异导致不可预知的问题。
3.1.3 额外关键:下载
device-mapper-persistent-data
和
lvm2
对于CentOS/RHEL 7,Docker默认的存储驱动曾经是
devicemapper
,虽然新版本默认已改为
overlay2
,但一些旧指南或系统可能仍需要这些依赖。为了确保万无一失,特别是如果你不确定目标服务器的历史配置,最好一并下载。
sudo yumdownloader --resolve device-mapper-persistent-data lvm2
3.1.4 打包与完整性校验
下载完成后,我们需要将这些包和安装脚本一起打包,方便传输。
# 回到上级目录,准备打包
cd /opt
# 创建一个简单的安装脚本模板(稍后会在目标服务器上编辑)
cat > install-docker.sh << 'EOF'
#!/bin/bash
# 离线安装Docker脚本
# 请将此脚本与所有.rpm文件放在同一目录下执行
INSTALL_DIR=$(dirname "$0")
cd $INSTALL_DIR
echo “开始安装Docker离线包...”
# 使用本地路径安装所有rpm包,忽略依赖检查(因为依赖包已全部在本地)
sudo rpm -ivh --nodeps *.rpm
echo “启动Docker服务并设置开机自启”
sudo systemctl start docker
sudo systemctl enable docker
echo “验证安装”
sudo docker --version
EOF
# 给脚本添加执行权限
chmod +x docker-offline-packages/install-docker.sh
# 打包整个目录
tar -czvf docker-offline-20.10.24-centos7.x86_64.tar.gz docker-offline-packages/
现在,
docker-offline-20.10.24-centos7.x86_64.tar.gz
这个文件就是我们的终极离线安装包。你可以通过U盘、内网FTP、或者安全的文件传输工具将其复制到目标离线服务器。
3.2 阶段二:在目标离线服务器上操作
将上一步生成的压缩包上传到目标服务器的某个目录,例如
/tmp
。
3.2.1 解压与预检查
# 1. 切换到上传目录并解压
cd /tmp
tar -xzvf docker-offline-20.10.24-centos7.x86_64.tar.gz
# 2. 进入解压后的目录
cd docker-offline-packages
# 3. (可选但推荐)手动检查内核是否支持overlay2存储驱动
# 这是Docker推荐且性能更好的存储驱动
lsmod | grep overlay
# 如果没有任何输出,需要加载模块
sudo modprobe overlay
# 确认加载成功
lsmod | grep overlay
3.2.2 执行离线安装
直接运行我们准备好的脚本,或者手动执行安装命令。
方法一:使用脚本(推荐)
sudo ./install-docker.sh
脚本会依次安装所有RPM包,启动Docker服务并设置开机自启。
方法二:手动安装 如果你想更清晰地控制过程,可以手动执行:
# 安装所有rpm包
sudo rpm -ivh --nodeps *.rpm
# 启动并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker
关键参数解释 :
rpm -ivh --nodeps中的--nodeps参数表示“不检查依赖”。这是因为我们在跳板机上下载时,已经通过--resolve确保了所有依赖包都在当前目录。如果不用这个参数,rpm命令会去线上仓库查找依赖,在离线环境下必然会失败。
3.2.3 安装后配置与验证
安装完成后,有几项重要的后续工作。
-
验证安装 :
sudo docker --version # 预期输出:Docker version 20.10.24, build 297e128 sudo systemctl status docker # 查看服务状态,应为 active (running) -
配置用户组(非root用户运行Docker) : 默认情况下,执行Docker命令需要
sudo。为了方便,可以将当前用户加入docker用户组。sudo groupadd docker # 如果docker组不存在则创建,通常安装时会自动创建 sudo usermod -aG docker $USER重要 :执行此命令后,需要 完全注销并重新登录 ,或者新开一个终端,用户组更改才会生效。之后,你就可以直接使用
docker ps而不需要sudo了。 -
测试Docker基础功能 :
# 运行一个最简单的测试容器 docker run hello-world如果这个命令能成功执行,并输出 “Hello from Docker!” 等欢迎信息,那么恭喜你,Docker离线安装已经大功告成。
4. 针对不同发行版的策略调整
虽然我们以CentOS为例,但其他发行版的流程大同小异,核心是更换包管理工具。
4.1 Ubuntu/Debian 系统
在Ubuntu跳板机上的操作流程对比如下:
| 步骤 | CentOS/RHEL系 | Ubuntu/Debian系 |
|---|---|---|
| 安装下载工具 |
yum install yum-utils
|
apt install dpkg-dev
(或使用
apt-offline
)
|
| 添加仓库 |
yum-config-manager --add-repo
|
add-apt-repository
或手动编辑
/etc/apt/sources.list.d/docker.list
|
| 下载包及依赖 |
yumdownloader --resolve
|
apt download <package>
配合
apt-cache depends
手动解析,或使用
apt-offline
更佳
|
| 本地安装命令 |
rpm -ivh --nodeps *.rpm
|
dpkg -i *.deb
|
对于Ubuntu,更推荐使用
apt-offline
工具,它能更优雅地生成一个完整的离线安装签名文件(
sig
文件),在目标机上用这个文件来获取所有包。但考虑到通用性,手动下载依赖也是一种可行方案,只是过程更繁琐一些。
4.2 国产化操作系统(如麒麟、统信UOS)
国产系统大多基于CentOS或Ubuntu的某个版本衍生。首先,使用
cat /etc/os-release
命令,找到其“基系统”信息。例如,银河麒麟V10可能基于CentOS 8。然后,按照对应的基系统(CentOS或Ubuntu)的离线安装方法进行。
关键点
在于,Docker官方可能不直接提供该衍生版的仓库,你需要:
- 确认系统自带的仓库或第三方兼容仓库中是否有Docker包。
- 如果没有,尝试使用其基系统对应版本的Docker包(如CentOS 8的包用于麒麟V10),但这存在一定的兼容性风险,务必先在测试环境验证。
5. 高级技巧与深度避坑指南
5.1 存储驱动选择与配置
安装完成后,Docker默认使用的存储驱动未必是最优的。对于CentOS/RHEL 7,如果内核版本 >= 3.10,且文件系统是
xfs
并启用了
ftype=1
,强烈建议使用
overlay2
驱动。
检查并配置overlay2 :
# 1. 检查当前存储驱动
docker info | grep “Storage Driver”
# 2. 如果显示为 devicemapper,建议修改为 overlay2
# 停止Docker服务
sudo systemctl stop docker
# 编辑Docker守护进程配置文件
sudo vi /etc/docker/daemon.json
在
daemon.json
文件中添加以下内容(如果文件不存在则创建):
{
“storage-driver”: “overlay2”
}
保存后,启动Docker:
sudo systemctl start docker
。再次使用
docker info
确认驱动已更改。
踩坑记录 :我曾遇到一个环境,修改为
overlay2后Docker启动失败。原因是/var/lib/docker目录下存在旧的devicemapper数据。解决方法是在修改配置前,先备份并 清理/var/lib/docker目录(sudo rm -rf /var/lib/docker/*)。这是一个危险操作,仅适用于全新安装或可接受数据丢失的环境,生产环境务必谨慎!
5.2 离线环境下的镜像管理
Docker安装好了,但怎么在没有网络的环境下获取镜像呢?答案是: 镜像导出与导入 。
-
在联网机器上拉取并保存镜像 :
docker pull nginx:alpine docker save -o nginx-alpine.tar nginx:alpine -
将
nginx-alpine.tar文件拷贝到离线服务器 。 -
在离线服务器上加载镜像 :
docker load -i nginx-alpine.tar -
验证 :
docker images docker run -d -p 80:80 nginx:alpine
对于复杂的多镜像应用(例如包含web、app、db多个服务的Compose项目),你需要在联网环境将每个镜像都
save
出来,然后到离线环境逐个
load
。也可以使用脚本批量操作。
5.3 常见问题排查实录
即使按照步骤操作,也可能遇到意外。下面是我总结的几个典型问题及解决方案。
| 问题现象 | 可能原因 | 排查与解决思路 |
|---|---|---|
rpm -ivh
安装时报错,提示文件冲突
| 系统中已存在旧版本或冲突的软件包。 | 使用 `rpm -qa |
systemctl start docker
失败,查看日志
journalctl -xe -u docker
发现
”Failed to start Docker Application Container Engine.”
|
1. 存储驱动配置错误(如上述overlay2问题)。
2. 内核模块未加载(如
overlay
、
br_netfilter
)。
3. 防火墙或SELinux阻止。 |
1. 检查
/etc/docker/daemon.json
配置。
2. 执行
sudo modprobe overlay
和
sudo modprobe br_netfilter
手动加载模块,并确保开机自动加载(写入
/etc/modules-load.d/
)。
3. 临时关闭防火墙和SELinux测试:
sudo setenforce 0
和
sudo systemctl stop firewalld
。如果是它们的问题,需要配置放行规则而非简单关闭。
|
执行
docker run hello-world
时提示
”Cannot connect to the Docker daemon…”
| Docker服务未启动,或当前用户没有权限连接Docker socket。 |
1. 确认服务状态:
systemctl status docker
。
2. 确认当前用户是否在
docker
组内:
groups $USER
。如果不在,执行
sudo usermod -aG docker $USER
并
重新登录
。
|
| 在国产化系统上安装后,运行容器性能极差或报错 | 内核兼容性问题,或缺少必要的内核特性支持。 |
1. 检查内核版本和发行版说明,确认官方是否支持该环境。
2. 考虑使用更轻量级的容器方案,如 Podman(其命令行与Docker高度兼容),并寻找对应的离线安装方案。 |
5.4 构建企业级离线镜像仓库
对于需要长期在离线环境部署多个项目的团队,每次都手动
save/load
镜像效率太低。更专业的做法是搭建一个
私有的离线Docker镜像仓库
。
-
在联网环境
:拉取所有需要的镜像,并推送到一个你自己搭建的私有仓库(如使用
registry:2镜像)。 -
将整个私有仓库的数据目录(通常是
/var/lib/registry)打包 。 - 在离线环境 :部署同样的私有仓库容器,并将打包的数据目录解压覆盖。
-
配置离线环境的Docker客户端
,将其镜像仓库地址指向这个内网私有仓库地址(通过修改
/etc/docker/daemon.json中的”insecure-registries”)。
这样,离线环境中的所有机器都可以从这个内网仓库拉取镜像,实现了镜像的集中管理和高效分发。这算是离线Docker使用的进阶玩法了,能极大提升运维效率。
更多推荐
所有评论(0)