ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Docker 19.03.9 离线部署全攻略:从原理到实战,解决内网环境容器化难题

Docker 19.03.9 离线部署全攻略:从原理到实战,解决内网环境容器化难题 简介容器化技术已成为现代软件开发和部署的基础设施其核心在于通过容器引擎实现应用及其依赖的标准化打包与隔离运行。Docker作为最流行的容器引擎其工作原理基于客户端-服务器架构通过镜像分层存储和联合文件系统实现高效部署。在金融、军工、工业等对网络安全有严格要求的领域内网隔离环境成为常态这使得标准的在线安装和镜像拉取流程无法进行。Docker离线部署工具正是为解决这一痛点而生它通过预先打包二进制文件、系统依赖和容器镜像实现了在完全隔离网络中的自主部署。本文以稳定版本Docker 19.03.9为例深入解析其离线部署的核心组件与自动化脚本涵盖从环境准备、依赖分析到安全配置的全流程为运维工程师在内网环境实施容器化提供了一套经过验证的工程实践方案。1. 为什么我们需要一个离线部署工具在容器化技术已经成为基础设施标配的今天Docker 几乎是每个开发者、运维工程师和架构师绕不开的工具。无论是用于本地开发环境搭建、CI/CD 流水线构建还是生产环境的微服务部署Docker 都扮演着核心角色。然而在实际的企业级落地过程中尤其是在一些特定场景下我们常常会遇到一个非常棘手的问题网络隔离。想象一下你负责为一家金融机构、一个保密级别较高的研发实验室或者一个位于偏远地区的工厂部署一套基于容器的应用系统。这些环境往往出于安全或物理限制与外网完全隔离即我们常说的“离线环境”或“内网环境”。在这种环境下你无法直接执行docker pull从 Docker Hub 或任何公有镜像仓库拉取镜像也无法通过apt-get install或yum install在线安装 Docker 引擎本身及其依赖。一切操作都必须基于预先准备好的离线介质来完成。这就是“Docker 19.03.9 离线部署工具”诞生的背景。它不是一个官方工具而是社区和企业在实践中为了解决这个痛点而总结出来的一套方法论和脚本集合。选择 19.03.9 这个特定版本通常是因为它是在 Docker 19.03.x 这个长期支持LTS分支中的一个稳定版本被许多生产系统所采用其稳定性和兼容性经过了时间的考验。这个工具的核心目标就是让你能在一台完全离线的 Linux 服务器上从零开始成功安装并运行指定版本的 Docker 引擎。2. 离线部署工具的核心组件与工作原理一个完整的 Docker 离线部署工具包远不止一个 Docker 的二进制安装文件那么简单。它需要是一个自包含的、能够处理依赖关系的完整解决方案。下面我们来拆解它的核心组件和工作原理。2.1 核心组件清单一个典型的离线部署工具包应该包含以下内容Docker 引擎二进制文件这是最核心的部分即dockerdDocker 守护进程和dockerDocker 客户端命令行工具的可执行文件。对于 19.03.9 版本我们需要对应操作系统架构如 x86_64, aarch64的特定文件。容器运行时二进制文件Docker 默认使用containerd作为其容器运行时。从 19.03 版本开始containerd是独立于 Docker 引擎发布的因此必须单独准备其二进制文件。系统服务配置文件用于将 Docker 守护进程注册为系统服务如 systemd 服务确保其能开机自启和受系统管理。这通常包括一个docker.service文件。依赖库文件Docker 和 containerd 的运行可能依赖一些特定的系统共享库如libseccomp,libdevmapper等。在离线环境下如果目标服务器的系统版本较老或缺少这些库就需要将它们一并打包进来。镜像归档文件这是离线部署的另一个关键。你需要将应用所需的所有 Docker 镜像如nginx:alpine,redis:6.2, 你自己的应用镜像等预先在联网环境通过docker save命令打包成.tar文件并随工具包一起携带。部署脚本一个或多个 Shell 脚本用于自动化执行以下步骤检查环境、安装依赖库、复制二进制文件、配置系统服务、加载镜像等。好的脚本应该具备幂等性即重复执行不会导致错误和良好的错误处理与日志输出。2.2 工作原理从在线到离线的“搬运”过程这个工具的本质是将在线环境下的标准安装和配置过程“固化”下来并搬运到离线环境。其工作流程可以概括为以下几步第一步在线环境准备打包阶段在一台可以联网的、操作系统版本与目标离线服务器尽可能一致的机器上我们称之为“打包机”完成以下操作从 Docker 官方 GitHub Release 页面或国内镜像站下载指定版本19.03.9的 Docker 引擎和 containerd 的静态二进制包。分析这些二进制文件的依赖关系使用ldd命令将目标系统可能没有的动态链接库收集起来。使用docker save -o命令将所有需要的应用镜像导出为.tar文件。编写部署脚本并将所有上述文件二进制、库、镜像tar包、脚本、服务文件整理到一个目录结构中最后打包成一个压缩文件如docker-offline-19.03.9.tar.gz。第二步离线环境部署解压执行阶段通过U盘、内网共享或任何其他物理介质将打包好的压缩文件传输到目标离线服务器。解压工具包。执行部署脚本。脚本会将二进制文件复制到系统路径如/usr/bin/。将依赖库文件复制到系统库路径如/usr/lib64/。注册并启动 Docker 系统服务。使用docker load -i命令将镜像归档文件导入到本地 Docker 镜像仓库。整个过程结束后目标服务器上就拥有了一个功能完整的 Docker 19.03.9 环境并且所需的镜像也已就绪可以直接通过docker run启动容器。3. 手把手构建你自己的 Docker 19.03.9 离线工具包理论讲清楚了我们进入实战环节。我将以 CentOS 7.x (x86_64) 为例演示如何从零开始构建一个离线部署工具包。你可以根据这个思路适配到 Ubuntu、RHEL 等其他发行版。3.1 环境准备与文件下载首先找一台可以联网的 CentOS 7 机器作为打包机。# 1. 创建一个工作目录 mkdir -p ~/docker-offline-19.03.9 cd ~/docker-offline-19.03.9 # 2. 下载 Docker 19.03.9 静态二进制包 # 官方地址可能较慢可以使用国内镜像这里以官方为例 wget https://download.docker.com/linux/static/stable/x86_64/docker-19.03.9.tgz # 3. 下载对应版本的 containerd 静态二进制包 # 需要去 GitHub releases 页面查找例如 wget https://github.com/containerd/containerd/releases/download/v1.3.7/containerd-1.3.7-linux-amd64.tar.gz # 注意19.03.9 通常与 containerd 1.2.x 或 1.3.x 兼容需根据官方文档确认。这里以1.3.7为例。 # 4. 下载 docker-compose可选但强烈建议包含 # 检查最新版本号这里以1.29.2为例 wget https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_643.2 分析依赖与收集系统库解压 Docker 二进制包并分析其依赖。# 解压 Docker tar -xzvf docker-19.03.9.tgz # 解压后得到一个 docker/ 目录里面包含 dockerd 和 docker 等二进制文件 # 使用 ldd 检查动态链接库依赖 cd docker ldd dockerd docker查看ldd的输出你会看到类似以下的依赖列表。重点关注那些非系统核心的库如libseccomp,libdevmapper。linux-vdso.so.1 (0x00007ffd3c3f0000) libpthread.so.0 /lib64/libpthread.so.0 (0x00007f8b6a200000) libdl.so.2 /lib64/libdl.so.2 (0x00007f8b69ffc000) libc.so.6 /lib64/libc.so.6 (0x00007f8b69c3a000) /lib64/ld-linux-x86-64.so.2 (0x00007f8b6a41c000) libseccomp.so.2 /lib64/libseccomp.so.2 (0x00007f8b699f6000) # 需要关注 libdevmapper.so.1.02 /lib64/libdevmapper.so.1.02 (0x00007f8b697a3000) # 需要关注 ...如果目标离线服务器是全新的最小化安装很可能缺少libseccomp和libdevmapper。我们需要将它们从打包机复制出来。# 回到工作目录 cd ~/docker-offline-19.03.9 # 创建用于存放依赖库的目录 mkdir -p system-libs # 拷贝关键依赖库。请根据你 ldd 的实际输出路径进行拷贝。 # 注意使用 cp -L 拷贝实际文件而不是软链接。 cp -L /lib64/libseccomp.so.2 system-libs/ cp -L /lib64/libdevmapper.so.1.02 system-libs/ # 有时还需要拷贝这些库所依赖的其他库可以写一个简单的脚本来收集 # 这里提供一个基础思路你可以根据需要完善 for lib in $(ldd docker/dockerd docker/docker | grep -v linux-vdso | grep -v ld-linux-x86-64 | awk {print $3} | sort -u); do if [ -f $lib ]; then cp -L $lib system-libs/ fi done3.3 准备系统服务文件Docker 官方提供了 systemd 的 service 文件。我们可以直接从其 GitHub 仓库获取或者从一台已在线安装 Docker 的机器上拷贝。# 创建服务配置目录 mkdir -p systemd-service # 方法一从在线安装的机器获取如果有的话 # scp useronline-host:/usr/lib/systemd/system/docker.service systemd-service/ # 方法二手动创建或从官方源码获取。这里提供一个 19.03.9 版本可用的简化模板。 # 将以下内容保存为 systemd-service/docker.service cat systemd-service/docker.service EOF [Unit] DescriptionDocker Application Container Engine Documentationhttps://docs.docker.com Afternetwork-online.target firewalld.service containerd.service Wantsnetwork-online.target Requirescontainerd.service [Service] Typenotify ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock ExecReload/bin/kill -s HUP $MAINPID TimeoutSec0 RestartSec2 Restartalways StartLimitBurst3 StartLimitInterval60s LimitNOFILEinfinity LimitNPROCinfinity LimitCOREinfinity TasksMaxinfinity Delegateyes KillModeprocess [Install] WantedBymulti-user.target EOF # 同样需要 containerd 的 service 文件 cat systemd-service/containerd.service EOF [Unit] Descriptioncontainerd container runtime Documentationhttps://containerd.io Afternetwork.target [Service] ExecStartPre-/sbin/modprobe overlay ExecStart/usr/bin/containerd Restartalways RestartSec5 Delegateyes KillModeprocess OOMScoreAdjust-999 LimitNOFILE1048576 LimitNPROCinfinity LimitCOREinfinity [Install] WantedBymulti-user.target EOF3.4 编写自动化部署脚本这是工具包的“大脑”。一个好的脚本应该清晰、健壮、有日志。# 创建部署脚本 cat install.sh EOF #!/bin/bash set -e # 遇到错误立即退出 LOG_FILE/var/log/docker-offline-install.log exec (tee -a $LOG_FILE) 21 # 同时输出到屏幕和日志文件 echo echo 开始 Docker 19.03.9 离线安装 $(date) echo # 定义颜色输出可选 RED\033[0;31m GREEN\033[0;32m NC\033[0m # No Color # 1. 检查是否为 root 用户 if [[ $EUID -ne 0 ]]; then echo -e ${RED}错误此脚本必须以 root 权限运行。${NC} exit 1 fi # 2. 定义目录假设脚本和资源在同一目录 SCRIPT_DIR$( cd $( dirname ${BASH_SOURCE[0]} ) /dev/null pwd ) DOCKER_BIN_DIR$SCRIPT_DIR/docker CONTAINERD_TAR$SCRIPT_DIR/containerd-1.3.7-linux-amd64.tar.gz SYSTEM_LIBS_DIR$SCRIPT_DIR/system-libs SYSTEMD_SERVICE_DIR$SCRIPT_DIR/systemd-service # 3. 安装依赖系统库 echo 步骤1安装依赖的系统库... if [ -d $SYSTEM_LIBS_DIR ] [ $(ls -A $SYSTEM_LIBS_DIR) ]; then cp -n $SYSTEM_LIBS_DIR/* /lib64/ 2/dev/null || true echo 系统库已复制。 else echo 未找到额外的系统库跳过。 fi # 4. 安装 Docker 二进制文件 echo 步骤2安装 Docker 二进制文件... if [ -d $DOCKER_BIN_DIR ]; then cp -f $DOCKER_BIN_DIR/* /usr/bin/ chmod x /usr/bin/docker /usr/bin/dockerd echo Docker 二进制文件已安装。 else echo -e ${RED}错误未找到 Docker 二进制文件目录。${NC} exit 1 fi # 5. 安装 containerd echo 步骤3安装 containerd... if [ -f $CONTAINERD_TAR ]; then tar -xzvf $CONTAINERD_TAR -C /usr/bin chmod x /usr/bin/containerd /usr/bin/containerd-shim /usr/bin/containerd-shim-runc-v1 /usr/bin/containerd-shim-runc-v2 /usr/bin/ctr echo containerd 已安装。 else echo -e ${RED}警告未找到 containerd 安装包Docker 可能无法正常运行。${NC} fi # 6. 配置 systemd 服务 echo 步骤4配置 systemd 服务... if [ -d $SYSTEMD_SERVICE_DIR ]; then cp -f $SYSTEMD_SERVICE_DIR/*.service /etc/systemd/system/ systemctl daemon-reload systemctl enable containerd.service systemctl enable docker.service echo systemd 服务已配置并启用。 else echo -e ${RED}错误未找到 systemd 服务文件目录。${NC} exit 1 fi # 7. 启动服务 echo 步骤5启动 containerd 和 docker 服务... systemctl start containerd sleep 2 # 给 containerd 一点启动时间 systemctl start docker sleep 2 # 8. 验证安装 echo 步骤6验证安装... if systemctl is-active --quiet docker; then echo -e ${GREEN}Docker 服务正在运行。${NC} docker version --format Client: {{.Client.Version}}\nServer: {{.Server.Version}} else echo -e ${RED}错误Docker 服务启动失败。请检查日志journalctl -u docker${NC} exit 1 fi echo echo Docker 19.03.9 离线安装完成 $(date) echo # 提示后续操作 echo -e \n${GREEN}提示${NC} echo 1. 如需加载离线镜像请将 .tar 文件放在本目录然后执行: echo docker load -i 你的镜像文件.tar echo 2. 查看详细安装日志: tail -f $LOG_FILE EOF # 赋予脚本执行权限 chmod x install.sh3.5 打包与传输现在将所有必要文件整理并打包。# 假设你的应用镜像已经打包好命名为 app-images.tar # 将其放入工作目录 # cp /path/to/your/app-images.tar ~/docker-offline-19.03.9/ # 查看最终目录结构 tree ~/docker-offline-19.03.9 -L 2 # 打包整个目录 cd ~ tar -czvf docker-offline-19.03.9-centos7.tar.gz docker-offline-19.03.9/现在docker-offline-19.03.9-centos7.tar.gz就是你的离线部署工具包。将其拷贝到U盘或内网服务器。4. 离线环境部署实战与排错指南将工具包上传到目标离线服务器后我们开始部署。4.1 标准部署流程# 1. 上传并解压工具包假设已上传到 /tmp cd /tmp tar -xzvf docker-offline-19.03.9-centos7.tar.gz cd docker-offline-19.03.9 # 2. 执行安装脚本 sudo ./install.sh # 3. 加载应用镜像如果有的话 sudo docker load -i app-images.tar sudo docker images # 确认镜像已加载4.2 常见问题与深度排错即使准备充分离线部署也常会遇到意外。以下是一些典型问题及其排查思路。问题一执行./install.sh时报错containerd.service启动失败。排查思路检查二进制文件权限ls -lh /usr/bin/containerd确保其有可执行权限-rwxr-xr-x。脚本中已包含chmod x但双重确认无妨。检查依赖库在离线服务器上对/usr/bin/containerd运行lddldd /usr/bin/containerd | grep not found。如果发现缺失的库说明打包机上的库版本或路径与目标服务器不一致。你需要回到打包机针对目标服务器的环境可通过虚拟机模拟重新收集依赖库。查看详细日志journalctl -u containerd -xe --no-pager。这是最直接的排错手段。常见错误包括failed to create shim task: OCI runtime create failed: ... exec: runc: executable file not found in $PATH这说明缺少runc二进制。containerd的 tar 包里应该包含runc检查是否成功解压到了/usr/bin。如果没有你需要单独下载runc的静态二进制并放入工具包。failed to start daemon: error initializing graphdriver: driver not supported这通常是因为devicemapper存储驱动所需的libdevmapper库缺失或版本不对。确保system-libs/目录下的libdevmapper.so.1.02已正确复制到目标服务器的/lib64/。问题二Docker 服务 (docker.service) 启动失败提示需要containerd.sock。排查思路确认 containerd 已运行systemctl status containerd。如果 containerd 没起来先解决上一个问题。检查 socket 文件ls -la /run/containerd/containerd.sock。如果这个文件不存在说明 containerd 没有成功创建监听 socket。再次检查 containerd 的日志。核对 Docker 服务文件检查/etc/systemd/system/docker.service中ExecStart行确保--containerd/run/containerd/containerd.sock参数路径正确。我们的脚本模板中已经正确配置。查看 Docker 日志journalctl -u docker -xe --no-pager。结合 containerd 的日志一起分析。问题三安装成功后运行docker run hello-world失败提示Unable to find image hello-world:latest locally。排查思路 这是预期行为因为离线环境无法从网络拉取镜像。这恰恰说明了预先打包应用镜像的重要性。你需要确保在打包阶段已经将所有必需的镜像包括基础镜像如alpine,centos等通过docker save导出并在离线服务器上通过docker load导入。一个常见的误区是只保存了最终的应用镜像而忽略了它依赖的父镜像。在打包机上使用docker image ls和docker history image_name来理清所有依赖的镜像层并全部保存。问题四在不同版本或不同发行版的 Linux 之间迁移工具包失败。排查思路 这是离线部署最大的挑战。Linux 发行版如 CentOS 和 Ubuntu的库文件路径、名称、版本甚至初始化系统sysvinit vs systemd都可能不同。黄金法则尽可能保证“打包机”和“目标机”的操作系统发行版和主版本号完全一致例如都是 CentOS 7.9。最小化安装的版本最为理想。库路径差异Ubuntu 的库可能在/lib/x86_64-linux-gnu/而 CentOS 在/lib64/。如果你的工具包是从 CentOS 打包的却要用于 Ubuntu复制库文件到/lib64/是无效的。必须在对应系统的打包机上重新制作工具包。内核版本影响Docker 对内核版本有要求例如需要高版本的overlay2存储驱动支持。确保目标服务器的内核版本不要太旧。5. 进阶考量安全、存储与版本管理一个用于生产环境的离线部署工具还需要考虑更多因素。5.1 安全加固配置离线不等于安全。在部署脚本中可以集成一些基础的安全配置。# 可以在 install.sh 脚本末尾添加以下配置 cat /etc/docker/daemon.json EOF { log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 }, live-restore: true, userland-proxy: false, iptables: false } EOF systemctl restart dockeriptables: false在严格的内网环境中有时需要关闭 Docker 自动管理 iptables 规则以避免与主机防火墙冲突。注意这会影响容器间的网络通信和端口映射需要根据实际网络架构决定。live-restore: true允许 Docker 守护进程重启时保持容器运行提高可用性。配置日志轮转防止日志占满磁盘。5.2 存储驱动与数据目录规划默认的overlay2存储驱动在大多数现代内核上工作良好。但在离线环境尤其是磁盘空间有限或使用特定存储设备时需要预先规划。更改数据根目录默认 Docker 数据镜像、容器存放在/var/lib/docker。如果该分区空间不足可以在daemon.json中修改{ data-root: /path/to/your/bigger/disk/docker }这必须在首次启动 Docker 服务前配置。因此更稳妥的做法是在部署脚本中先创建好目录并配置好daemon.json然后再启动 Docker。5.3 版本管理与升级策略你制作的是 19.03.9 的工具包。当未来需要升级到 20.10.x 或更新版本时怎么办文档化详细记录工具包的构建过程就像本文、包含的组件版本、针对的操作系统版本。这比工具包本身更重要。版本化归档每个工具包以版本和系统命名如docker-offline-19.03.9-centos7.9.tar.gz、docker-offline-20.10.23-ubuntu2004.tar.gz。建立内部归档仓库进行管理。升级流程离线升级 Docker 是一个高风险操作。标准流程是在新版本的打包机上制作新版本的工具包。在离线环境备份现有的/var/lib/docker或自定义数据目录和容器配置。停止所有容器停止 Docker 服务。卸载旧版本通常就是删除二进制文件和服务配置。使用新工具包进行安装。启动 Docker 服务恢复数据注意存储驱动兼容性重新启动容器。务必在测试环境充分验证升级流程。构建和维护一个可靠的 Docker 离线部署工具包是一项看似基础但极其重要的运维能力。它考验的是你对 Docker 组件架构、Linux 系统依赖和自动化流程的深入理解。通过本文的拆解希望你不只得到了一个可用的“工具”更掌握了从零构建、灵活适配和深度排错的方法论。在完全隔离的网络环境中这份自给自足的能力就是系统稳定运行的基石。本文还有配套的精品资源点击获取
返回列表