ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

docker19.03.9离线部署工具:内网环境最省心的安装方案

docker19.03.9离线部署工具:内网环境最省心的安装方案 简介面向需要在内网或无外网环境完成Docker容器引擎部署的运维人员这份离线工具包以docker19.03.9稳定版为核心有效规避在线安装时网络源不可用、依赖缺失等常见问题。压缩包内含四个文件包括容器引擎镜像压缩包、环境配置模板、系统服务管理单元以及一键执行脚本覆盖了从解压镜像到注册服务、再到按需调整配置的完整部署流程。整体体积约五十七兆字节轻量便携便于在离线网络中拷贝传输和批量推送整个部署过程无需额外下载依赖特别适用于离线机房、内网隔离等场景。已有超过九千人学习下载部署方案经过实际环境验证能够显著减少人工配置步骤与排错时间。模板中还预留了仓库地址、数据目录等参数用户可快速修改适配不同业务场景。1. docker19.03.9离线部署工具内网环境最省心的Docker安装方式一台刚从机房上架的CentOS 7.9服务器贴着“禁止外联”的标签要求你三小时之内把 Docker 19.03.9 跑起来后面还有二十台等着批量铺。这种场景下docker19.03.9离线部署工具就是解决“没有外网却要装指定版本Docker”的标准动作在一台有网的机器上把 Docker 19.03.9 及其全部依赖打成一个自包含目录拷到内网目标机用一条命令完成安装启动。它适合运维、实施工程师也适合在政企内网、物理隔离机房做交付的人。只要内核不低于3.10、架构一致这套方案基本能做到“打包一次批量复用”。2. 离线部署前先想清楚rpm包、静态二进制还是自建Yum源2.1 三种离线部署方案的适用边界和坑先泼一盆冷水离线部署 Docker 19.03.9 不是“把安装包拷过去就行”难在依赖关系的收集。Docker 19.03.9 的安装包依赖一堆系统库和容器运行时不同方案的依赖处理方式完全不同选错方案后多半要从头再来。第一种是抓取 rpm 依赖包方案。在有网机器上配置 Docker 官方仓库用 yumdownloader 把 docker-ce 主包和依赖包全部拉到本地然后拷到目标机器用 rpm 或本地 yum 安装。这个方案的优点是安装过程贴近在线体验系统能自动处理依赖顺序缺点是必须提前考虑到目标系统的版本和架构不能只拷主包。第二种是静态二进制方案。从官方 Release 渠道下载 docker-19.03.9.tgz解压得到 dockerd、docker、containerd、runc 等可执行文件直接放到 /usr/local/bin再手工写一个 systemd 服务。它的优点是包大小小、不依赖 rpm 体系适合没有 yum 的精简系统缺点是要自己维护 systemd、启动参数、存储驱动很多遗漏的坑都是在这里埋下的。第三种是自建 Yum 源。把 rpm 包上传到内网一台服务器或对象存储用 createrepo 生成 repodata然后所有目标机器的 yum 源都指向这个内网地址。这个方案适合几十台、上百台的批量交付后续再装其他软件也好扩展但前期要准备一台源服务器还要考虑 repo 文件分发、GPG 校验、后续版本更新单机场景没必要搞这么重。方案准备成本依赖处理批量友好度最容易翻车的点rpm包依赖目录低yum自动中漏依赖、包架构不符静态二进制中手工处理低systemd/存储配置缺失自建Yum源高yum自动高repo配置错误、元数据过期表格里的三行我都写过。如果你的目标机器是 RHEL/CentOS 系列第一行通常是性价比最高的如果系统太精简连 rpm 都缺才考虑第二行如果内网机器超过二十台第三行值得花半天去搭建。2.2 我为什么建议优先选rpm包依赖目录以 CentOS 7.x 为例docker-ce-19.03.9-3.el7.x86_64.rpm 不是孤立的。它依赖 container-selinux 2.107、containerd.io、docker-ce-cli、docker-ce-rootless-extras往下还依赖 libcgroup、iptables、libtool-ltdl、pigz 等系统包。用在线 yum 安装时这些依赖会被自动拉取到了离线环境它们不会自己冒出来。我见过有人只拷了 docker-ce 过去结果安装时第一行就报Requires: container-selinux 2.107然后卡在那里。抓取 rpm 依赖包方案的好处就在这里yumdownloader 的--resolve选项会帮我们把所有依赖按当前系统解析出来一次性拉到同一个目录。到了目标机器只要目录完整用本地 yum 源就能像在线一样自动安装几乎不需要人工排序。这也是离线部署工具最常见的实现方式。还有一层理由rpm 包安装后systemd 服务、docker.sock、logrotate 配置、bash 补全都是现成的。相比之下静态二进制方案要手工补服务文件还要确认 socket 权限、日志轮转每个细节都容易漏。所以只要目标系统支持 rpm我一般优先选这个方向。2.3 离线部署前的环境采集内核、系统版本、架构一个不能少在准备离线包之前我会先在目标机器上执行几条命令做个环境登记这些输出决定了你去下载哪些包# 在目标机器上执行记录下来再回有网机器上找包 cat /etc/redhat-release uname -m uname -r getenforce rpm -q iptables libcgroup 2/dev/null逐条说明/etc/redhat-release确认是 CentOS 7 还是 8。7 和 8 的 rpm 包名、依赖关系、甚至仓库地址都不一样不能通用。uname -m确认架构是 x86_64 还是 aarch64。Docker 官网的 rpm 包按架构分文件拷错架构的包进去安装时会出现架构冲突。uname -r看内核版本。Docker 19.03.9 对内核最低要求是 3.10CentOS 7 的 3.10.0 系列可以跑但太低会有 overlay2 兼容问题。getenforce查看 SELinux 状态。如果是 Enforcing那么 container-selinux 这个依赖绝对不能少否则 Docker 创建容器时会报 Permission denied。rpm -q iptables libcgroup是为了确认目标机器上已有的包版本避免离线包里重复安装冲突。环境信息采集完成后你还需要确认有网机器上安装了 yum-utils、createrepo 等打包工具。这一步常见误用是直接在目标机器执行 yum 安装结果因为无网失败正确顺序是先在无网机器上采集再到有网机器上准备包最后把包带回。这个过程看起来啰嗦但能省去后面所有“装到一半缺依赖”的麻烦。3. 在有网机器上制作docker 19.03.9离线部署包两条可复现的路径3.1 路径一用yumdownloader把依赖rpm包全部拖下来在有外网权限的机器上推荐用 docker-ce 官方源。先安装打包工具再添加 Docker 仓库最后把 docker19.03.9 和它的依赖全部拉到一个目录。我常用的命令如下# 在有网机器上执行准备 rpm 离线包 sudo yum install -y yum-utils createrepo sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum clean all sudo yum makecache sudo yumdownloader --resolve --destdir/tmp/docker19039 docker-ce-19.03.9-3.el7.x86_64命令背后的逻辑yumdownloader 的--resolve会读取当前系统的 yum 依赖关系把 docker-ce 需要的全部 rpm 下载到--destdir指定目录。这里有一个容易被忽略的细节下载机器的系统版本和目标机器越接近越好。如果你在一台 CentOS 8 上下载 CentOS 7 的包依赖解析很可能不对拉下来的包要么多要么少。参数说明docker-ce-19.03.9-3.el7.x86_64是 CentOS 7 x86_64 的完整包名。如果目标系统是 CentOS 8包名中的el7要换成el8依赖关系也会变成 containerd 1.2 以上版本必须重新解析。如果是 aarch64 架构则用aarch64后缀且下载机器也必须是 aarch64 系统否则依赖解析不准确。下载完成后不要急着拷贝先做一个自检# 确认所有依赖已经完整并生成 repodata ls /tmp/docker19039 | grep -E docker-ce|containerd|container-selinux sudo createrepo --update /tmp/docker19039ls检查主包是否存在createrepo生成 repodata 元数据。这一步可以让很多直接rpm -ivh的翻车现场免掉——yum 会按 repodata 正确排序而 rpm 手动安装顺序一错就会报循环依赖。另外说一句如果你下载时发现 yumdownloader 把系统自带的旧版本 docker 依赖也拉进来了不要慌。只要目标机器的 yum 源只有这个本地目录它就会在这个目录里解析依赖不会跑回系统库找。3.2 路径二直接下载官方静态二进制并做最小systemd单元有的内网机器用的是精简 CentOS连 rpm 包管理都没有完整依赖甚至 yum 源都不全这时静二进制方案更直接。从 Docker 官方 Release 渠道下载docker-19.03.9.tgz解压后结构大致是docker/ ├── docker ├── dockerd ├── docker-init ├── docker-proxy ├── containerd ├── containerd-shim ├── ctr └── runc我把这些可执行文件全部放到/usr/local/bin然后手工创建 systemd 服务。需要指出的是官方 tgz 包里的 docker 版本和 rpm 包并不完全等同19.03.9 的静态包需要手动指定 Cgroup 驱动为 systemd否则容器内存控制会不准。下面是一个能用的最小docker.service[Unit] DescriptionDocker Application Container Engine Afternetwork-online.target firewalld.service containerd.service Wantsnetwork-online.target [Service] Typenotify ExecStart/usr/local/bin/dockerd ExecReload/bin/kill -s HUP $MAINPID LimitNOFILE1048576 LimitNPROCinfinity LimitCOREinfinity TimeoutStartSec0 Restartalways StartLimitBurst3 [Install] WantedBymulti-user.target这个 service 文件有几个关键点Typenotify表示 docker daemon 启动完成后会通过 sd_notify 通知 systemd避免systemctl start卡住不返回。ExecStart明确指向/usr/local/bin/dockerd因为静态包没有 rpm 安装的/usr/bin/dockerd。LimitNOFILE1048576要求把文件描述符上限拉高否则容器一多就会报 “too many open files”。Restartalways保证 Docker 因 OOM 或崩溃被 kill 后能自动拉起这是生产环境的基本习惯。创建完 service 文件后还需要配置/etc/docker/daemon.json内容会在第四章详细说。静态二进制方案最大的坑在于很多人解压后只拷贝了 docker 和 dockerd漏掉了 docker-proxy导致端口映射时容器起来但外部访问失败。所以建议解压后直接整个目录复制到目标机器再用ln -sf建立软链接。3.3 离线包目录结构设计和自检清单不管用哪条路径最后离线工具包的结构要清楚。我一般做成这样docker19.03.9-offline/ ├── packages/ # 存放所有rpm包或静态二进制的子目录 ├── install.sh # 主安装脚本自动完成所有步骤 ├── docker.service # systemd单元静态二进制方案用 ├── daemon.json # 镜像加速、日志、存储配置 ├── images/ # 预导出的镜像tar包 └── README.md # 写明目标系统版本和架构packages目录在 rpm 方案下需要有repodata/子目录否则无法作为本地 yum 源在二进制方案下则直接放解压后的 docker 目录。images目录用来存放docker save导出的镜像内网环境拉不了镜像这一步必须在有网机器上提前做好。自检清单就三条目标机架构和离线包架构一致用uname -m对过。所有依赖 rpm 包都在没有遗漏用rpm -Uvh --test提前模拟安装。daemon.json 里没有写死内网 DNS 或某台机器的 IP避免换机器后启动不了。完整性校验的做法是在有网机器打 tar 包时同时生成 sha256 校验文件目标机器解压后执行sha256sum -c sha256sum.txt。这一步看起来多余但能避免因为 scp 中断导致 docker.service 文件半截systemd 报 parse 错误却找不到原因。4. 目标机器安装从拷贝到docker info全绿的完整命令序列4.1 最小安装命令一条脚本完成依赖安装与启动离线包拿到目标机器后最常见的失败原因是目标机器上没有对应版本的 docker-ce 源。我的做法是先把packages目录拷到/opt/docker19.03.9-offline/packages然后写入一个本地 repo 文件让 yum 只从这个离线目录安装# 目标机器上执行配置本地仓库并安装 sudo mkdir -p /opt/docker19039 sudo cp -r packages/ /opt/docker19039/ sudo tee /etc/yum.repos.d/docker-local.repo EOF [docker-local] namedocker-local baseurlfile:///opt/docker19039/packages enabled1 gpgcheck0 EOF sudo yum clean all sudo yum makecache sudo yum install -y docker-ce-19.03.9 sudo systemctl start docker sudo systemctl enable docker这段命令的逻辑是先用baseurlfile://把离线包目录变成 yum 能识别的本地源再用yum install docker-ce-19.03.9让 yum 自动解析依赖。yum clean all和yum makecache必须成对出现否则旧缓存会让 yum 找不到新源里的包。参数说明gpgcheck0是离线环境下的便利解法前提是离线包来源可控。如果公司安全规范要求开启签名校验需要在打包时把 GPG 公钥也放入目录并在 repo 文件中用gpgkeyfile:///opt/docker19039/RPM-GPG-KEY-docker指定。我在实际项目里两种都写过后者在审计时更容易通过。安装过程中如果看到No more mirrors to try说明 yum 在本地源里找不到某个依赖。这时不要急着换源先确认/opt/docker19039/packages目录下是否有repodata子目录。有的同事喜欢用 tar 打包时排除隐藏文件结果 repodata 没拷全yum 缓存也重建不了。重新把 repodata 完整拷贝过去再执行yum clean all yum makecache就能解决。4.2 配置镜像加速器、数据目录和日志轮转的常见做法安装完成后不要立刻投入使用先配置/etc/docker/daemon.json。Docker 19.03.9 的默认数据目录在/var/lib/docker日志默认无限增长这两个在生产环境都是定时炸弹。我的标配sudo mkdir -p /etc/docker /data/docker sudo tee /etc/docker/daemon.json EOF { data-root: /data/docker, exec-root: /var/run/docker, log-driver: json-file, log-opts: { max-size: 50m, max-file: 5 }, storage-driver: overlay2, storage-opts: [ overlay2.override_kernel_checktrue ] } EOF sudo systemctl restart docker># 第一分钟确认daemon配置和驱动状态 docker info | grep -E Cgroup|Storage|Server Version docker info | grep -A 2 Overlay # 第二分钟启动一个测试容器 docker run --rm busybox:latest sh -c echo ok sleep 1 # 第三分钟验证bridge网络和端口映射 docker network create -d bridge testnet docker run -d --name nginx-test --network testnet -p 8080:80 nginx:1.19-alpine curl -s http://127.0.0.1:8080/ docker network rm testnet第一分钟的重点是看Cgroup Driver是否显示 systemd。19.03.9 在某些环境下会退化成 cgroupfs导致容器内存限制不精确需要通过 daemon.json 的exec-opts: [native.cgroupdriversystemd]修正。第二分钟用 busybox 跑个小命令能过说明容器运行时和镜像加载都没问题。第三分钟真正要测的是端口映射链路因为 curl 通不通取决于 iptables 规则是否正常这比单纯docker ps有意义得多。离线环境里没有现成的 nginx 镜像那就在有网机器上先把镜像 save 下来放进images目录再用docker load导入。离线镜像导入命令可以批量做把images目录下的 tar 包逐一 load然后 grep 输出中的Loaded image确认是否带 tag。如果发现有镜像没有 tag用docker tag补齐后再执行后续编排。这里的验证逻辑是一样的容器能不能起、端口能不能通、网络能不能用只看版本号是看不出来的。5. docker 19.03.9离线部署避坑指南5个翻车现场和对应解法5.1 现象安装时卡在依赖报错libltdl.so.7找不到我最早做离线包时在目标机器执行完yum install再跑docker version直接报error while loading shared libraries: libltdl.so.7。原因是 docker-ce 的 rpm 包依赖 libtool-ltdl 这个系统库而我的离线包只收集了 docker 主包和它的直接依赖把这个间接依赖漏了。原因yumdownloader 的--resolve在部分 CentOS 源里不会把 libtool-ltdl 这类不在 docker 官方仓库、而在 Base 源里的包拉全尤其是有网机器已经装过同版本库的时候。解决在有网机器上单独把 libtool-ltdl 拉下来加进离线包yumdownloader --resolve --destdir/tmp/docker19039 libtool-ltdl sudo createrepo --update /tmp/docker19039然后把整个 packages 目录重新拷贝到目标机器再次yum install docker-ce-19.03.9就会自动装上。这个坑提醒我离线包的依赖检查不能只看 docker-ce 的 Requires 字段还要用ldd检查 docker 二进制依赖的 .so 文件。5.2 现象systemd启动Docker失败提示iptables chain不存在目标机器执行systemctl start docker后报错里出现类似Failed to create docker-up: iptables: No chain/target matching by that name。第一次遇到时我以为是 iptables 服务没启动反复重启 iptables 也没用。原因Docker 19.03.9 启动时会操作DOCKER-USER、FORWARD等链但它要求的这些链需要由 firewalld 或 iptables 服务先创建。目标机器上 firewalld 虽然 enabled但内核 nftables 接管了规则集旧版 iptables 工具读写的是 nft 兼容层两边链表不同步。解决先确认 firewalld 状态然后按顺序重启sudo systemctl restart firewalld sudo systemctl restart docker如果还不行直接放开 FORWARD 链默认策略sudo iptables -P FORWARD ACCEPT不过这个操作在生产环境要先和网络安全负责人确认。更彻底的做法是在 systemd unit 里给 docker 加Afterfirewalld.service并让 docker 服务启动前先触发 firewalld 的规则生成。这类问题属于离线部署里的常见玄学建议看journalctl -u docker -n 50结合排查。5.3 现象部署后容器网络不通ping不通网关容器能创建但进入容器后ping 192.168.1.1不通宿主机的端口映射也无法访问。这条坑在离线环境里特别常见因为最小化安装的系统默认关闭了 IP 转发。原因Docker 的 bridge 网络依赖net.ipv4.ip_forward1CentOS 默认值为 0。在线 yum 安装时这个参数通常会被网络服务脚本改掉离线环境没人管它。解决先确认参数再写入内核参数文件sysctl net.ipv4.ip_forward echo net.ipv4.ip_forward 1 /etc/sysctl.conf sysctl -p systemctl restart docker另外还要检查br_netfilter模块是否加载桥接 iptables 规则需要它modprobe br_netfilter echo br_netfilter /etc/modules-load.d/docker.conf这两个检查做完容器网络基本就通了。如果你的系统开启了 nftables 且 FORWARD 默认 DROP还要在上游防火墙里放行 docker 网段这是另一个层面的问题和 docker 本身无关。5.4 现象离线导入的镜像tar包tag丢失在有网机器上执行docker save -o busybox.tar busybox:latest到目标机器docker load -i busybox.tar后docker images里看到的是none:none。这个问题我在一次交付中碰到导致后面的 compose 文件全部启动失败。原因docker save保留的是镜像元数据里的 tags但如果你 save 时用的是镜像 ID如docker save -o busybox.tar 123456789保存的就是一个无名镜像或者源镜像本身就没有 tag。另外docker load不会自动把none改成名字。解决load 完成后人工补 tagdocker tag $(docker load -i busybox.tar | grep -o sha256:.* | cut -d: -f2) busybox:latest但这种写法很绕不如在 save 时养成习惯docker save -o busybox.tar docker.io/library/busybox:latest看到 load 输出提示Loaded image: busybox:latest就是带了 tag。镜像 tar 包也是离线部署工具的一部分建议每次打包镜像时用完整的仓库名不要偷懒用 ID。5.5 现象yumdownloader在CentOS 8.x上默认拉取的是podman-dockerCentOS 8 系统自带的软件源里有一个podman-docker它提供一个基本兼容 docker 命令的工具让你误以为 docker 装好了。我在做 CentOS 8.5 离线包时下载命令写得很宽泛结果目标机器装完跑docker versionCLI 能执行但 daemon 是 podman 套壳容器运行时路径全都不对。原因CentOS 8 的 AppStream 源开启了 module 流且系统默认启用了container-tools模块该模块把 docker 指到了 podman-docker。yumdownloader 解析时如果没有指定确切版本优先命中了模块流里的包。解决下载时把版本号写满并显式指定架构yumdownloader --resolve --destdir/tmp/docker19039 docker-ce-19.03.9-3.el8.x86_64同时在目标机器上禁用无关模块防止被串包sudo dnf module disable -y container-tools离线部署工具在 CentOS 8 上比 CentOS 7 更容易出现“感觉装了但用不了”的问题根本原因是包管理器的模块流机制太活跃版本号不写死就会翻车。6. 落地后的进阶技巧把离线包做成可复用脚本顺手验证内核参数当离线包从“一次性安装”变成“批量交付工具”install.sh 就不该只是几条命令的拼凑。我会在脚本开头做环境预检在结尾做运行验证并让每个关键步骤输出日志。# install.sh 的关键开头片段 set -e [ -f /etc/redhat-release ] || { echo 仅支持RHEL/CentOS; exit 1; } [ $(uname -m) x86_64 ] || { echo 仅支持x86_64; exit 1; } modprobe overlay || true modprobe br_netfilter || true sysctl -w net.ipv4.ip_forward1 /dev/nullmodprobe br_netfilter和sysctl -w net.ipv4.ip_forward1必须放在 Docker 启动之前这是 5.3 节网络问题的预防动作。把set -e放在脚本开头后任何一条安装命令失败都会立即退出避免装了一半还继续执行后面操作把现场搞得更乱。脚本尾部我还习惯加入一段自检echo 开始验证 Docker 19.03.9 docker info /tmp/docker-info.log 21 echo daemon ok || echo daemon failed这里的关键不是输出 ok 还是 failed而是把docker info日志留档。后续如果需要定位问题/tmp/docker-info.log里已经记录了版本、存储驱动、Cgroup 驱动不用再重跑命令。我自己的经验是版本管理一定要覆盖离线包。把 daemon.json、docker.service 和 install.sh 全部纳入 git升级到 20.10 或 24.x 时直接 diff 这几个文件能快速看出新版本有哪些配置项被弃用。有一次我在新项目里直接复制了 19.03.9 的 daemon.json结果新版 Docker 把exec-root字段改成了containerd命名空间启动直接失败。从那次以后我只在目标机器内核和系统版本完全一致时复用旧包其余情况都重新走一遍打包流程。希望帮到你。本文还有配套的精品资源点击获取
返回列表