news 2026/9/20 3:46:52

内网离线安装Docker与docker-compose全攻略:从rpm包到镜像导入

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
内网离线安装Docker与docker-compose全攻略:从rpm包到镜像导入

1. 内网离线部署的真实痛点与整体思路

1.1 为什么内网环境装 Docker 这么折腾

但凡在金融、制造、医疗这类对网络管控严格的行业待过,你一定遇到过这种场景:客户现场给了一台 CentOS 7 的物理机,网络完全隔离,连外网 DNS 都不通,但项目要求必须用 Docker 跑微服务。这时候你习惯性地敲下yum install -y docker-ce,等来的只有一行Could not resolve host: mirrors.aliyun.com,然后就是漫长的沉默。

内网离线安装 Docker 的核心矛盾在于:Docker 本身不是一个孤零零的二进制文件,它依赖一整套运行时组件——containerdruncdocker-ce-clidocker-ce-rootless-extras,还有一堆系统级的依赖包如libcgroupcontainer-selinuxfuse-overlayfs等。在线安装时 yum 会自动帮你解决这些依赖关系,离线环境下这些全得你自己搞定。更麻烦的是docker-compose,它从 v2 开始变成了一个独立的 Go 二进制文件,虽然安装简单了,但版本匹配和路径配置又成了新的坑点。

我见过太多人在内网部署时踩坑:有人只拷了docker-ce的 rpm 包,结果装到一半报依赖缺失;有人把 compose 装到了/usr/local/bin但 systemd 服务找不到;还有人忽略了 SELinux 和防火墙的配置,容器起来了但端口死活不通。这些问题在在线环境下可能一条命令就解决了,但在离线环境里,每一个都得手动处理。

1.2 整体方案选型:为什么用 rpm 离线包而不是二进制

离线安装 Docker 有两条路可走:一是下载静态二进制包(docker-xx.tgz),解压后手动配置 systemd 服务;二是下载完整的 rpm 包集合,用yum localinstallrpm -ivh安装。我强烈推荐第二种,原因有三:

第一,rpm 包会自动处理依赖关系。虽然离线环境下 yum 不能联网下载依赖,但只要你把依赖包也一并下载好放在同一个目录,yum localinstall *.rpm就能自动按正确顺序安装,省去手动解决依赖的麻烦。第二,rpm 安装会自动创建docker用户组、配置 systemd 服务文件、设置好默认的daemon.json路径,这些在二进制方案里全得手动做。第三,rpm 包支持yum remove干净卸载,二进制方案卸载时容易残留文件。

至于docker-compose,从 v2 版本开始官方只提供独立的二进制文件,直接下载对应架构的二进制放到/usr/local/bin//usr/libexec/docker/cli-plugins/即可。注意 v2 版本的 compose 命令是docker compose(作为 docker 的子命令),而不是独立的docker-compose命令,这一点后面会详细说。

整个方案的核心思路可以概括为:在外网机器上准备完整的离线安装包集合,通过物理介质传输到内网机器,然后按顺序安装并验证。听起来简单,但每一步都有细节需要注意。

1.3 准备工作:外网机器上的包下载策略

在外网机器上准备离线包时,最关键的是要保证目标机器的操作系统版本、CPU 架构和外网机器一致。CentOS 7 有 x86_64 和 aarch64 两种架构,Docker 的 rpm 包是不同的。你可以用uname -m确认架构,用cat /etc/centos-release确认系统版本。

下载 rpm 包有两种方式。第一种是用yumdownloader工具,它能自动把指定包及其所有依赖下载到本地目录:

# 安装 yumdownloader 工具 yum install -y yum-utils # 下载 docker-ce 及其所有依赖到指定目录 mkdir -p /tmp/docker-offline yumdownloader --resolve --destdir=/tmp/docker-offline docker-ce docker-ce-cli containerd.io docker-compose-plugin

这里--resolve参数是关键,它会自动解析并下载所有依赖包。如果你不加这个参数,下载下来的 rpm 包在内网安装时会报依赖缺失。

第二种方式是直接从 Docker 官方仓库手动下载。Docker 的 rpm 包托管在https://download.docker.com/linux/centos/7/x86_64/stable/Packages/路径下,你可以用浏览器或wget逐个下载。这种方式适合你明确知道需要哪些包的情况,但容易漏掉依赖。

