ARTICLE DETAIL

资讯详情

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

无网环境部署LiteIO网关:离线物料准备、镜像导入与验证全流程

无网环境部署LiteIO网关:离线物料准备、镜像导入与验证全流程 直接访问内网服务器部署服务这事儿我做过太多次了。大多数部署文档默认你有外网张口就是apt install、pip install、docker pull可真到了生产内网机房机器上什么都没有连个基础依赖都得靠U盘往里倒。最近一次给客户部署 LiteIO 网关服务就碰上这种典型场景外网下载好的东西怎么完整搬进隔离区搬进去之后怎么装、怎么配、怎么验证踩了一圈坑。这篇把整套离线部署流程和中间的关键判断逻辑整理出来给同样要面对无网环境的兄弟们做个参考。LiteIO 属于那种轻量级的 IO 网关组件常用在边缘节点或内网数据交换场景里负责把业务系统的请求转发到后端服务顺带做点协议转换、流量限制之类的活。这类组件本身不复杂部署难点几乎全集中在离线两个字上怎么把镜像、依赖包、配置文件干干净净地准备好怎么在内网机器上一次装成功以及装完之后怎么判断它真的在正常工作而不是半死不活。下面按我实际操作的时间线来讲。1. 先搞清楚 LiteIO 的交付形态这决定了整个离线方案怎么设计拿到一个软件要在内网部署第一步不是急着找安装包而是确认它的交付形态。这一步判断错了后面全白干。LiteIO 在不同版本和不同客户的现场交付方式通常有四种处理逻辑完全不一样。发行包形式。一个 zip 或 tar.gz 压缩包里面是编译好的二进制制品、配置文件模板、启动脚本。这类是最友好的因为它不依赖网络安装过程解压即用。缺点是它往往依赖运行环境比如需要特定版本的 JDK、Node.js 或基础系统库而这些基础环境在内网里可能根本没有。容器镜像形式。这是现在最常见的方式也是 LiteIO 官方文档里主推的方式。一个镜像 tar 文件通过docker load导进来就能跑。它的好处是运行环境、依赖库全在镜像里基本不受宿主机器环境影响。缺点是镜像本身可能很大而且如果镜像依赖外部基础镜像比如 FROM ubuntu:22.04离线导入时会遭遇依赖链断裂。源码编译形式。拿到手是一包源码需要在目标机器上编译出可执行文件。这种形式在离线环境里最痛苦因为编译期依赖往往比运行期依赖多得多。除非客户方明确要求从源码构建否则我会尽量避免在离线环境里走这条路。包管理安装形式。比如 deb/rpm 包或者通过 pip/npm 安装。这类形式有个通病依赖关系是链式的你要装 A它要求先装 B 和 CB 和 C 之间还有版本约束。在在线环境里包管理器自动处理离线环境里缺一个就得手动找非常耗时。以我这次部署的 LiteIO 为例客户方交付的是容器镜像加 Docker Compose 编排文件。那就走镜像离线导入这条路。这几年我在内网部署网关类组件遇到十次里有七次是容器形态所以后面主线的操作都围绕容器方案展开发行包和源码形式我会在相关环节单独提一句差异。另外提个醒LiteIO 部署前要确认一件事它是不是商业授权软件。如果是离线环境里可能涉及 license 激活而激活往往需要联网验证这个坑比技术问题更麻烦一定要提前和软件供应商确认好。2. 在联网机器上准备离线物料包一次性做好省得来回跑离线部署的核心思想是把所有需要的东西提前在一台能上网的机器上准备好打成包再搬到内网。听起来简单但所有需要的东西这个清单很容易漏。我吃过亏因为在联网机器上准备时少拉了一个镜像到了内网才发现来回折腾一趟就是一整天所以在这里把完整的准备流程拆开讲。2.1 镜像拉取与保存别漏了依赖镜像第一步是在联网机器上把 LiteIO 镜像拉下来。假设镜像名是registry.example.com/liteio/gateway:2.4.1实际部署时替换为你自己的镜像地址执行docker pull registry.example.com/liteio/gateway:2.4.1但这里有个关键细节LiteIO 的镜像很可能依赖其他镜像或配置比如它可能在启动时要拉一个 sidecar 镜像、日志采集镜像。docker pull只拉你指定的镜像不会自动把所有相关镜像都拉回来。所以你需要先看 LiteIO 的编排文件docker-compose.yml把里面出现的所有image:字段列出来逐个拉取。我这次部署的 LiteIO 编排文件里有三个镜像网关主服务、一个 Redis 缓存、一个日志采集代理。其中日志采集代理是阿里云仓库的Redis 是官方镜像。如果只拉了主服务到内网才意识到缺这两个那就麻烦了。另外检查一下镜像的架构。现在不少新服务器是 ARM 架构而很多镜像默认为 x86_64。拉镜像时用--platform linux/amd64或--platform linux/arm64显式指定架构或者到内网机器上先确认uname -m再回来拉对应架构的镜像。CPU 架构不匹配镜像能 load 进去但根本跑不起来报错往往让人摸不着头脑。拉取完成后用docker save把镜像打包成 tar 文件docker save -o liteio-gateway-2.4.1.tar registry.example.com/liteio/gateway:2.4.1 docker save -o redis-7.2.tar redis:7.2 docker save -o filebeat-8.11.tar docker.elastic.co/beats/filebeat:8.11.3这里用-o指定输出文件。每个镜像单独打包方便后面按需导入。如果所有的镜像塞进一个大 tar万一内网导入时某个镜像损坏整个包都得重来。单独打四个包哪个坏了补哪个。计算一下物料包体积。这个不能拍脑袋因为搬运方式决定体积上限。如果走U盘8GB、16GB 的容量一般够用如果走内网传输工具要考虑服务器的磁盘空间。我这次的 LiteIO 主镜像 800MBRedis 150MBfilebeat 300MB加起来约 1.3GBtar 文件再加一点。但要注意Docker 镜像在 save 成 tar 之后大小和镜像实际占用的磁盘空间可能不同。镜像内部有层layer的概念多个镜像可能共享基础层但 save 成独立 tar 时每层会被重复保存。所以我一般会建立一个清单文件把镜像名、版本、大小全部记录好方便到了内网核对。2.2 编排文件与配置文件的收集镜像只是食材菜谱是编排文件和配置文件。打包的时候以下文件一个都不能少docker-compose.yml或docker-compose.yaml定义了服务怎么启动、端口怎么映射、卷怎么挂载。.env文件compose 文件里通常会有${VAR}这样的变量替换比如端口号、镜像 tag、日志级别、数据库密码。这些变量的值就放在.env里离线环境必须一併携带。忘了带 .env到内网启动时 compose 会报变量未设置并拒绝启动或者用默认值启动而默认值往往不对。挂载目录里的初始配置比如 LiteIO 的config/、data/、logs/目录。首次部署时这些目录里可能有默认配置或初始化数据甚至可能有初始化 SQL 脚本。把整个目录结构原样打包进去是最稳妥的。配置文件里的隐藏依赖也要提前处理。LiteIO 这类网关组件配置里经常要对接外部的数据库、消息队列或认证服务。在线环境部署时配置可以写到一半然后到内网调但离线环境里内网往往没有你要对接的那套服务所以还要顺便准备依赖服务的部署材料。比如我的场景里LiteIO 要对接一套内网已有的 MySQL那就不用管但如果它要对接 Kafka 而内网没有 Kafka你就得把 Kafka 的离线部署包也准备好。这里建议在准备阶段就把整个调用链画一遍LiteIO 启动时需要什么、运行时会连什么、这些下游服务内网有没有。没有的一并解决。一份完整的准备清单应该是镜像 tar、compose 文件、.env 文件、配置目录、依赖服务的部署包、系统级依赖如 JDK、Python如果需要的话。2.3 系统级依赖与基础软件的准备LiteIO 如果是 jar 包形式运行需要 JRE 8 或 11如果是 Python 写的需要 Python 3.8如果是编译型语言一般不需要额外运行时。但这些运行时内网不一定预装。准备方法对于 Java直接下载对应版本的 JRE 或 JDK 的 tar.gz 包例如从 Adoptium 或 OpenJDK 网站不用安装包解压就能用。对于 Python尽量用 pip 把依赖打成离线包。命令是pip download -r requirements.txt -d ./python-packages这会下载所有依赖的 wheel 文件和源码包如果 wheel 不存在。到内网后用pip install --no-index --find-links./python-packages -r requirements.txt安装。对于 Docker 环境本身Debian/Ubuntu 上可以用apt-get download下载 docker-ce 及其依赖数量非常多手动下很痛苦CentOS/RHEL 上用yumdownloader --resolve把依赖一链拉齐。更省事的方式是拿一个同架构的现成机器把 Docker 的二进制文件直接拷贝过去新版 Docker 是静态编译的不需要一堆动态库依赖直接扔到/usr/local/bin/就能跑配合 systemd 服务文件注册成服务即可。这个技巧我用了很多次一劳永逸。这里不厌其烦地强调准备阶段的完备性是因为离线部署最大的成本是往返成本。外网机器和内网机器物理隔离漏了一样东西就得重新走一遍流程时间损耗极高。宁可多带不可少带。3. 内网导入与装配镜像进去不等于服务能跑一切以编排文件为准物料包通过U盘或内网传输工具拷贝到目标机器后开始装配。这一步的顺序和细节直接决定后面是顺滑还是踩坑。3.1 目录归类与环境预检我习惯在目标机器上建一个统一目录比如/opt/liteio-offline/下面分出images/、config/、compose/、deps/四个子目录把物料分门别类放好。然后做环境预检uname -m # 确认架构 cat /etc/os-release # 确认系统版本 docker version # 确认 docker 客户端/服务端版本 docker compose version # 确认 compose 插件版本 free -h # 内存 df -h /opt # 磁盘空间预检的意义在于提前发现问题而不是等服务启动到一半才报错。比如docker compose这个插件有的机器上只有docker-compose旧版独立二进制两者命令语法基本一致但新版 compose 文件里的某些字段如deploy.resources、healthcheck的某些写法旧版不支持。看一眼版本心里有数后面写命令时用对版本。内存方面LiteIO 网关如果配置了较大的 JVM 堆比如 4GB而机器只有 4GB 内存那启动大概率 OOM。内存不足时要么减小 JVM 配置要么加 swap但这个要在启动前判断不能到内网才看着 OOM 日志发呆。3.2 镜像导入与 tag 核对导入镜像很简单docker load -i images/liteio-gateway-2.4.1.tar docker load -i images/redis-7.2.tar docker load -i images/filebeat-8.11.tarload 成功后会输出一行Loaded image: registry.example.com/liteio/gateway:2.4.1。这里要核对一件事镜像的完整名称和 tag 必须与 compose 文件里的image:字段完全一致。不一致时docker compose up会认为本地没有该镜像然后尝试去网络拉取而内网没有网络于是直接报错。出现pull access denied或failed to resolve这类错误时八成不是网络问题而是 tag 对不上。对不上的处理方式有两种一是用docker tag重新打标签二是修改 compose 文件里的镜像名。我更推荐前者因为 compose 文件是参考配置最好保持在原始状态。比如我这次导入后发现 registry 地址比 compose 文件多了一个端口段registry.example.com:8443vsregistry.example.com我用一行命令修正docker tag registry.example.com:8443/liteio/gateway:2.4.1 registry.example.com/liteio/gateway:2.4.1另外补充一下非容器形态的装配区别。如果是发行包zip/tar.gz解压到指定目录然后设置环境变量。环境变量的设置要写进/etc/profile.d/下否则重启后失效。如果是 rpm/deb 包离线安装用dpkg -i或rpm -ivh但它们会检查依赖缺依赖时用apt/yum的离线源解决这个环节比较繁琐我一般尽量避免这种交付形态。3.3 配置文件按现场环境调整镜像导入完配置还不能直接用有几个变量要按当前内网的实际情况改。一是端口。LiteIO 的默认监听端口是 8080但目标机器上很可能已经有别的服务占用了。用ss -lnp | grep 8080检查端口占用情况被占用就要修改 compose 文件里的端口映射格式是宿主机端口:容器内端口改冒号左边的。二是时区。容器默认时区是 UTC会导致日志时间和业务时间对不上。在 compose 文件的环境变量里加TZAsia/Shanghai并且挂载/etc/localtime:/etc/localtime:ro。如果你管理的是一批国内内网节点这个必改否则后面查日志怀疑人生。三是数据目录权限。LiteIO 容器通常以非 root 用户运行而挂载的宿主机目录权限默认是 root:root。容器内用户 ID 是 1000 或者别的值目录权限不对会导致Permission denied服务无法写入日志或数据。排查方法是看容器日志里的报错如果出现 Permission denied 或 cannot create directory处理方式chown -R 1000:1000 /opt/liteio/data chown -R 1000:1000 /opt/liteio/logs具体 UID 要看镜像里的用户定义docker exec进容器用id命令确认即可。这种事前配置阶段就处理好比启动后再看日志找问题快得多。四是.env文件里的密码和 token。客户现场的数据库密码、redis 密码、license 文件路径都需要在.env里调整为真实值。我可以提前写好一个.env.example把所有需要填的变量留空到现场逐个填避免漏项。3.4 系统服务的配置如果需要有些情况下LiteIO 需要注册成系统服务systemd比如要求开机自启、服务崩溃后自动拉起。容器形态推荐用 Docker 自带的restart: always策略在 compose 文件里配好即可。如果是发行包形式写一个 systemd service 文件[Unit] DescriptionLiteIO Gateway Service Afternetwork.target [Service] Typesimple Userliteio ExecStart/opt/liteio/bin/liteio --config /opt/liteio/config/liteio.yml Restartalways RestartSec5 [Install] WantedBymulti-user.target注意Userre}^...不能用 root 跑服务创建一个专用系统用户更安全。这块属于初装时的加分项但对后续运维影响很大建议一次配好。4. 启动时机与验证逻辑不是 docker compose up 完事儿就结束了很多人在离线部署时有个误区镜像 load 进去了compose up 起来了看到容器状态是 Up 就觉得大功告成。实际上容器在跑和服务可用之间隔着一整条验证链路。容器起来了可能内部进程已经崩溃可能端口没监听可能连不上数据库在无限重试。所以启动之后的验证环节才是真正花时间的部分。4.1 启动的顺序先依赖后主服务在 compose 文件里服务之间往往有依赖关系。LiteIO 依赖 RedisRedis 和日志代理之间可能没有依赖。启动顺序不对LiteIO 会因为连不上 Redis 而反复重启。Compose 的depends_on字段可以声明依赖关系但它只保证依赖服务启动起来不保证可用。保险的做法是手动分步启动先起 Redisdocker compose up -d redis观察 Redis 日志确认 ready日志里会出现 Ready to accept connections。等几十秒确认 Redis 稳定了再启动 LiteIOdocker compose up -d第二步不带服务名表示启动编排文件里剩下的服务。如果你的编排文件里没写depends_on尤其要手动控制顺序。4.2 三层验证法进程层、端口层、业务层我验证服务健康状态从不只看docker ps。那只是最低标准我把它拆成三层逐层确认。第一层进程与日志层。docker ps看状态然后docker logs --tail 200 容器ID看日志。LiteIO 启动成功的日志通常会出现Server started或Application startup complete之类的标志性语句。如果日志停留在某个初始化阶段报错先解决报错再继续。第二层端口与连通层。确认容器内进程在正常监听端口docker exec 容器ID ss -lnp | grep 8080同时在宿主机上验证端口映射curl -v http://localhost:8080/health如果 curl 返回 HTTP 200 或预期状态码说明端口链路是通的。如果connection refused检查映射关系docker port 容器ID可查看端口映射如果是 no route to host检查防火墙规则。内网机器防火墙策略各不相同有的默认放行有的全部阻断。ping和telnet排除网络路径问题时直接用 curl 看 HTTP 层响应最直接。第三层业务层验证。LiteIO 是网关正常是转发业务的所以找一个真实的业务请求打过去确认它能正确转发到后端服务。如果没有现成的业务流量可以对着它配置里的路由规则手工发一个测试请求。如果请求走通了说明配置文件里的路由、负载均衡、限流规则都被正确加载了而不是服务起来了但配置没生效。这里我特别提醒一点千万不要跳过第三层验证。我遇到过容器 Up、端口通、健康检查 200但实际业务转发全部报 502 的情况。原因是配置里后端服务地址写的是开发环境域名内网解析不了主服务看着正常一转发就挂。这层验证到位了才能算部署完成。5. 离线部署的故障特征与排查链路几个能跑但不对的经典场景离线部署和在线部署排错最大的不同是在线环境报错了可以随手apt install或pip install解决依赖离线环境报错报什么错就是缺什么解决手段十分有限。所以排查时要格外有耐心地沿着证据链一步步走不能瞎猜。5.1 场景一容器一直 Restarting日志却看不到关键信息这是我最常遇到的第一类问题。docker compose up -d之后docker ps看到 LiteIO 容器状态是Restarting但docker logs只看到几行输出没有明显异常。这种静默重启常见于两类原因一类是启动脚本里检查外部依赖失败比如连不上数据库进程主动退出另一类是 Java 应用 OOMJVM 直接被杀日志来不及输出。排查时先看退出码docker inspect 容器ID --format {{.State.ExitCode}}ExitCode 137 通常是 OOM被 kill101 或 1 通常是应用主动退出。137 的话查dmesg | grep -i kill有没有 oom-killer 记录有就调整 JVM 内存配置或宿主机内存分配。主动退出的话多半是依赖问题这时候看容器启动时间如果每 30 秒重启一次说明某种重试机制还没放弃如果重启间隔很短可能是配置校验直接失败。无论哪种都要耐心看完整日志。很多人只看--tail 50信息量不够。离线环境里日志是全量输出的直接从最早一行看。重置容器日志再复现一次启动过程往往能发现被刷屏漏掉的关键报错docker logs --since 5m 容器ID5.2 场景二健康检查接口通了但业务全部超时健康检查正常不代表业务正常。LiteIO 这类网关一般有自己的健康检查端点但这个端点可能只报告进程状态不报告下游依赖状态。所以健康检查 200 但业务超时基本锁定在下游依赖问题上。按这条链路排查先看 LiteIO 日志里转发失败的报错常见的是connection refused下游服务没起、host not foundDNS 解析失败、connection timed out网络不通或防火墙丢弃。然后到 LiteIO 所在机器上直接测试它要连的下游服务telnet 下游服务IP 端口 或 curl -v http://下游服务IP:端口/内网环境最常见的坑是LiteIO 配置的是域名但内网 DNS 没有对应记录。网络是通的但解析不了域名。处理方式是在/etc/hosts里手动加一条记录让域名临时解析到内网实际 IP。这一步在在线环境很少需要做离线环境却是高频操作提前知道能省很多时间。5.3 场景三镜像导入成功但启动报OCI runtime create failed这个报错要看的是后面括号里的详细原因。常见的有几种permission denied挂载目录权限问题按前文改chown即可。no such file or directorycompose 文件里挂载了一个不存在的宿主机目录。Docker 有时会自动创建目录但有时不创建。检查配置里的volumes:字段宿主机目录提前mkdir -p。exec format error架构不匹配。镜像拉的是 amd64机器是 arm64。只能回到联网机器重新拉对应架构的镜像没有别的招。这就是我之前强调准备阶段查架构的原因。5.4 场景四compose 文件变量未替换docker compose up时如果报env file not found或者Invalid interpolation format首先要看.env文件是不是和 compose 文件在同一个目录。Compose 自动读取当前目录下的.env但不读取子目录的。如果.env文件在别处需要在 compose 文件里用env_file:字段显式指定路径或者在启动命令里加上docker compose --env-file /opt/liteio/.env up -d另外compose 文件里有${VAR:-default}这种带默认值的语法如果漏了.env服务会用默认值启动而默认值往往是错误的端口或密码。所以启动前最好先 dry-run 看实际生效的配置docker compose config这个命令会把渲染后的完整 compose 配置打印出来所有变量替换结果一目了然。我习惯在每次up之前跑一遍这个命令比直接启动后翻日志高效得多。5.5 场景五服务启动后日志有中文乱码或时区不对LiteIO 如果内部是 Java 或 Go 应用默认字符集可能依赖系统 locale。内网机器如果没装中文字符集比如zh_CN.UTF-8日志里的中文信息会变成???或乱码。在发起启动命令时加上环境变量export LANGzh_CN.UTF-8 export LC_ALLzh_CN.UTF-8或者更稳妥地在容器环境变量里配置LANGC.UTF-8LiteIO 的日志框架一般都能识别 UTF-8。时区问题前面提过TZAsia/Shanghai必加。这种东西不排查能折磨人一整天但解决方法就一行配置。6. 离线环境的规模化思考一台装通之后如何复制到一批节点如果一次只部署一台前面的章节足够覆盖。但实际项目里离线部署往往意味着第一批节点装通后同样的包要在一批相同配置的机器上重复部署。这时候有两条路可选取决于你的现场情况和时间预算。6.1 镜像仓库方案离线环境里的软件源当机器数量超过五台一台台docker load就太低效了而且容易出错。更专业的做法是在内网搭一个私有镜像仓库Harbor 或 Registry。在一台机器上启动 Registry 容器把离线带进来的镜像 push 进去其他机器配置/etc/docker/daemon.json里的insecure-registries指向这台仓库然后像在线环境一样docker pull。这个方案的好处是后续版本升级只需要把新镜像 push 到仓库所有节点统一拉取。坏处是需要在一开始就把仓库搭起来并且要注意磁盘空间和并发拉取时网络带宽。我做的大规模项目里三台以内就走docker load超过五台就上私有仓库。有一个细节离线环境没有公网 CA必须将仓库地址加入每个 Docker 客户端的insecure-registries否则docker login和pull会报 x509 证书错误。这是离线仓库最经典的坑。6.2 数据与配置的标准化让每台机器的部署结果一致水平复制部署最大的风险是第一台手工调完配置能跑但第二台换个 IP 和密码就漏改了一个变量。我建议维护一套标准化的下发清单每次部署逐项核对机器 hostname 是否符合命名规范。docker compose config渲染结果是否和上一台一致除了必要的 IP 和密码差异。.env文件是否做了差异化管理避免把上一台的密码带到这一台。防火墙规则里是否放行了 LiteIO 的端口。时钟是否同步。内网没有 NTP 服务时各机器时间可能偏差很大。网关组件在生成 token 或做证书校验时对时间敏感时间偏差会造成业务异常。我经历过一次容器正常、配置正常、网络正常但 HTTP 请求返回 401最后发现是两台机器时间差了七八分钟token 校验直接失败。务必确保每台内网机器有时间同步机制哪怕手动date -s校准也要在部署清单里写上。6.3 升级与回滚预案离线环境升级比在线环境更讲究因为没法在线回滚。我通常保留前一个版本的镜像 tar 文件和配置快照放在/opt/liteio/backup/。升级时先docker load新镜像再用新 compose 文件启动如果验证不通过立刻用旧镜像和旧配置回滚。这听起来是常识但真到现场很多人急着上线新版本没有备份旧配置一旦要回滚就只能从记忆里手写配置或者再跨网传输一次旧包——想想就崩溃。备份这一步一分钟的事能省一天的事。另外升级前看一下 LiteIO 的版本发布说明确认有没有破坏性变更比如配置字段改名、数据库结构变化。离线环境没法直接访问官方文档所以准备阶段最好把对应版本的文档一并下载下来放在 config 目录里。内网查不到资料的时候本地文档就是唯一的救命稻草。7. 离线部署的时间估算与常见误区总结结合我历次离线部署的经验做一次总结。单台 LiteIO 离线部署如果物料齐全、系统干净熟练的情况下两到三个小时能完成包含验证。如果准备阶段不充分或者走了源码编译路线时间往往成倍增长。时间主要耗在哪里我可以拆给大家看物料准备阶段如果缺包往返传输一次少说四五个小时配置阶段如果没做变量核对启动后调试日志可能耗掉一晚上验证阶段如果跳过业务层测试后面交到运维手里出问题返工时间更不可控。误区一以为离线部署只是没有网络而已。实际上离线意味着所有的错误处理和诊断手段也被离线了。在线环境报错可以搜索、可以装工具、可以查文档离线环境报错你只能靠本地日志、本地文档、本地积累。所以离线部署真正考验的是准备阶段的系统性思维。误区二拿在线部署的配置直接套离线环境。在线部署时很多配置可以保持默认值或让应用自动探测离线部署时所有探测手段都不好使必须显式配置一切后端地址、DNS、时区、字符集、时钟源。我的经验是把显式配置作为离线部署的基本原则凡是可能被隐式推断的配置一律写死。误区三忽略验证环节。我见过不少部署容器起来了就算完成结果当天夜里业务方调用才发现问题。验证不是走过场验证是部署流程的一部分。建议给自己定个铁律进程层、端口层、业务层三层验证全部通过才算部署完成。最后分享一个我自己的习惯每次离线部署完成我会把准备清单、实际修改过的配置、踩过的坑写到一个部署记录文件里留在目标机器的/opt/liteio/目录下。下一次升级或部署相似环境时这份记录能省掉大半重复排查时间。离线环境里知识管理和物料管理一样重要。
返回列表