ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

内网离线安装Docker与Docker Compose全流程实战指南

内网离线安装Docker与Docker Compose全流程实战指南 简介面向中初级运维工程师及容器平台实施人员这份资源包针对无外网、内网隔离的部署环境集中解决了离线安装Docker引擎与Docker Compose时依赖包缺失、下载困难的问题。包体包含22个文件主要由20个RPM格式的系统依赖与Docker组件包、一个install.sh自动安装脚本以及适配Linux x86_64架构的docker-compose二进制文件组成整体打包约120.91MB。其中RPM包完整覆盖了Docker守护进程、命令行工具、容器运行时及运行所需的系统基础库避免离线环境中因缺失关键依赖导致安装中断。安装时只需将压缩包拷贝至目标机器通过脚本即可自动完成依赖检查、RPM包安装与Compose工具部署特别适合政务内网、企业私有化、生产隔离区等批量交付场景。目前已有4696人学习使用这些组件能帮助技术人员在离线环境下快速搭建可用的容器运行环境提升交付效率并减少排障成本。 前几天接到一个现场任务机房里有台服务器要部署一套业务系统环境要求装docker和docker-compose。网线是插着的但交换机上联口根本没开通外网yum源ping不通apt源更不用说。这种场景在政企、工业、金融内网里太常见了装个docker本来一条命令的事离线环境下硬是能折腾半天。这篇文章就聊聊我在内网离线安装docker、docker-compose的完整过程包括准备工作、二进制安装、systemd注册、镜像导出导入、私有仓库配置这些环节给同样被困在离线环境里的运维和实施同学一个能直接抄的作业。1. 内网离线安装的整体思路为什么离线环境这么麻烦1.1 在线安装和离线安装的本质区别在线安装docker时包管理器会自动处理依赖关系。比如在CentOS上用yum install docker-ceyum会去配置好的软件源里拉取docker主包、containerd、runc等一系列依赖装完顺手把开机启动也配好。apt也一样一条命令自动解决依赖链。整个过程对使用者来说就是“黑盒”你不需要知道docker由哪些组件组成也不需要关心文件放到了哪里。离线环境最大的问题就在这里依赖链断了。你没有外网yum源不可用如果手里只有一份docker的rpm包安装时会直接卡在依赖解析上——要么报缺libltdl要么报缺container-selinux一个个补齐的过程能让人怀疑人生。更麻烦的是不同操作系统的依赖包还不一样CentOS 7的rpm放到Ubuntu上完全不兼容同一套离线包在不同版本系统上表现也可能有差异。所以离线安装不能走“依赖包补齐”这条路最稳妥的方式是用官方提供的静态二进制包。docker官方把运行所需的所有组件和依赖都编译进了一个压缩包里解压后拷贝到对应目录就能直接运行不依赖系统的软件源也不依赖其他动态库。这就是整个离线安装方案的基石。1.2 三种离线安装方案对比我在实际项目里试过三种思路各有适用场景这里直接放对比方案优点缺点适用场景rpm/deb离线包符合系统包管理习惯能用yum/apt卸载和升级依赖解析麻烦换台机器可能缺依赖需要逐个补齐批量交付且操作系统完全一致官方二进制tgz无依赖、拷贝即用一条命令完成安装需要手动注册systemd服务开机自启要自己配大多数内网场景推荐优先使用源码编译能定制编译参数耗时长依赖编译工具链离线环境基本没法用几乎没有不推荐我推荐二进制方案有三个理由。第一它对操作系统版本不敏感CentOS 7、Ubuntu 20.04、麒麟、统信这些系统都能跑只要内核满足要求就行第二升级方便下次拿到新版本tgz解压后直接覆盖/usr/bin下的文件重启docker服务就完事第三排查问题简单没有包管理器介入出问题能很快定位到具体文件和配置。1.3 离线安装前必须想清楚的清单离线安装最怕的就是到了现场发现缺东西所以出发前一定要列清单。我的建议是至少在清单里确认四件事一是docker和docker-compose的具体版本二是需要运行哪些容器、对应哪些镜像三是目标服务器的CPU架构是x86_64还是arm64四是要不要搭私有镜像仓库。版本和架构这两项最容易踩坑。docker的二进制包区分x86_64和aarch64docker-compose也区分不同架构拿错包直接exec format error。镜像同样有架构标签在一台x86服务器上load一个arm版的镜像容器起不来还说不出原因。宁可出发前多花十分钟确认也不要到现场才手忙脚乱。2. 准备工作在有网机器上下载离线安装包2.1 下载docker二进制包的正确姿势docker官方把静态二进制包放在download.docker.com/linux/static/stable/目录下按架构分子目录。以x86_64为例直接访问download.docker.com/linux/static/stable/x86_64/能看到按版本号命名的tgz文件比如docker-24.0.9.tgz。选择版本时有两条经验一是不要盲目追新生产环境选稳定版等新版本发布两三个月后再考虑升级二是避开.rc、.beta这类预发布版本。下载和校验我一般这样操作# 下载docker二进制包 wget https://download.docker.com/linux/static/stable/x86_64/docker-24.0.9.tgz # 查看压缩包内容确认包含docker、dockerd、containerd等组件 tar tzf docker-24.0.9.tgz # 校验SHA256确保文件完整、未被篡改 sha256sum docker-24.0.9.tgztar tzf这一步很多人会跳过但我建议每次都看一眼。正常的docker静态包解压后是一个docker/目录里面有docker、dockerd、containerd、containerd-shim-runc-v2、ctr、runc、docker-init等组件。如果发现文件缺失或者名字对不上说明包有问题不要继续往下走。下载完成后把tgz包传到U盘或者内网共享目录。压缩包本身只有几十MB传起来不费劲。2.2 下载docker-compose并选对版本docker-compose的官方下载地址在GitHub Releases页面github.com/docker/compose/releases。需要下载的文件名是docker-compose-linux-x86_64对应x86_64架构或者docker-compose-linux-aarch64对应arm64架构。这个文件本身就是可执行的二进制文件不需要解压下载后改名、加执行权限就能用。选版本时先要搞清楚一个概念docker-compose有两个“形态”。一个是独立的docker-compose命令通常放在/usr/local/bin/docker-compose适合老项目和脚本里直接调用另一个是docker的插件docker compose注意中间没有横杠放在~/.docker/cli-plugins/或/usr/local/lib/docker/cli-plugins/目录下通过docker compose命令调用。两种形态的底层实现一样compose文件格式也完全兼容只是命令名和存放位置不同。我个人的建议是下载v2.x版本的独立二进制命名为docker-compose并放到/usr/local/bin/下。这样既能用docker-compose命令兼容旧习惯又能支持新版compose文件格式。下载命令如下# 下载v2.24.5版本按实际版本号调整 wget https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-linux-x86_64 # 改名并加执行权限 mv docker-compose-linux-x86_64 docker-compose chmod x docker-compose2.3 提前准备镜像并导出装好docker和docker-compose只是第一步没有镜像是跑不起来任何容器的。在离线环境里镜像只能靠提前导出、现场导入。这一步要在有网机器上提前完成而且镜像版本要在出发前确定好到了内网再改版本就麻烦了。我通常会准备两类镜像一类是业务直接依赖的比如mysql:8.0、redis:7.0、nginx:1.24这类中间件另一类是基础工具镜像用来排查问题比如busybox、alpine体积小关键时刻非常有用。导出命令# 拉取镜像 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指定输出文件名后面跟镜像名。如果一次导出多个镜像可以写在一行比如docker save -o all.tar mysql:8.0 redis:7.0导入时会一起加载但导出文件会比较大。我习惯每个镜像单独导出现场按需逐个导入这样单文件小、传输快也方便排查哪个镜像有问题。2.4 把安装包传到目标服务器从有网机器到内网服务器的传输方式取决于现场条件。最常见的三种一是用U盘拷贝适合单台服务器二是通过内网FTP或者共享目录适合多台批量分发三是从跳板机用scp传到目标机器。无论哪种方式我建议都建一个专门的目录比如/root/offline_install/把docker二进制包、docker-compose、镜像tar包统一放进去方便后续操作。3. 内网服务器安装从解压到systemd注册3.1 docker核心组件的安装步骤到了内网服务器上先把之前准备的docker二进制包解压然后拷贝到系统路径# 解压 tar xzf docker-24.0.9.tgz # 把解压后的二进制文件拷贝到/usr/bin/ cp docker/* /usr/bin/ # 创建docker用户组非root用户要用docker命令需要它 groupadd docker # 验证版本 docker version执行到docker version时如果能看到Client和Server两个部分的信息说明docker已经能运行了。但这里有个细节手动执行docker version时系统会自动拉起一个临时的dockerd进程来响应请求所以你看到Server信息不代表服务已经配置成开机自启了。要让docker在重启后自动启动必须注册systemd服务。在/etc/systemd/system/docker.service中写入以下内容[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 TimeoutSec0 RestartSec2 Restartalways LimitNOFILEinfinity LimitNPROCinfinity LimitCOREinfinity Delegateyes KillModeprocess [Install] WantedBymulti-user.target然后执行systemctl daemon-reload systemctl enable docker systemctl start docker systemctl status docker加粗提醒一点ExecStart/usr/bin/dockerd这里的路径必须和实际拷贝路径一致。如果你把二进制放到了/usr/local/bin/这里就要改成/usr/local/bin/dockerd。路径不一致服务会启动失败报Exec format error或者No such file or directory。3.2 把docker-compose装成独立命令docker-compose的安装比docker简单得多本质就是拷贝一个可执行文件# 拷贝到/usr/local/bin/让它对所有用户可用 cp docker-compose /usr/local/bin/ # 加执行权限 chmod x /usr/local/bin/docker-compose # 验证 docker-compose version这里有一个新手很容易忽略的问题从网上下载的docker-compose-linux-x86_64文件本身没有可执行权限如果你忘了chmod x运行docker-compose version会直接报Permission denied。拷贝到/usr/local/bin/之后如果没有执行权限即使切换root用户也没用因为Linux执行文件靠的是文件的权限位不是用户身份。如果你更喜欢docker compose插件方式的安装把文件放到/usr/local/lib/docker/cli-plugins/目录下命名为docker-compose即可。推荐使用独立命令方式因为老版本的shell脚本和CI工具里基本都是调docker-compose兼容性更好。3.3 配置daemon.json与常用参数安装完成后别急着跑容器先配置daemon.json。对于离线环境最重要的配置项是insecure-registries。后续如果搭建了私有仓库docker从仓库拉取镜像走的是HTTP协议默认会被拒绝必须在这里把仓库地址加白名单。{ data-root: /var/lib/docker, log-driver: json-file, log-opts: { max-size: 100m, max-file: 3 }, insecure-registries: [192.168.1.100:5000] }配置文件路径是/etc/docker/daemon.json改完后执行systemctl restart docker生效。>mkdir -p /root/offline_install/images把镜像tar包上传到这个目录然后逐个导入docker load -i mysql-8.0.tar docker load -i redis-7.0.tar导入完成后用docker images查看如果能看到对应镜像和tag说明导入成功。这里有个细节要注意docker save导出的是完整镜像包括所有层和元数据所以tar包一般比较大。但tar包不支持跨平台导入比如你在x86_64的机器上save的镜像不能load到arm64的机器上运行架构必须一致。当服务器数量多、镜像包大的时候频繁load效率很低。这个时候更优的方案是搭一个内网私有仓库镜像只导入一次其他机器从仓库拉取。4.2 搭建一个内网私有仓库搭私有仓库需要用到registry镜像。先在有网机器上操作docker pull registry:2 docker save -o registry-2.tar registry:2把registry-2.tar带到内网服务器load之后运行容器docker load -i registry-2.tar docker run -d \ --name registry \ --restartalways \ -p 5000:5000 \ -v /data/registry:/var/lib/registry \ registry:2这里把registry的数据目录挂载到了宿主机的/data/registry容器删了重建数据还在这个设计在生产环境里非常关键。如果容器不挂数据卷一旦容器被删除仓库里所有镜像就全没了。仓库起来之后把已有的镜像打上指向内网仓库地址的标签然后推送上去docker tag mysql:8.0 192.168.1.100:5000/mysql:8.0 docker push 192.168.1.100:5000/mysql:8.0当然前提是daemon.json里已经配置了insecure-registries。推送成功后在内网其他机器上就可以直接执行docker pull 192.168.1.100:5000/mysql:8.0拉取镜像了。4.3 私有仓库在团队协作中的优势如果只有一台内网服务器私有仓库的价值不明显docker load直接导入就行。但一旦涉及多台服务器私有仓库的价值就体现出来了。首先是节省时间。一台服务器load一份几百MB的镜像包三台就要load三次有了仓库每台机器直接pull网络传输通常比本地解压快而且不用每次拿着U盘到处跑。其次是版本统一。团队多个人部署同一套业务时各自load镜像容易出现版本不一致仓库里只有一份镜像所有人从同一个仓库拉取版本天然统一。最后是回滚方便。旧版本镜像也保留在仓库里需要回滚时直接用旧tag重新拉取即可。当然私有仓库也有额外成本需要一台机器或一个目录专门跑registry容器还要定时清理无用镜像避免磁盘被占满。对于5台以内的内网环境我通常还是会用docker load管理成本更低超过5台或者部署频率较高的场景果断上私有仓库。5. 常见问题与排查技巧实录5.1 systemd启动docker失败用systemctl start docker启动时卡住然后报Job for docker.service failed because the control process exited with error code这种情况我遇到过好多次。先别慌第一步是用systemctl status docker -l看完整日志或者journalctl -u docker查最近的日志。常见的坑有一个可能的原因是docker.service文件里的ExecStart路径写错了导致找不到dockerd。解决方法是排查路径确保和实际二进制所在位置一致。另一个是SELinux拦截在CentOS和麒麟系统上比较常见。先执行getenforce看SELinux状态如果是Enforcing可以先setenforce 0临时关闭再执行systemctl start docker。如果问题消失说明是SELinux策略问题可以在配置文件里调整策略或者在内网安全要求允许的情况下将SELinux改为Permissive模式。还有一个隐蔽的问题daemon.json配置错误。比如JSON格式写错了一个逗号或者写入了不可识别的配置字段dockerd启动时会直接报错。可以先运行dockerd --validate或dockerd --debug查看具体报错信息也可以用python3 -m json.tool /etc/docker/daemon.json校验JSON格式。5.2 docker-compose命令找不到或版本不对在服务器上执行docker-compose version提示command not found大概率是文件没有放到PATH路径下或者没加执行权限。先检查echo $PATH看看路径里有没有/usr/local/bin再检查ls -l /usr/local/bin/docker-compose的权限位。如果文件存在且有执行权限但新开的终端还是提示找不到可能是当前session的PATH缓存问题退出重新登录即可。另一种情况是docker-compose能执行但版本显示是v1.x。v1版本已经停止维护compose文件里很多新字段比如version字段废弃后的写法不支持建议升级到v2.x。直接替换二进制文件然后重启相关服务即可。5.3 镜像加载成功但容器启动失败docker load导入镜像后docker images里能看到镜像但docker run时直接退出docker logs也看不到有效日志。这种情况优先怀疑镜像架构和宿主机架构不匹配。用docker inspect 镜像名 | grep Architecture查看镜像架构再用uname -m查看宿主机架构如果不一致重新下载对应架构的镜像。另外一个常见原因是端口冲突。如果docker run时指定了-p 3306:3306但宿主机3306端口已经被其他进程占用容器会启动失败。用ss -lntp | grep 3306查端口占用情况换端口或停掉占用进程即可。还有镜像内部应用本身的启动参数问题这个就得具体问题具体分析了。5.4 内网仓库拉取镜像报HTTP错误从私有仓库拉取镜像时报http: server gave HTTP response to HTTPS client这是典型的daemon.json没配好。docker默认用HTTPS访问仓库私有仓库用的是HTTP必须把仓库地址配置到insecure-registries里然后重启docker。改完daemon.json后重启docker再拉取一次。如果还是同样报错检查docker info里Insecure Registries是否已经包含目标地址。注意配置后一定要systemctl restart docker只reload是无效的。5.5 故障速查表现象可能原因排查命令解决思路docker.service启动失败ExecStart路径错误、SELinux拦截、daemon.json有误journalctl -u dockerdockerd --debug核对路径调整SELinux校验JSONdocker-compose command not found未加执行权限、文件不在PATH中ls -l /usr/local/bin/docker-composechmod x重新登录session容器启动立即退出架构不匹配、端口冲突、应用参数错误docker inspectss -lntp拉取正确架构镜像换端口检查应用日志私有仓库拉取报HTTPS错误未配置insecure-registriesdocker info修改daemon.json后重启dockerdockerd运行时磁盘满日志没有设置上限、镜像过多df -hdu -sh /var/lib/docker配置log-opts清理无用镜像离线安装docker和docker-compose这件事做一次觉得麻烦但把流程跑顺之后会发现真正核心的只有三件事安装包准备全、镜像提前导出、服务配置对。我个人习惯是把下载好的二进制包、镜像tar包、daemon.json模板、systemd service文件全部按版本号归档存一份在U盘和共享存储里下次再遇到内网环境直接整套拷过去就能用不用重新上网找资源。最后再分享一个实战小技巧第一次去现场之前先在本地找一台相同操作系统的测试机把整套离线安装流程完整走一遍包括docker、docker-compose、镜像导入、容器启动验证。测试机上跑通了现场基本就能一次成功。离线环境没有试错的余地提前演练是最省时间的方式。本文还有配套的精品资源点击获取
返回列表