我个人的习惯是用yumdownloader --resolve下载,然后把整个目录打包成一个 tar 文件,通过 U 盘或内网文件服务器传到目标机器。打包命令很简单:

cd /tmp tar czvf docker-offline.tar.gz docker-offline/

传输到内网后解压即可。这里有个小技巧:如果你不确定目标机器是否缺少某些基础依赖,可以在外网机器上先用yum deplist docker-ce查看完整的依赖树,确保没有遗漏。

注意:CentOS 7 的container-selinux包版本有讲究,如果目标机器已经装了旧版本的 SELinux 策略包,可能需要先升级。建议在离线包中同时包含container-selinux的最新版本。

2. 核心细节解析与实操要点

2.1 rpm 包安装顺序与依赖处理

把离线包传到内网机器后,第一步是解压并查看包列表:

tar xzvf docker-offline.tar.gz cd docker-offline ls -lh *.rpm

你会看到类似这样的文件列表:

containerd.io-1.6.21-3.1.el7.x86_64.rpm container-selinux-2.119.2-1.911c772.el7_8.noarch.rpm docker-ce-24.0.5-1.el7.x86_64.rpm docker-ce-cli-24.0.5-1.el7.x86_64.rpm docker-ce-rootless-extras-24.0.5-1.el7.x86_64.rpm docker-compose-plugin-2.20.2-1.el7.x86_64.rpm docker-scan-plugin-0.23.0-1.el7.x86_64.rpm fuse-overlayfs-0.7.2-6.el7_8.x86_64.rpm fuse3-libs-3.6.1-4.el7.x86_64.rpm slirp4netns-0.4.3-4.el7_8.x86_64.rpm

安装时直接用yum localinstall一次性安装所有包:

yum localinstall -y *.rpm

yum localinstall会自动分析包之间的依赖关系并按正确顺序安装。如果你用rpm -ivh *.rpm,可能会因为安装顺序不对而报依赖错误。当然,如果你对包之间的依赖关系非常清楚,也可以手动按顺序安装:先装container-selinux,再装containerd.io,然后是docker-ce-cli,最后装docker-ce

安装完成后,验证 Docker 是否安装成功:

docker version

如果看到 Client 和 Server 的版本信息,说明安装成功。如果只看到 Client 信息,Server 部分报错,说明 Docker 守护进程没有启动,需要检查 systemd 服务状态。

2.2 docker-compose 的两种安装方式与版本选择

docker-compose的安装是另一个容易出问题的环节。从 Docker Compose v2 开始,官方推荐的方式是安装docker-compose-plugin,它会把 compose 作为 docker 的一个 CLI 插件安装到/usr/libexec/docker/cli-plugins/目录下。安装后你可以用docker compose(注意中间是空格)来调用。

如果你下载的离线包中包含了docker-compose-plugin,那么yum localinstall时会自动安装,不需要额外操作。验证方式:

docker compose version

如果这个命令报错,说明插件没有正确安装。你可以手动检查插件目录:

ls -lh /usr/libexec/docker/cli-plugins/

正常情况下应该能看到docker-compose这个二进制文件。如果没有,你可以从离线包中单独解压这个 rpm 包,把里面的二进制文件拷到对应目录:

rpm2cpio docker-compose-plugin-2.20.2-1.el7.x86_64.rpm | cpio -idmv cp usr/libexec/docker/cli-plugins/docker-compose /usr/libexec/docker/cli-plugins/ chmod +x /usr/libexec/docker/cli-plugins/docker-compose

如果你更习惯用独立的docker-compose命令(v1 风格),也可以下载 compose 的独立二进制文件。GitHub 的 release 页面提供了各版本的二进制下载,选择对应架构的文件放到/usr/local/bin/并赋予执行权限即可:

chmod +x /usr/local/bin/docker-compose docker-compose --version

不过我要提醒一句:v1 版本的 compose 已经停止维护,新项目建议直接用 v2 的插件方式。如果你维护的老项目用的是docker-compose命令,可以在/usr/local/bin/下创建一个软链接指向插件二进制:

ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/local/bin/docker-compose

这样两种命令风格都能用。

2.3 系统配置:SELinux、防火墙与内核参数

