尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

内网环境Docker离线安装全实践:静态二进制包部署与私有仓库搭建

内网环境Docker离线安装全实践:静态二进制包部署与私有仓库搭建 简介面向内网或无外网环境的运维人员与开发工程师该资源提供了一套完整的 Docker 与 Docker Compose 离线安装方案解决了无互联网连接时部署容器服务的难题。包内共计 22 个文件包含 20 个经整理的 RPM 依赖包、1 个一键安装脚本以及 docker-compose-linux-x86_64 二进制文件压缩包总大小约 120.91MB。资源针对 CentOS 7 环境进行了适配覆盖 docker-ce、cli、containerd.io、rootless-extras 等核心组件及相应运行依赖。已有 4696 人学习下载适用于企业内网、隔离网络或生产环境中的批量部署与容器环境搭建安装脚本可帮助快速完成配置避免手动逐个安装依赖的繁琐过程。 内网环境下装 Docker 这件事做运维的应该都不陌生。项目跑在隔离网段机器不能出网而手边偏偏只有一台能上网的开发机要装 docker 和 docker-compose靠yum install docker-ce这种在线方式肯定走不通网上搜到的教程全是apt install docker.io、curl -fsSL get.docker.com | sh这类拿到内网环境就是废纸。这篇文章就把我最近一次完整的内网离线安装过程、踩过的坑、以及最后如何验证和自建仓库的细节写清楚给后面需要在隔离环境复用的人一个参考。1. 先理清离线安装的整体思路1.1 为什么离线安装比在线安装更讲究方案选型在线装 Docker包管理器会帮我们自动处理依赖关系一条命令就行根本不用关心背后装了什么。但离线环境下所有安装物料都得自己提前准备好带到现场缺一个依赖就得回头重新折腾。所以方案选型特别关键不能随手抄网上的办法。我试过两条路rpm/deb 离线包路线在联网机器上用yumdownloader --resolve或dnf download把 docker 及其依赖包全部下载下来再拷贝到内网机器rpm -ivh *.rpm批量安装。好处是安装后走系统包管理器卸载、升级都方便坏处是依赖链太长了不同系统的包版本差异大经常出现缺containerd.io或runc某个小版本的情况排查依赖关系很费劲。官方静态二进制包路线Docker 官方长期提供linux/static的 tar.gz 包一个包里面就包含docker、dockerd、containerd、runc等全部组件解压即用几乎不依赖系统环境的动态库。坏处是升级时得手动替换二进制文件和重新加载 systemd 配置。最终我选了静态二进制包路线。理由很实际包体积小、依赖少适合用 U 盘或内网文件服务器分发而且 tar 包里的组件版本是配套测试过的冲突概率最低。对于内网环境“一次部署、长期稳定运行”的需求这是性价比最高的方式。1.2 准备工作清单一台能联网的机器加一台内网机器离线安装需要提前准备的内容不只是 docker 和 docker-compose 这两个安装包还包括你要跑的镜像。这是我这次动手前整理的任务分解角色用途需要准备的东西联网机器Linux/Windows 均可下载安装包、导出镜像docker 二进制包、docker-compose 二进制、目标应用镜像内网目标机器离线部署安装包拷贝、U盘或内网共享通道、可用的系统环境传输通道将物料从联网机器转移到内网U盘、内网 scp/sftp、内网 ftp 或共享目录另外还有几个硬性条件要提前确认内核版本Docker 对内核要求是 3.10 以上建议 4.x 及以上。内网机器如果还是老内核先升内核再折腾 docker不然后面 overlay2 存储驱动会报错。系统架构下载包之前先确认架构。绝大多数服务器是x86_64但 ARM 机器也不少下载时别选错包。防火墙状态内网机器通常会跑 firewalld 或 iptables安装 docker 后容器端口映射需要放行相应端口建议先把策略梳理清楚否则容器运行正常但外部访问不了很容易误判成 docker 装坏了。2. 核心资源准备在联网机器上下载全部安装物料2.1 获取 docker 二进制包并校验完整性Docker 官方静态包下载地址是https://download.docker.com/linux/static/stable/x86_64/。如果网络情况不理想也可以走阿里的镜像站https://mirrors.aliyun.com/docker-ce/linux/static/stable/x86_64/。两个源的文件结构和命名规则完全一致内容都是官方打包产物。版本选择上我的建议是不追新选经过生产环境检验的主流版本。比如 24.0.x 这个系列社区反馈稳定各种排障资料也全没必要一上来上 27.x虽然功能多但内网环境没有升级需求稳定压倒一切。下载命令示例# 以 docker-24.0.7.tgz 为例 wget https://download.docker.com/linux/static/stable/x86_64/docker-24.0.7.tgz wget https://download.docker.com/linux/static/stable/x86_64/docker-24.0.7.tgz.sha256 # 校验哈希值确认下载过程没有损坏 sha256sum -c docker-24.0.7.tgz.sha256一定要做哈希校验这一步。内网传输文件的过程中U盘拷贝或者网络传输导致文件损坏的情况我遇到过不止一次如果到了现场解压出来跑不起来那才是真的绝望。2.2 获取 docker-compose 二进制文件现在的 docker-compose 官方推荐的是 v2 版本它和 v1 最大的区别是v1 依赖 Python 环境、是一个完整程序v2 则是用 Go 写的单文件二进制官方推荐作为 Docker 的 CLI 插件来使用。下载地址是https://github.com/docker/compose/releasesLinux x86_64 架构对应的文件名一般是docker-compose-linux-x86_64。国内网络访问 GitHub 有时候慢也可以到国内的一些镜像源找下载。下载后同样做一次 sha256 校验下载命令示例wget https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64 sha256sum docker-compose-linux-x86_64注意这里下载的是单文件不需要解压后续到内网机器上直接赋可执行权限就行。2.3 提前搬好镜像docker save 导出离线镜像包安装包只是第一步更关键的是要用的应用镜像。内网环境无法从 Docker Hub 拉镜像所以必须在联网机器上把镜像下载好、打包带走。这一步的原则是能用 docker save 就尽量别用 docker export。docker save保存的是镜像的完整层结构和历史元数据docker load加载之后镜像跟原版一模一样docker export导出的只是容器文件系统快照会丢掉镜像的层信息加载后是一个不完整镜像无法用于后续构建和依赖继承。举个例子我需要在内网跑 mysql 和 redis# 在联网机器上拉取镜像 docker pull mysql:8.0 docker pull redis:7.0 # 导出为 tar 包可以一次带多个镜像 docker save -o mysql-8.0.tar mysql:8.0 docker save -o redis-7.0.tar redis:7.0 # 也可以用一条命令打包多个镜像 docker save -o app-images.tar mysql:8.0 redis:7.0 # 打 tar 包时建议再压缩一层内网拷贝能省不少时间 gzip app-images.tar导出的 tar 包是压缩的关键物料一定要单独放在一个目录里。我一般会顺手写一个README.txt把镜像名称、tag、对应的 tar 文件名、sha256 值都记录下来到了现场不用临时回忆这个习惯后面会救你一命。3. 内网目标机器安装实操3.1 解压 docker 二进制并配置 systemd 服务先把所有物料上传到内网机器上我习惯统一放在/root/docker-deploy/目录下目录结构清晰方便排查。然后是正式安装步骤。# 1. 进入部署目录解压 docker 二进制包 cd /root/docker-deploy/ tar xf docker-24.0.7.tgz # 2. 解压得到 docker 目录里面是完整的 docker 组件 # 将二进制文件复制到系统 PATH 目录 cp docker/* /usr/bin/ # 3. 验证版本 docker --version dockerd --version这里有个容易忽略的点解压出来的目录里除了 docker 和 dockerd还有 containerd、containerd-shim-runc-v2、runc、docker-init、docker-proxy 等文件必须全部复制到/usr/bin下不能只拷贝 docker 一个文件。否则 dockerd 启动时会因为这些辅助组件缺失而失败。接着配置 systemd 管理 docker 服务让它在开机时自动启动cat /etc/systemd/system/docker.service EOF [Unit] DescriptionDocker Application Container Engine Documentationhttps://docs.docker.com Afternetwork-online.target firewalld.service containerd.service Wantsnetwork-online.target [Service] Typenotify ExecStart/usr/bin/dockerd ExecReload/bin/kill -s HUP \$MAINPID LimitNOFILEinfinity LimitNPROCinfinity LimitCOREinfinity TimeoutStartSec0 Delegateyes KillModeprocess Restarton-failure StartLimitBurst3 StartLimitInterval60s [Install] WantedBymulti-user.target EOF启动前最好先建好daemon.json配置文件。即使不配镜像加速也可以先留一个空配置把镜像存储目录和存储驱动固定下来避免以后想改目录时还要迁移数据。我的习惯是{ data-root: /opt/docker, storage-driver: overlay2, exec-opts: [native.cgroupdriversystemd], log-driver: json-file, log-opts: { max-size: 100m, max-file: 3 } }这里建议把>systemctl daemon-reload systemctl enable --now docker systemctl status docker如果一切正常status会显示active (running)。再执行docker version做客户端和守护进程的双端验证docker version docker infodocker info里重点看 Storage Driver 是不是 overlay2、Cgroup Driver 是不是 systemd、Server Version 是否和下载的版本一致。这些信息都对上了说明基础环境基本可用。3.3 安装并验证 docker-composedocker-compose v2 作为 CLI 插件推荐放的位置是/usr/local/lib/docker/cli-plugins/同时也可以把它放到/usr/local/bin/下走传统的docker-compose命令。为了兼容两套命令我的做法是主文件放在 cli-plugins 目录再做软链接# 1. 创建 cli-plugins 目录 mkdir -p /usr/local/lib/docker/cli-plugins # 2. 把 docker-compose 二进制放进去并赋执行权限 cp /root/docker-deploy/docker-compose-linux-x86_64 /usr/local/lib/docker/cli-plugins/docker-compose chmod x /usr/local/lib/docker/cli-plugins/docker-compose # 3. 做软链接让 docker-compose 老命令也能用 ln -s /usr/local/lib/docker/cli-plugins/docker-compose /usr/local/bin/docker-compose # 4. 两种方式验证 docker compose version docker-compose --version两个命令都正常输出版本信息docker-compose 的安装就算完成了。3.4 导入镜像并启动一个测试容器镜像导入是最直观的验证手段。把之前导出的 tar 包上传到内网机器然后执行# 可以加 --quiet 参数导入大镜像时不会刷太多输出 docker load -i mysql-8.0.tar.gz docker load -i redis-7.0.tar.gz # 查看已导入的镜像列表 docker images光是docker images能看到还不够我一般会跑一个真实容器确认容器能起、端口能通、日志能输出才敢把环境交出去。比如拿 redis 做一次快速验证docker run -d --name redis-test -p 6379:6379 redis:7.0 docker ps docker logs redis-test看到容器状态是 Up日志输出正常这套离线安装的流程才算真正走通。4. 常见问题与排查技巧实录4.1 依赖缺失导致 dockerd 启动失败这是一个高发问题。很多人在第一步解压后只复制了 docker 二进制文件漏掉了 containerd、runc 等组件启动 dockerd 的时候报failed to start containerd或者exec: runc: executable file not found in $PATH。解决办法也简单把解压出来的 docker 目录下所有二进制文件全部复制到/usr/bin不要挑三拣四。我自己的习惯是直接cp docker/* /usr/bin/全量覆盖省事且稳妥。4.2 overlay2 存储驱动初始化报错启动 dockerd 时报Failed to mount overlay2: no such file or directory或者failed to configure storage多半是内核缺少 overlay 和 br_netfilter 模块。内网离线环境下内核模块需要预先在系统里启用# 临时启用 modprobe overlay modprobe br_netfilter # 永久启用写入模块配置 cat /etc/modules-load.d/docker.conf EOF overlay br_netfilter EOF # 同时开启内核转发参数 cat /etc/sysctl.d/docker.conf EOF net.bridge.bridge-nf-call-iptables 1 net.ipv4.ip_forward 1 EOF sysctl --system改完后重新启动 docker 服务这个问题基本就消失了。如果 modprobe 报模块找不到那就是内核确实太老老老实实升级内核吧。4.3 systemd 已存在旧版本 docker 服务冲突有些内网机器之前被用脚本部署过 docker或者系统自带了老版本 docker。这种情况新版本起不来而且报错还不明显。排查时先看看已有服务systemctl list-unit-files | grep -i docker如果有旧的 docker.service 或者旧版本 dockerd 进程先停掉、禁用、删掉对应的 systemd 文件再重新来。残留的老配置文件daemon.json也可能导致新版本启动异常建议检查/etc/docker/daemon.json确认 JSON 格式合法、字段兼容。4.4 容器端口映射后外部无法访问docker 容器起来了docker ps显示端口映射正常但在不在本机上curl却不通。这个问题表面上是 docker 的问题实际上往往是防火墙策略没放行。检查目标端口是否在 firewalld 或 iptables 里被拦截firewall-cmd --list-ports firewall-cmd --add-port6379/tcp --permanent firewall-cmd --reload另外确认daemon.json里是否配置了iptables: false这个参数一旦被设置为 falsedocker 不会自动写入 iptables 规则端口映射大概率不生效而且很隐蔽。4.5 常见问题速查表现象常见原因排查/解决方向dockerd 启动失败提示找不到 runc二进制文件复制不全cp docker/* /usr/bin/全部复制启动报 overlay2 挂载失败内核缺少模块modprobe overlay br_netfilter确认内核版本docker compose 命令找不到插件路径或权限不对cli-plugins 目录 chmod x容器起不来报端口被占用端口冲突ss -lntp查看占用进程换映射端口镜像 load 报磁盘空间不足根分区空间不够df -h查看修改># 先在有网机器上拉取 registry 镜像并导出 docker pull registry:2 docker save -o registry-2.tar registry:2 # 在内网一台机器上导入并启动私有仓库 docker load -i registry-2.tar docker run -d \ --name registry \ --restartalways \ -p 5000:5000 \ -v /data/registry:/var/lib/registry \ registry:2部署好后其他内网机器就可以把镜像推送到这台仓库再通过私网地址直接拉取。对机器数量多、镜像版本要统一管理的内网环境这比逐个拷 tar 包省力太多。如果环境更正式一点还可以考虑 Harbor它自带 UI、权限控制和镜像同步能力功能强很多但需要额外的资源轻量场景没必要。5.3 docker-compose 在内网使用的几个小细节用 docker-compose 编排服务时特别注意image字段必须和内网docker images里的镜像名和 tag 完全一致。因为内网离线环境没有网络拉取能力compose 启动时不会自动去远程仓库拉镜像本地没有就直接报image not found。所以导入镜像后先docker images确认完整的 REPOSITORY 和 TAG再去写 compose 文件别看镜像名称相似就随手填。我还会在写完后做一次配置校验docker compose config这个命令会解析并输出最终生效的配置也能检查 YAML 格式和参数引用是否正确。启动时建议加上-d参数后台运行查看运行状态用docker compose ps看日志用docker compose logs -f --tail100这套组合已经够日常运维用了。说回这次离线安装最大的体会就是越是不联网的环境越要把每个步骤标准化。下载、校验、导出、导入、验证一个环节乱了都要付出时间代价。我建议第一次做的人把下载好的安装包连同镜像全部打好 tar再写一个install.sh脚本和 README把版本、路径、校验值和执行顺序写清楚传到内网直接执行。这个习惯帮我省了太多事。现在如果再来一台新机器基本上半小时就能支起一套带 docker、compose 和基础镜像的工作环境真的很值得花点时间把流程固化下来。本文还有配套的精品资源点击获取
返回列表