尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Linux离线安装Docker全攻略:从依赖解析到私有化部署实战

Linux离线安装Docker全攻略:从依赖解析到私有化部署实战 1. 为什么需要离线安装Docker最近在给一个客户的内部生产环境部署一套新的微服务应用他们的服务器集群位于一个严格的内网环境中完全无法访问外网。客户的要求很明确所有软件包括Docker都必须通过离线方式安装。这其实不是个例在金融、军工、政府或者一些对网络安全有极高要求的私有化部署场景里离线安装是常态。你可能觉得不就是把安装包拷进去运行一下吗但真上手了才发现从依赖检查、包下载、传输到最终配置每一步都可能藏着坑。网上很多教程只给了在线安装的命令对于离线环境尤其是不同Linux发行版之间的差异说得并不透彻。今天我就结合这次实战把Linux环境下离线安装Docker的完整流程、核心原理以及我踩过的那些坑给你彻底讲明白。简单来说离线安装Docker的核心挑战在于解决“依赖”和“版本”两个问题。Docker本身不是一个孤立的二进制文件它依赖于容器运行时如containerd、网络插件、存储驱动等一系列组件。在线安装时包管理器如yum或apt会自动帮你解决这些依赖。但在离线环境下你需要手动准备一个包含所有依赖的、完整的软件包集合并确保它们之间的版本完全兼容。这个过程我们通常称为“制作离线安装包”或“搭建本地仓库”。2. 前期准备环境探查与包获取策略在动手下载任何东西之前充分的准备工作能避免你白忙活一场。这一步的目标是弄清楚目标服务器的“底细”并制定对应的包获取方案。2.1 目标服务器环境探查首先你需要登录到那台不能上网的目标服务器执行几个关键命令来收集信息。别小看这几步它们直接决定了你后续要下载什么版本的包。确认操作系统发行版和版本号cat /etc/os-release这个命令会输出类似下面的信息重点关注ID和VERSION_ID。NAMECentOS Linux VERSION7 (Core) IDcentos ID_LIKErhel fedora VERSION_ID7 ...在这个例子中我们明确知道这是 CentOS 7。如果是 UbuntuID 会是ubuntu版本号可能是20.04或22.04。不同的发行版使用的包管理器和软件源格式完全不同。确认系统架构uname -m常见的输出有x86_64(64位Intel/AMD)、aarch64(64位ARM常见于国产化或树莓派环境)。这决定了你要下载x86_64还是arm64的安装包。下错了架构安装时就会报错。检查内核版本与容器支持uname -rDocker 对 Linux 内核版本有最低要求一般建议 3.10 以上。同时虽然离线安装不涉及docker desktop但那个网络热词里提到的virtualization support not detected错误的本质是 Linux 内核需要开启cgroups和namespaces等容器所需的支持。你可以通过以下命令检查grep -E cgroup|namespace /proc/filesystems以及检查overlay存储驱动是否可用这是Docker推荐的驱动lsmod | grep overlay如果这些内核特性没有即使Docker安装成功也无法运行容器。不过主流的现代Linux发行版CentOS 7, Ubuntu 18.04默认都是开启的。2.2 制定离线包获取方案探查清楚环境后你需要在另一台可以访问互联网的、操作系统和架构与目标服务器完全相同的机器上准备离线包。这是最关键的原则确保环境一致性。通常有三种方案方案A使用包管理器下载推荐利用yum或apt的downloadonly或--download-only功能只下载不安装这样能自动解决所有依赖关系。这是最可靠、最省事的方法。方案B手动下载RPM/DEB包从Docker官方仓库或发行版镜像站手动查找并下载所有依赖包。这种方法繁琐容易遗漏依赖不推荐。方案C使用静态二进制包Docker官方提供了静态编译的docker-ce二进制包.tgz格式它包含了dockerd、docker客户端以及containerd、runc等。这种方式相对独立但对系统基础库仍有要求。对于生产环境我强烈推荐方案A。它最能模拟在线安装的过程保证依赖的完整性。接下来我将以最常见的CentOS 7/RHEL 7 (x86_64)和Ubuntu 20.04 (x86_64)为例详细演示方案A的操作。3. CentOS 7/RHEL 7 离线安装全流程假设我们的目标服务器是 CentOS 7.9 x86_64。我们需要一台同版本的在线机器作为“下载机”。3.1 在下载机准备离线安装包配置Docker的YUM仓库 在下载机上首先添加Docker的官方YUM源。这能确保我们下载到的是官方认证的最新稳定版。sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo清理本地YUM缓存并下载所有包 使用yumdownloader工具来自yum-utils来下载指定软件包及其所有依赖。# 创建一个目录存放所有下载的rpm包 mkdir -p /opt/docker-offline-packages cd /opt/docker-offline-packages # 下载docker-ce社区版、docker-ce-cli客户端、containerd.io容器运行时 # 注意这里不指定版本则会下载最新版生产环境建议指定版本如 docker-ce-20.10.9 sudo yumdownloader --resolve --destdir/opt/docker-offline-packages docker-ce docker-ce-cli containerd.io--resolve参数会自动解析并下载所有依赖包。--destdir指定下载目录。执行完后/opt/docker-offline-packages目录下会有一堆.rpm文件这就是我们需要的完整离线包。实操心得务必在下载机上执行一次sudo yum install docker-ce但先别确认安装看看它会列出哪些依赖包再与下载目录里的包对比一下确保关键包如container-selinux如果系统开启了SELinux等已被包含。有时yumdownloader可能会因为下载机已安装过某些基础依赖而漏掉但在目标机上可能没有。额外关键依赖检查 Docker依赖于device-mapper-persistent-data和lvm2来提供devicemapper存储驱动虽然现在推荐overlay2但安装包可能仍有依赖。同时如果目标服务器开启了防火墙还需要firewalld的相关配置。为了保险起见我通常会手动确保这些包也被下载sudo yumdownloader --destdir/opt/docker-offline-packages device-mapper-persistent-data lvm23.2 传输包到目标服务器并安装将/opt/docker-offline-packages整个目录打包通过U盘、内网SFTP或其他任何离线方式传输到目标服务器的某个路径例如/tmp/docker-packages。在目标服务器上进入包目录并本地安装cd /tmp/docker-packages sudo yum localinstall *.rpmyum localinstall命令会处理本地rpm文件并自动解决它们之间的依赖关系因为所有依赖包都在当前目录。这是离线安装的核心命令。启动Docker服务并设置开机自启sudo systemctl start docker sudo systemctl enable docker验证安装sudo docker version sudo docker run hello-world如果hello-world镜像能成功运行并输出欢迎信息那么恭喜你Docker离线安装成功3.3 针对CentOS 7的特定避坑点SELinux问题如果目标服务器启用了SELinux默认启用而你的离线包中没有container-selinux这个策略包安装会失败。你可以选择 a) 确保下载包时包含了container-selinux可能需要从CentOS官方Base源下载对应版本的包。 b)临时方案仅用于测试或特定环境编辑/etc/selinux/config将SELINUXenforcing改为SELINUXpermissive或disabled然后重启服务器。生产环境请谨慎修改SELinux策略建议采用方案a。存储驱动选择CentOS 7 的内核版本3.10默认支持overlay2但可能需要手动加载内核模块overlay。如果lsmod | grep overlay无输出可以尝试sudo modprobe overlay。然后确保Docker的存储驱动配置为overlay2默认通常是。防火墙如果目标服务器防火墙是开启的需要放行Docker守护进程监听的端口默认是2375/2376但通常不直接暴露而是用Unix Socket。更常见的需求是容器网络与外部通信。你需要添加防火墙规则例如允许bridge网桥的流量。一个简单的做法是根据你的网络策略调整sudo firewall-cmd --permanent --zonetrusted --add-interfacedocker0 sudo firewall-cmd --reload4. Ubuntu 20.04 离线安装全流程Ubuntu使用apt包管理器流程与CentOS类似但命令不同。目标服务器为 Ubuntu 20.04 LTS x86_64。4.1 在下载机准备离线安装包配置Docker的APT仓库sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg lsb-release curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null sudo apt-get update下载所有DEB包apt工具本身没有直接的downloadonly参数但我们可以使用apt-get download来下载指定包并结合apt-cache depends来获取依赖列表。不过更简单的方法是使用apt-offline工具或者用以下“笨”但有效的方法首先在一个干净的容器或临时虚拟机与目标环境一致中模拟安装并获取所有要下载的包列表。这里提供一个手动脚本思路a. 创建一个脚本get-docker-deps.sh:#!/bin/bash PACKAGESdocker-ce docker-ce-cli containerd.io apt-get update # 模拟安装仅获取依赖列表 apt-get install -s $PACKAGES | grep ^Inst | awk {print $2} /tmp/docker-packages-list.txt echo 需要下载的包列表已保存至 /tmp/docker-packages-list.txtb. 运行脚本后根据列表使用apt-get download逐一或批量下载mkdir -p /opt/docker-offline-debs cd /opt/docker-offline-debs for pkg in $(cat /tmp/docker-packages-list.txt); do apt-get download $pkg done或者使用xargs更高效cd /opt/docker-offline-debs cat /tmp/docker-packages-list.txt | xargs -n 1 apt-get download更推荐的工具使用dpkg和apt-rdepends可以更精确地生成依赖树。但考虑到复杂度对于一次性任务上述模拟安装法基本够用。关键是确保下载环境容器/虚拟机是“干净”的没有预先安装过Docker相关包否则依赖列表会不完整。4.2 传输包到目标服务器并安装将/opt/docker-offline-debs目录传输到目标服务器的/tmp/docker-debs。在目标服务器上使用dpkg安装本地deb包cd /tmp/docker-debs sudo dpkg -i *.deb如果遇到依赖错误因为dpkg不会自动处理依赖可以运行以下命令来修复sudo apt-get install -f注意apt-get install -f需要能访问配置好的软件源来获取缺失的依赖。在纯离线环境下这一步会失败。因此我们必须确保*.deb已经包含了所有依赖包。这就是为什么上一步下载完整依赖列表如此重要。如果dpkg -i报错缺少某个包你就必须回到下载机找到并下载那个缺失的包重新传输过来。启动与验证sudo systemctl start docker sudo systemctl enable docker sudo docker version sudo docker run hello-world4.3 针对Ubuntu的特定避坑点AppArmorUbuntu默认使用AppArmor作为安全模块。Docker的某些组件如containerd可能有自己的AppArmor配置文件。如果安装后Docker服务启动失败可以检查journalctl -u docker.service的日志看是否有AppArmor相关的拒绝信息。通常安装包会处理好这些配置但偶尔需要手动加载或调整。iptables与nftablesUbuntu 20.04 默认使用nftables作为后端但Docker默认操作的是iptables兼容层。这通常没问题但如果你在系统上自定义了复杂的防火墙规则可能会遇到冲突。确保iptables和nftables的相关工具包已安装。用户组安装完成后记得将需要使用Docker的非root用户加入docker用户组以避免每次都要sudo。sudo usermod -aG docker $USER重要修改组后用户需要重新登录才能生效。5. 通用配置与离线镜像加载安装好Docker引擎只是第一步。在内网环境中我们还需要解决镜像从哪里来的问题。5.1 配置Docker守护进程可选对于离线环境可能需要对Docker的配置进行一些调整例如修改数据存储根目录、配置私有镜像仓库地址等。配置文件通常位于/etc/docker/daemon.json如果不存在则创建。一个常见的配置是如果你在内网搭建了私有镜像仓库如Harbor需要在这里添加insecure-registries配置如果仓库是HTTP而非HTTPS{ insecure-registries: [your.private.registry:5000], registry-mirrors: [], data-root: /path/to/your/big/disk/docker }修改配置后需要重启Docker服务sudo systemctl restart docker5.2 离线加载Docker镜像这是离线环境的核心操作。你需要在一台有网的机器上将所需的镜像拉取下来保存为文件然后传输到内网服务器加载。在有网机器上拉取并保存镜像# 拉取镜像例如nginx docker pull nginx:alpine # 将镜像保存为tar归档文件 docker save -o nginx-alpine.tar nginx:alpine # 如果要保存多个镜像到一个文件 docker save -o my-images.tar nginx:alpine redis:alpine mysql:8传输tar文件到内网服务器。在内网服务器上加载镜像docker load -i nginx-alpine.tar加载后使用docker images即可看到导入的镜像。实操心得对于大型镜像或镜像集合docker save产生的tar文件会很大。可以考虑使用docker save | gzip进行压缩然后在目标服务器上用gzip -d解压后再docker load或者在传输过程中使用支持压缩的工具如scp -C。另外注意镜像的版本标签在生产环境中使用固定版本标签如nginx:1.21-alpine而非浮动标签如nginx:alpine以保证环境一致性。6. 故障排查与常见问题即使在严格按照步骤操作后仍可能遇到问题。这里列举几个我遇到过的典型问题及排查思路。问题一docker.service启动失败日志显示Failed to start Docker Application Container Engine.排查首先使用sudo systemctl status docker.service查看状态然后使用sudo journalctl -u docker.service -xe --no-pager查看详细日志。常见原因存储驱动问题日志中可能有overlay2相关的错误。检查内核模块sudo lsmod | grep overlay。如果未加载尝试sudo modprobe overlay。如果失败可能是内核不支持考虑升级内核或改用devicemapper驱动不推荐已弃用。cgroup挂载问题检查/sys/fs/cgroup目录。确保系统使用了cgroup v1Docker对cgroup v2的完全支持是较新版本。可以检查/proc/mounts | grep cgroup。SELinux/AppArmor如前述查看日志中是否有安全模块的拒绝信息。可以尝试临时禁用它们来确认是否是根本原因。问题二运行docker run hello-world时报错提示无法连接到Docker守护进程 (Cannot connect to the Docker daemon at unix:///var/run/docker.sock)排查这通常意味着Docker服务没有在运行或者当前用户没有权限访问Docker的Unix Socket。解决确认服务已启动sudo systemctl status docker。确认当前用户是否在docker用户组内groups $USER。如果不在使用sudo usermod -aG docker $USER添加并重新登录。直接使用sudo docker run hello-world测试如果成功就是用户组权限问题。问题三容器无法访问外部网络排查首先在容器内ping 8.8.8.8测试基础连通性。如果失败检查主机防火墙是否阻止了Docker网桥的流量参考前面防火墙配置部分。Docker的bridge网络是否正常创建docker network ls。主机的IP转发是否开启sysctl net.ipv4.ip_forward应为1。如果不是编辑/etc/sysctl.conf设置net.ipv4.ip_forward 1然后执行sysctl -p生效。离线安装Docker确实比在线安装繁琐但它是掌握Linux软件包管理和Docker底层依赖的绝佳实践。整个过程的核心思想就是“环境复制”在一台联网的、与目标环境一致的机器上模拟出完整的安装过程并将所有产生的软件包“快照”下来搬运到离线环境中还原。只要前期探查仔细包下载完整安装过程其实非常稳定。最后别忘了在一切就绪后在内网环境搭建一个私有镜像仓库如Harbor这将彻底解决后续镜像分发和管理的问题让离线环境的容器运维走上正轨。
返回列表