Docker 安装完成后,还需要对系统做一些配置才能正常使用。这些配置在在线安装时可能被 yum 自动处理了,但离线环境下需要手动确认。

首先是 SELinux。CentOS 7 默认开启 SELinux,这会导致容器挂载宿主机目录时出现权限问题。你可以选择永久关闭 SELinux:

setenforce 0 sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

或者保留 SELinux 但在 Docker 配置中启用selinux-enabled。我个人的建议是内网环境直接关闭 SELinux,省去很多权限排查的麻烦。如果安全要求高必须开启,那就要在daemon.json中配置"selinux-enabled": true,并确保container-selinux包已正确安装。

防火墙方面,CentOS 7 默认使用 firewalld。Docker 启动后会自动创建docker0网桥并配置 iptables 规则,但 firewalld 可能会干扰容器网络。你可以选择关闭 firewalld:

systemctl stop firewalld systemctl disable firewalld

或者保留 firewalld 但把docker0网桥加入信任区域:

firewall-cmd --permanent --zone=trusted --add-interface=docker0 firewall-cmd --reload

内核参数方面,Docker 需要开启 IP 转发:

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf sysctl -p

这个参数在大多数 CentOS 7 系统上默认是开启的,但有些安全加固过的系统会关闭它,导致容器无法访问外网。建议安装后主动检查一下。

2.4 配置国内镜像加速与数据目录迁移

内网环境虽然不能访问外网,但如果你所在的内网有私有镜像仓库,或者有内部代理可以访问部分外网资源,配置镜像加速能显著提升拉取速度。编辑/etc/docker/daemon.json

{ "registry-mirrors": ["https://your-internal-mirror.example.com"], "data-root": "/data/docker", "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" } }

这里>systemctl daemon-reload systemctl restart docker systemctl enable docker

验证配置是否生效:

docker info | grep -A5 "Registry Mirrors" docker info | grep "Docker Root Dir"

3. 实操过程与核心环节实现

3.1 完整离线安装流程:从外网打包到内网验证

我把整个流程拆成两个阶段:外网准备阶段和内网安装阶段。外网准备阶段的目标是生成一个完整的离线安装包,内网安装阶段的目标是把这些包正确安装并配置好。

外网准备阶段,在一台与目标机器同架构、同系统版本的机器上执行:

# 1. 安装必要工具 yum install -y yum-utils createrepo # 2. 添加 Docker 官方仓库 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 3. 创建离线包目录 mkdir -p /opt/docker-offline/packages # 4. 下载 Docker 及依赖 yumdownloader --resolve --destdir=/opt/docker-offline/packages \ docker-ce docker-ce-cli containerd.io docker-compose-plugin # 5. 下载一些常用工具(可选) yumdownloader --resolve --destdir=/opt/docker-offline/packages \ vim net-tools lsof # 6. 生成 repodata(可选,方便用 yum 本地源安装) createrepo /opt/docker-offline/packages # 7. 打包 cd /opt/docker-offline tar czvf docker-offline-full.tar.gz packages/

这里我额外下载了vimnet-toolslsof这几个工具,因为很多最小化安装的 CentOS 7 系统连这些基础工具都没有,排查问题时很不方便。createrepo生成的 repodata 可以让你在内网用yum --disablerepo=* --enablerepo=local的方式安装,比yum localinstall更灵活。

内网安装阶段,在目标机器上执行:

# 1. 解压离线包 tar xzvf docker-offline-full.tar.gz -C /opt/ # 2. 方式一:直接用 yum localinstall cd /opt/packages yum localinstall -y *.rpm # 方式二:配置本地 yum 源 cat > /etc/yum.repos.d/local.repo <<EOF [local] name=Local Repository baseurl=file:///opt/packages enabled=1 gpgcheck=0 EOF yum --disablerepo=* --enablerepo=local install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin # 3. 启动 Docker systemctl start docker systemctl enable docker # 4. 验证 docker version docker compose version docker run --rm hello-world

最后一步docker run --rm hello-world需要本地有hello-world镜像。如果内网完全隔离,你需要提前在外网机器上docker pull hello-world,然后docker save成 tar 文件传到内网,再docker load进去。这是离线环境下验证 Docker 是否正常工作的标准流程。

3.2 离线镜像的导入导出:让容器真正跑起来

