简介:这份资源面向需要在无外网或内网环境中部署容器运行时的运维与开发人员,提供 Docker 24.0.5 的离线安装方案,解决服务器无法联网拉取依赖、安装过程反复报错的痛点。压缩包共 18 个文件,以 17 个 rpm 依赖包和 1 个 install_docker.sh 安装脚本为主,整体约 108.02MB,其中 rpm 覆盖 docker-ce、containerd、docker-compose-plugin、docker-buildx-plugin 以及 container-selinux、fuse-overlayfs 等系统依赖,脚本则负责统一编排安装流程。资源描述提示执行脚本即可完成部署,并特别说明脚本需执行两遍、安装后 Docker 会自动启动,同时包内已附带 docker compose 命令,省去额外配置环节。目前已有 935 人学习下载,适合希望快速在离线 CentOS 7 环境搭建 Docker 与 Compose 的读者参考使用。
1. 内网环境下的 Docker 24.0.5 离线部署:从踩坑到落地
很多做交付的同行都遇到过这种场景:客户机房完全隔离,没有外网,但业务又必须跑在容器里。这时候apt install docker-ce或者yum install docker-ce直接歇菜,因为包管理器根本连不上源。Docker 24.0.5 这个版本在离线场景里出镜率很高,它属于 24.x 稳定分支,containerd 和 runc 的版本搭配比较成熟,不像 25.x 刚出来那会儿有些内核兼容性的玄学问题。所谓离线安装,本质就是把 Docker 的静态二进制包、systemd 单元文件、containerd 运行时、runc 以及 CLI 插件全部提前准备好,拷贝到目标机器上按顺序铺开。这套流程适合两类人:一是经常跑内网交付的实施工程师,二是需要在无网环境下快速搭建 CI 构建节点的运维。下面我把整个链路拆开,从包结构到 systemd 接管,再到验证和排错,一步步走一遍。
2. 离线包结构拆解:二进制、单元文件与依赖链
2.1 静态包和动态包的区别,为什么选静态
Docker 官方提供的离线包分两种形态:一种是docker-24.0.5.tgz这种静态二进制压缩包,另一种是docker-ce-24.0.5-1.el7.x86_64.rpm这类发行版包。静态包的好处是不依赖目标机器的 glibc 版本和包管理器,解压就能用,适合异构环境。动态包走 rpm/deb 安装,依赖链清晰但要求目标机器有对应的包管理器和依赖库。
我一般在内网交付时优先选静态包,原因很简单:你永远不知道客户机器上跑的是 CentOS 7.6 还是 Ubuntu 18.04,glibc 版本差异会导致动态包直接报GLIBC_2.28 not found。静态包把 dockerd、docker、containerd、runc、docker-proxy 这些二进制全打在一起,解压后手动铺到/usr/bin就行。
静态包解压后的目录结构大致是这样:
docker/ ├── docker ├── dockerd ├── containerd ├── containerd-shim-runc-v2 ├── ctr ├── runc ├── docker-init ├── docker-proxy └── dockerd-rootless.sh这些文件里,dockerd是守护进程主程序,docker是 CLI 客户端,containerd和runc是容器运行时,docker-proxy负责端口映射。缺一个都跑不起来。
2.2 依赖链梳理:containerd、runc 与 systemd 单元
Docker 24.0.5 的运行时依赖链是:dockerd 调用 containerd,containerd 调用 containerd-shim-runc-v2,shim 再调用 runc 去真正创建容器进程。所以离线部署时,这四个二进制必须版本匹配。Docker 24.0.5 官方捆绑的 containerd 版本是 1.7.x 系列,runc 是 1.1.x 系列。如果你从别处拷了一个老版本 runc 混用,会出现容器启动后立刻退出、docker ps看不到进程的现象。
systemd 单元文件有两个:docker.service和docker.socket。docker.socket用于 socket 激活,docker.service是主服务。离线环境下我通常只启用docker.service,把 socket 激活关掉,避免因为 socket 文件权限问题导致守护进程起不来。
单元文件里几个关键参数需要根据内网环境调整:
| 参数 | 默认值 | 内网建议值 | 说明 |
|---|---|---|---|
ExecStart | /usr/bin/dockerd -H fd:// | /usr/bin/dockerd | 去掉 fd:// 避免 socket 依赖 |
LimitNOFILE | infinity | 1048576 | 内网老内核可能不支持 infinity |
TimeoutStartSec | 0 | 300 | 避免启动超时被 systemd 杀掉 |
这些参数不改也能跑,但内网机器内核版本参差不齐,改一下能省掉很多排查时间。
3. 离线安装实操:从解压到 systemd 接管
3.1 二进制铺开与权限设置
假设你已经把docker-24.0.5.tgz拷到了目标机器的/tmp目录。第一步是解压并铺二进制:
# 解压静态包 tar -xzvf /tmp/docker-24.0.5.tgz -C /tmp/ # 把二进制拷贝到 /usr/bin cp /tmp/docker/* /usr/bin/ # 给可执行权限 chmod +x /usr/bin/docker \ /usr/bin/dockerd \ /usr/bin/containerd \ /usr/bin/containerd-shim-runc-v2 \ /usr/bin/ctr \ /usr/bin/runc \ /usr/bin/docker-init \ /usr/bin/docker-proxy # 验证版本 docker --version dockerd --version containerd --version runc --version这里有个细节:containerd-shim-runc-v2必须放在/usr/bin下,因为 containerd 默认从 PATH 里找它。如果你放到/usr/local/bin,需要改 containerd 配置或者加软链接。我一般直接全放/usr/bin,省事。
版本验证输出应该类似:
Docker version 24.0.5, build ced0996 dockerd version 24.0.5, build ced0996 containerd version 1.7.20 runc version 1.1.12如果runc --version报runc: command not found,检查是不是漏拷了。如果报symbol lookup error,说明 glibc 版本不匹配,得换静态编译版本。
3.2 systemd 单元文件配置与启动
二进制铺好后,需要配置 systemd 接管。创建/etc/systemd/system/docker.service:
[Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network-online.target firewalld.service Wants=network-online.target [Service] Type=notify ExecStart=/usr/bin/dockerd ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=1048576 LimitNPROC=infinity LimitCORE=infinity TimeoutStartSec=300 Restart=on-failure StartLimitBurst=3 StartLimitInterval=60s [Install] WantedBy=multi-user.target注意ExecStart这里我去掉了-H fd://,因为离线环境下 socket 激活经常出问题。如果你确实需要 socket 激活,可以保留,但要确保docker.socket文件也配置正确。
然后重载 systemd 并启动:
# 重载 systemd 配置 systemctl daemon-reload # 启动 Docker systemctl start docker # 设置开机自启 systemctl enable docker # 查看状态 systemctl status docker如果启动失败,用journalctl -u docker -n 50 --no-pager看日志。最常见的报错是failed to start daemon: error initializing graphdriver: driver not supported,这是因为内核不支持 overlay2,需要降级到vfs或者升级内核。
3.3 配置 daemon.json 与镜像加速
内网环境下,Docker 默认会去 Docker Hub 拉镜像,但没网肯定拉不动。你需要提前把需要的镜像docker save成 tar 包,拷到目标机器后docker load。但在此之前,先配好/etc/docker/daemon.json:
{ "data-root": "/var/lib/docker", "storage-driver": "overlay2", "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" }, "exec-opts": ["native.cgroupdriver=systemd"], "registry-mirrors": [], "insecure-registries": ["192.168.1.100:5000"], "live-restore": true }几个关键参数说明:
>systemctl restart docker docker info | grep -E "Storage Driver|Cgroup Driver|Docker Root Dir"输出应该显示
overlay2、systemd和你的># 导入镜像 docker load -i /tmp/nginx-1.25.tar # 查看镜像列表 docker images # 跑一个测试容器 docker run -d --name test-nginx -p 8080:80 nginx:1.25 # 验证容器状态 docker ps # 验证端口映射 curl http://127.0.0.1:8080如果
docker load报open /var/lib/docker/tmp/...: no space left on device,说明>#!/bin/bash # 批量导出镜像并推送到内网 registry REGISTRY="192.168.1.100:5000" IMAGES=( "nginx:1.25" "redis:7.2" "mysql:8.0" "openjdk:17-slim" ) for img in "${IMAGES[@]}"; do # 拉取镜像 docker pull "$img" # 打内网标签 docker tag "$img" "$REGISTRY/$img" # 推送到内网仓库 docker push "$REGISTRY/$img" echo "Pushed $img to $REGISTRY" done这个脚本在有网机器上跑,把镜像推到内网 registry。内网机器只需要配好
insecure-registries,直接docker pull 192.168.1.100:5000/nginx:1.25就行。版本锁定方面,我习惯在
/etc/docker/daemon.json里加"runtimes"配置,把 runc 路径写死:{ "runtimes": { "runc": { "path": "/usr/bin/runc" } }, "default-runtime": "runc" }这样即使系统里装了多个 runc,Docker 也只用你指定的那个。另外,把
docker --version、containerd --version、runc --version的输出记到部署文档里,下次出问题先对版本号。验证离线部署是否彻底成功,我一般跑一个 checklist:
检查项 命令 预期结果 Docker 版本 docker versionClient 和 Server 都是 24.0.5 存储驱动 docker info | grep "Storage Driver"overlay2 或 vfs Cgroup 驱动 docker info | grep "Cgroup Driver"systemd 容器运行 docker run --rm hello-world输出 Hello from Docker! 端口映射 docker run -d -p 8080:80 nginxcurl 127.0.0.1:8080返回欢迎页开机自启 systemctl is-enabled dockerenabled 这套流程我在多个内网项目里跑过,最常翻车的地方就是存储驱动和 runc 版本。从那以后我每次离线部署前,都强制先在目标机器上
modprobe overlay和ldd /usr/bin/runc走一遍,确认内核和依赖没问题再铺二进制。希望帮到你。本文还有配套的精品资源,点击获取