Docker 装好了只是第一步,真正要让业务跑起来,还需要把镜像也弄到内网。Docker 提供了saveload两个命令来处理镜像的离线传输。

在外网机器上,把需要的镜像保存成 tar 文件:

# 保存单个镜像 docker save -o nginx-1.24.tar nginx:1.24 # 保存多个镜像到一个文件 docker save -o all-images.tar nginx:1.24 redis:7.0 mysql:8.0 # 批量保存所有镜像 docker save -o all-images.tar $(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "<none>")

这里有个细节:docker save保存的镜像包含所有层,文件可能很大。如果你只需要传输到内网,可以用gzip压缩:

docker save nginx:1.24 | gzip > nginx-1.24.tar.gz

在内网机器上导入:

# 导入 tar 文件 docker load -i nginx-1.24.tar # 导入 gzip 压缩的文件 gunzip -c nginx-1.24.tar.gz | docker load

导入后可以用docker images确认镜像是否加载成功。注意docker load不会覆盖已有的同名镜像,如果内网已经有旧版本,需要先docker rmi删除再导入。

对于docker-compose项目,你还需要把项目文件也传到内网。通常包括docker-compose.yml.env文件、配置文件目录、初始化 SQL 脚本等。建议把这些文件放在一个目录里一起打包:

tar czvf myapp-deploy.tar.gz docker-compose.yml .env config/ init-sql/

在内网解压后,用docker compose up -d启动。如果 compose 文件中引用了镜像,确保这些镜像已经提前docker load进去了。

3.3 参数计算与资源规划:容器配置的取舍

在内网环境部署时,资源规划往往比在线环境更重要,因为一旦配置不当,调整起来很麻烦。我以一台 8 核 16G 内存的 CentOS 7 机器为例,说说容器资源限制的配置思路。

假设你要部署一个典型的 Web 应用栈:Nginx + 应用服务 + MySQL + Redis。在docker-compose.yml中,可以通过deploy.resourcesmem_limitcpus来限制资源。注意deploy.resources只在 Swarm 模式下生效,单机模式下要用mem_limitcpus

services: mysql: image: mysql:8.0 mem_limit: 4g cpus: 2.0 environment: MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} volumes: - ./data/mysql:/var/lib/mysql restart: unless-stopped redis: image: redis:7.0 mem_limit: 1g cpus: 0.5 command: redis-server --maxmemory 800mb --maxmemory-policy allkeys-lru volumes: - ./data/redis:/data restart: unless-stopped app: image: myapp:latest mem_limit: 2g cpus: 1.5 depends_on: - mysql - redis restart: unless-stopped nginx: image: nginx:1.24 mem_limit: 512m cpus: 0.5 ports: - "80:80" - "443:443" volumes: - ./config/nginx.conf:/etc/nginx/nginx.conf:ro restart: unless-stopped

这里的内存分配逻辑是:MySQL 给 4G(InnoDB 缓冲池默认 128M,建议根据数据量调整到 1-2G),Redis 给 1G(maxmemory设为 800M 留出余量),应用服务给 2G,Nginx 给 512M。总共约 7.5G,加上系统本身占用 2-3G,16G 内存的机器还有余量应对突发流量。

CPU 分配方面,MySQL 给 2 核,应用服务给 1.5 核,Redis 和 Nginx 各 0.5 核,总共 4.5 核,8 核机器留出 3.5 核给系统和突发负载。注意cpus参数是软限制,容器在空闲时不会占用这么多,只有在竞争时才会受限。

restart: unless-stopped这个策略很重要,它保证容器在异常退出时自动重启,但手动停止后不会自动拉起。在内网环境中,机器可能长期无人值守,这个配置能避免服务意外挂掉后没人处理。

3.4 实操现场记录:一次完整的部署过程

我拿最近做的一个项目举例,目标机器是一台内网 CentOS 7.9,8 核 16G,系统盘 100G,数据盘 500G。部署的是一个 Spring Boot + MySQL + Redis + Nginx 的应用。

第一步,在外网机器上准备离线包。我用的是 CentOS 7.9 的虚拟机,执行了前面说的yumdownloader命令,下载了 Docker 相关包和常用工具。同时把应用镜像docker save成 tar 文件,应用部署文件打包成 tar.gz。

第二步,通过内网文件服务器把三个文件传到目标机器:docker-offline-full.tar.gz(约 120M)、app-images.tar.gz(约 800M)、app-deploy.tar.gz(约 5M)。

第三步,在目标机器上解压安装 Docker:

tar xzvf docker-offline-full.tar.gz -C /opt/ cd /opt/packages yum localinstall -y *.rpm systemctl start docker systemctl enable docker docker version

第四步,配置 Docker 数据目录到数据盘:

mkdir -p /data/docker cat > /etc/docker/daemon.json <<EOF { "data-root": "/data/docker", "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" } } EOF systemctl daemon-reload systemctl restart docker

第五步,导入镜像:

gunzip -c app-images.tar.gz | docker load docker images

第六步,解压部署文件并启动:

tar xzvf app-deploy.tar.gz -C /opt/app/ cd /opt/app docker compose up -d docker compose ps

第七步,验证服务:

curl -I http://localhost docker compose logs -f app

整个过程大约花了 40 分钟,其中大部分时间花在文件传输和镜像导入上。实际安装 Docker 只用了不到 5 分钟。

4. 常见问题与排查技巧实录

4.1 安装阶段的高频报错与解决

离线安装 Docker 时,最常见的报错集中在依赖缺失和版本冲突上。我整理了一个速查表:

报错信息原因解决方法
Error: Package: docker-ce-xxx requires containerd.io >= xxx缺少 containerd.io 包或版本过低下载对应版本的 containerd.io rpm 包一并安装
Error: Package: container-selinux is obsoleted by docker-cecontainer-selinux 版本冲突先卸载旧版 container-selinux,再安装新版
Error: transaction check error: file /usr/bin/docker from install conflicts已安装旧版 Dockeryum remove docker docker-client docker-common清理
Failed to start docker.service: Unit not foundsystemd 服务文件未安装检查 docker-ce 包是否完整安装,重新安装
docker: command not foundPATH 未包含 Docker 二进制目录检查/usr/bin/docker是否存在,确认 PATH 配置

其中container-selinux版本冲突是最常见的。CentOS 7 默认仓库里的container-selinux版本可能比较旧,而新版 Docker 需要更高版本。解决方法是下载最新版的container-selinuxrpm 包,先安装它再安装 Docker:

rpm -ivh container-selinux-2.119.2-1.911c772.el7_8.noarch.rpm yum localinstall -y docker-ce*.rpm containerd.io*.rpm

如果系统里已经装了旧版container-selinux,需要先升级:

rpm -Uvh container-selinux-2.119.2-1.911c772.el7_8.noarch.rpm

另一个常见问题是docker-compose命令找不到。如果你装的是docker-compose-plugin,命令是docker compose而不是docker-compose。如果你习惯用后者,需要创建软链接:

ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/local/bin/docker-compose

4.2 运行阶段的网络与权限问题

Docker 装好之后,运行容器时可能遇到网络不通或权限不足的问题。这类问题在内网环境下排查起来比较麻烦,因为不能随便上网搜。

容器无法访问外网,通常是因为 IP 转发没开启或 iptables 规则被清空。检查方法:

sysctl net.ipv4.ip_forward iptables -t nat -L POSTROUTING -n

如果ip_forward是 0,执行sysctl -w net.ipv4.ip_forward=1并写入/etc/sysctl.conf。如果 iptables 的POSTROUTING链中没有 Docker 的 MASQUERADE 规则,重启 Docker 服务会自动重建。

容器端口无法从宿主机访问,检查 Docker 的端口映射是否正确:

docker port <container_name> netstat -tlnp | grep <port>

如果docker port显示映射了但netstat看不到监听,可能是 firewalld 拦截了。临时关闭 firewalld 测试:

systemctl stop firewalld

如果关闭后能访问,说明需要配置 firewalld 规则。

挂载宿主机目录时权限拒绝,这是 SELinux 导致的。临时解决:

setenforce 0

永久解决是修改/etc/selinux/configSELINUX=enforcing改为SELINUX=disabled,然后重启。或者在挂载时加:z:Z标签:

volumes: - ./data:/var/lib/mysql:z

:z表示多个容器共享该目录,:Z表示私有。注意这两个标签只在 SELinux 开启时有效。

4.3 离线环境下的镜像管理技巧

内网环境下,镜像管理是个持续性的工作。你不能像在线环境那样随时docker pull,所以需要建立一套镜像导入导出的规范。

我的做法是在外网维护一个镜像仓库目录,每次需要更新镜像时,用脚本批量导出:

#!/bin/bash # export-images.sh IMAGES=( "nginx:1.24" "redis:7.0" "mysql:8.0" "myapp:latest" ) OUTPUT_DIR="/opt/image-exports" DATE=$(date +%Y%m%d) mkdir -p ${OUTPUT_DIR}/${DATE} for img in "${IMAGES[@]}"; do filename=$(echo ${img} | tr ':/' '--') docker save ${img} | gzip > ${OUTPUT_DIR}/${DATE}/${filename}.tar.gz echo "Exported ${img} to ${filename}.tar.gz" done # 生成校验文件 cd ${OUTPUT_DIR}/${DATE} md5sum *.tar.gz > checksums.md5

在内网导入时,先校验文件完整性:

md5sum -c checksums.md5

然后批量导入:

for f in *.tar.gz; do gunzip -c $f | docker load done

这里有个经验:镜像的 tag 一定要规范,不要用latest,因为latest在不同时间导出的内容可能不同,容易搞混。建议用版本号或日期作为 tag,比如myapp:20240115

另外,定期清理内网机器上不用的镜像也很重要。可以用docker image prune清理悬空镜像,用docker system prune清理停止的容器、无用网络和悬空镜像。但注意docker system prune -a会删除所有未被使用的镜像,执行前确认清楚。

4.4 独家避坑经验:那些文档里不会写的事

说几个我在实际项目中踩过的坑,都是文档里不会写的。

第一个坑:yum localinstall在最小化安装的系统上可能失败。CentOS 7 最小化安装时,yum本身可能缺少某些插件,导致localinstall命令不可用。这时候可以用rpm -ivh逐个安装,但要注意顺序。或者先安装yum-plugin-local包。

第二个坑:Docker 数据目录迁移后权限问题。如果你把>semanage fcontext -a -t container_var_lib_t "/data/docker(/.*)?" restorecon -Rv /data/docker

如果semanage命令不存在,需要先安装policycoreutils-python包。

第三个坑:docker compose.env文件路径问题docker compose默认从当前目录读取.env文件,如果你在别的目录执行docker compose -f /opt/app/docker-compose.yml up.env文件不会被加载。解决方法是加--env-file参数指定路径,或者先cd到 compose 文件所在目录。

第四个坑:离线环境下时间同步问题。内网机器如果时间不准,会导致容器内的时间也不准,进而影响日志时间戳、证书验证等。建议在内网搭建 NTP 服务器,或者至少确保宿主机时间正确。Docker 容器默认使用宿主机时间,但如果你在容器里装了tzdata并设置了TZ环境变量,时区会按容器配置来。

第五个坑:docker save大镜像时内存占用高docker save会把镜像的所有层打包,如果镜像很大(比如几个 G),可能会占用较多内存和磁盘空间。建议先docker pull到本地,用docker save时加gzip压缩,并且确保/tmp或输出目录有足够空间。

5. 内网 Docker 环境的长期维护建议

5.1 版本管理与升级策略

内网环境的 Docker 版本管理比在线环境更需要规划。因为升级需要重新走一遍离线安装流程,所以不能像在线环境那样随意yum update

我的建议是:保持 Docker 版本与业务需求匹配,不盲目追新。Docker 24.0.x 是目前的稳定版本,支持到 2024 年底。如果你的业务没有用到新版本特性,没必要频繁升级。升级前先在外网测试环境验证,确认新版本与现有 compose 文件、镜像兼容后再在内网操作。

升级的步骤和首次安装类似:下载新版 rpm 包,传到内网,yum localinstall覆盖安装,然后重启 Docker 服务。注意升级前备份/etc/docker/daemon.json和 compose 文件,升级后检查配置是否被覆盖。

docker-compose-plugin的版本也要和 Docker 版本匹配。一般来说,compose 插件版本可以独立于 Docker 引擎版本,但建议使用官方推荐的组合。你可以在 Docker 官方文档的 release notes 中查到版本兼容性信息。

5.2 监控与日志:让问题可追溯

内网环境出了问题,排查起来比在线环境困难,所以监控和日志尤为重要。Docker 本身提供了docker eventsdocker logs命令,但长期运行需要更系统的方案。

我通常会在内网部署一个轻量的监控栈:cAdvisor收集容器指标,Prometheus存储数据,Grafana展示面板。这三个组件都可以用 Docker 跑,镜像提前docker save进去就行。docker-compose.yml大概长这样:

services: cadvisor: image: gcr.io/cadvisor/cadvisor:v0.47.0 volumes: - /:/rootfs:ro - /var/run:/var/run:ro - /sys:/sys:ro - /var/lib/docker/:/var/lib/docker:ro ports: - "8080:8080" restart: unless-stopped prometheus: image: prom/prometheus:v2.47.0 volumes: - ./config/prometheus.yml:/etc/prometheus/prometheus.yml:ro - ./data/prometheus:/prometheus ports: - "9090:9090" restart: unless-stopped grafana: image: grafana/grafana:10.1.0 volumes: - ./data/grafana:/var/lib/grafana ports: - "3000:3000" restart: unless-stopped

日志方面,除了 Docker 的json-file驱动,还可以考虑journald驱动,把容器日志统一交给 systemd 管理。配置方法是在daemon.json中设置"log-driver": "journald",然后用journalctl -u docker查看。不过journald的日志查询不如json-file灵活,我一般还是用json-file配合日志轮转。

5.3 备份与恢复:数据安全底线

内网环境的数据备份往往被忽视,但一旦出问题就是大问题。Docker 环境需要备份的主要有三部分:镜像、容器数据卷、compose 文件。

镜像备份用docker save定期导出关键镜像,存到内网文件服务器或磁带库。数据卷备份可以用docker run --rm -v volume_name:/data -v /backup:/backup alpine tar czf /backup/volume_name.tar.gz -C /data .的方式打包。compose 文件和配置文件建议用 Git 管理,内网可以搭建 GitLab 或 Gitea 做版本控制。

恢复时,先docker load导入镜像,再解压数据卷备份到对应目录,最后docker compose up -d启动。注意数据卷的恢复要在容器停止状态下进行,否则可能数据不一致。

我个人的习惯是每周做一次全量备份,每天做一次增量备份。备份文件保留最近 4 周,过期的自动清理。这套流程用 cron 脚本就能实现,不需要额外的备份软件。

5.4 安全加固:内网也不能掉以轻心

很多人觉得内网环境安全要求低,Docker 配置比较随意。但实际上,内网一旦被突破,Docker 的 root 权限会成为攻击者的跳板。几个基本的安全加固措施:

第一,限制 Docker API 的访问。默认情况下 Docker 守护进程监听 Unix socket,这是安全的。但如果你开启了 TCP 监听(-H tcp://0.0.0.0:2375),任何能访问该端口的人都能控制 Docker。内网环境也不建议开启 TCP 监听,如果必须开启,一定要配置 TLS 证书认证。

第二,容器不要用 root 用户运行。在 Dockerfile 中用USER指令切换到非 root 用户,或者在 compose 文件中用user: "1000:1000"指定。这样即使容器被突破,攻击者也只有普通用户权限。

第三,限制容器的能力。默认情况下容器拥有不少 Linux capabilities,可以通过cap_dropcap_add精细控制:

services: app: image: myapp:latest cap_drop: - ALL cap_add: - NET_BIND_SERVICE security_opt: - no-new-privileges:true

no-new-privileges防止容器内的进程通过 setuid 等方式提权,是个很实用的安全选项。

第四,定期更新镜像。内网环境容易忽略镜像更新,但旧镜像可能包含已知漏洞。建议每季度检查一次关键镜像的更新情况,及时导入新版本。

6. 从零到一:给新手的快速上手清单

6.1 五分钟检查清单

如果你第一次做内网离线安装,按这个清单逐项确认,能避开 90% 的坑:

  • [ ] 确认目标机器架构(uname -m)和系统版本(cat /etc/centos-release
  • [ ] 在外网机器上下载完整 rpm 包(用yumdownloader --resolve
  • [ ] 下载docker-compose-plugin或 compose 独立二进制
  • [ ] 准备hello-world镜像用于验证
  • [ ] 传输离线包到内网(U 盘或文件服务器)
  • [ ] 解压后yum localinstall -y *.rpm
  • [ ] 启动 Docker 并设置开机自启
  • [ ] 配置daemon.json(数据目录、日志轮转、镜像加速)
  • [ ] 关闭 SELinux 或配置正确标签
  • [ ] 配置防火墙或关闭 firewalld
  • [ ] 导入业务镜像
  • [ ] 用docker compose up -d启动服务
  • [ ] 验证服务可访问

6.2 常用命令速查

内网环境下,这些命令你会反复用到:

# 查看 Docker 版本和配置 docker version docker info # 查看镜像和容器 docker images docker ps -a # 导入导出镜像 docker save -o image.tar image:tag docker load -i image.tar # 查看容器日志 docker logs -f --tail 100 container_name # 进入容器 docker exec -it container_name /bin/bash # 查看容器资源占用 docker stats # 清理无用资源 docker system prune -a # compose 操作 docker compose up -d docker compose down docker compose ps docker compose logs -f docker compose restart

6.3 我个人的经验总结

做了这么多内网部署项目,我最大的体会是:离线安装的核心不是技术难度,而是细致程度。在线安装时你不需要关心依赖关系、版本匹配、路径配置,因为 yum 和 Docker 官方脚本都帮你处理了。但离线环境下,每一个细节都需要你自己确认。

我的习惯是每次部署前先列一个清单,把需要下载的包、需要配置的参数、需要验证的步骤都写下来,部署时逐项打勾。这样虽然看起来麻烦,但能避免遗漏关键步骤导致的返工。另外,离线包建议多准备一份,放在不同的物理介质上,万一 U 盘坏了或者文件服务器挂了,还有备份可用。

还有一点:内网环境的文档记录很重要。每次部署后把实际操作的命令、遇到的问题、解决方法都记录下来,形成自己的知识库。下次遇到类似环境时,直接翻记录比重新摸索快得多。我现在的知识库里积累了十几个不同客户环境的部署记录,每次新项目都能找到参考。

最后分享一个小技巧:如果你经常需要做内网部署,可以做一个“万能离线包”,包含 Docker、compose、常用工具(vim、net-tools、lsof、curl、wget)以及几个基础镜像(alpine、busybox、nginx)。这个包大概 1-2G,放在 U 盘里随身带,到了现场直接解压安装,能省去很多准备时间。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 3:45:49

智慧社区一站式移动服务平台开题答辩全流程经验分享

1. 选题与定题思路&#xff1a;为什么一眼锁定了“智慧社区”1.1 从“想做App”到“选题落地”的三层筛选逻辑我最初在面对开题选题时&#xff0c;脑子里其实只有一个模糊方向&#xff1a;想做一个和日常生活结合度高的移动端项目&#xff0c;最好是那种答辩现场一说出来&#…

作者头像 李华
网站建设 2026/9/20 3:45:12

C语言循环结构详解:while、do-while与for的用法、区别及避坑指南

写C语言要是没搞懂循环&#xff0c;后面的链表、排序、文件读写这些内容你基本都下不了手。while和for这两个循环结构&#xff0c;差不多覆盖了日常开发里90%以上的重复逻辑场景&#xff0c;甚至可以说&#xff0c;循环玩得溜不溜&#xff0c;直接决定了你写出来的代码是“能跑…

作者头像 李华
网站建设 2026/9/20 3:41:27

Textual 样式指南:用 styles 对象打造精致的终端用户界面

Textual 样式指南&#xff1a;用 styles 对象打造精致的终端用户界面 【免费下载链接】textual The lean application framework for Python. Build sophisticated user interfaces with a simple Python API. Run your apps in the terminal and a web browser. 项目地址: h…

作者头像 李华
网站建设 2026/9/20 3:39:50

基于Sobel算子的垂直边缘检测系统:原理、实现与工程调参

做图像处理和计算机视觉项目这几年&#xff0c;我发现一个很有意思的现象&#xff1a;很多初学边缘检测的朋友&#xff0c;一上来就对着Canny整条链路猛看&#xff0c;反而忽略了最基础、也最容易被工程化的Sobel算子。实际上在工业视觉、文档扫描、PCB缺陷检测这些场景里&…

作者头像 李华