- 数据库
- 运维
- 云原生
- 高可用
- 监控
【免费下载链接】pigsty
Enterprise-Grade OSS PostgreSQL Distribution with HA, PITR, IaC, Monitor, 12 kernel forks and 575 PG extensions. Best-of-breed products integrated as a platform. Self-host Postgres like a Pro!
导读
本文围绕 Pigsty 的cache角色,系统讲解如何从一个已就绪的本地软件仓库一键生成"离线安装包"(.tgz压缩包),并将其分发到无外网的隔离环境完成整套 Pigsty 部署。读完本文,你将掌握cache.yml的完整用法、缓存包命名规则、脏包清理策略、YUM/APT 元数据重建原理,以及基于bootstrap -p的标准离线交付工作流。
一、角色定位:从本地仓库到离线分发包
cache是 Pigsty 基础设施(INFRA)模块中的一个专用角色,核心职责是把目标节点上已有的本地软件仓库打包成一个可迁移的离线 tarball。与repo角色(负责构建/填充本地仓库)和infra角色(负责整体基础设施部署)配合使用,二者关系在 cache.yml 与角色定义中均有体现。
从 roles/cache/tasks/main.yml 的源码结构看,整个角色由五个顺序阶段组成:
cache_id:计算输出文件名与目标目录(基于版本、OS、架构占位符);cache_check:校验仓库目录存在且非空;cache_create:清理多余/冲突软件包并重建 YUM/APT 元数据;cache_tgz:在目标节点上压缩生成/tmp/pkg.tgz;cache_fetch:用rsync将 tarball 拉回控制节点。
这一流程带来的实际收益非常明确:
- 离线安装(Offline Installation):无外网也能完成整套 Pigsty 部署;
- 隔离网络(Air-Gapped):适用于内网、军工/金融等安全隔离环境;
- 更快部署:新机器安装时跳过大量软件包下载;
- 版本一致性:所有部署节点使用完全相同的软件包集合,杜绝版本漂移。
二、前置条件
运行 cache 角色前,需确认以下前提(详见 roles/cache/README.md):
- Pigsty 必须已经安装在目标节点(infra 节点)上;
- 本地仓库已存在于
{{ repo_home }}/{{ repo_name }}(默认/www/pigsty); - 控制节点与目标节点均需安装
rsync(因为cache_fetch阶段使用 Ansiblesynchronize模块); - 仓库应包含所需全部软件包(建议先运行
./infra.yml -t repo完成仓库构建)。
其中repo_complete标记文件是仓库就绪与否的关键证据:repo角色在构建完成后会生成md5sum *.rpm > repo_complete(见 roles/repo/tasks/build.yml 第 231/238 行),而bootstrap脚本的check_repo函数也以/www/pigsty/repo_complete是否存在来判断仓库是否可直接复用(见 bootstrap 第 336-340 行)。
三、Playbook 与三种调用方式
cache角色的执行入口是顶层 playbook cache.yml,它由三个 play 组成:
| Play | 作用 | Tag |
|---|---|---|
| CREATE LOCAL DIST DIR | 在控制节点(localhost)创建dist/<version>目录 | cache_dir |
| MAKE OFFLINE PACKAGE | 在目标节点执行node_id(探测系统身份)+cache角色 | id/cache |
| SHOW CACHE TARBALL INFO | 计算 md5 校验和并展示文件大小 | cache_info |
基本用法:
# 从 infra 节点组制作离线包 ./cache.yml -l infra # 从指定节点制作离线包 ./cache.yml -l 10.10.10.10 # 使用 Makefile 快捷目标(若环境中已定义,等价于执行 ./cache.yml) make cache四、文件结构与源码级实现
角色的目录结构非常精简,只有 4 个文件:
roles/cache/ ├── defaults/ │ └── main.yml # 默认变量 ├── meta/ │ └── main.yml # 角色元数据与依赖声明 ├── tasks/ │ └── main.yml # 缓存制作核心逻辑 └── README.md # 本文档meta/main.yml声明了角色的最小 Ansible 版本为 2.9,支持 EL / Ubuntu / Debian 全系列平台。
4.1 阶段一:文件名计算(cache_id)
任务以set_fact完成三个关键变量的推导(roles/cache/tasks/main.yml 第 9-15 行):
- name: calculate offline package names tags: [ always , cache_id ] become: false set_fact: cache_filename: "{{ cache_pkg_name|replace('${version}', version)|replace('${os}', node_os_code)|replace('${arch}', os_arch) }}" cache_dirname: "{{ cache_pkg_dir | replace('${version}', version) }}" cache_repo_list: "{{ cache_repo.split(',') }}"这里的node_os_code与os_arch并非 cache 角色自行探测,而是由前置的node_id角色注入。从 roles/node_id/tasks/main.yml 第 52、71 行可以看到其推导逻辑:
os_arch:直接来自节点探测结果(如x86_64、aarch64);node_os_code:RPM 系输出el{{ os_version }}(如el7、el8、el9、el10),DEB 系输出{{ os_vendor[0] }}{{ os_version }}(如 Ubuntu 22.04 →u22、Debian 12 →d12),并提供node_os_code_fb回退(el10/u24/d12)以兼容未知系统。
4.2 阶段二:仓库校验(cache_check)
- name: check repo dirs exists & not empty tags: cache_check find: paths: "{{ repo_home }}/{{ item }}" file_type: any register: dir_contents failed_when: dir_contents.matched == 0 loop: "{{ cache_repo_list }}"对cache_repo_list中的每个仓库,在{{ repo_home }}下查找任意类型文件;一旦某个目录为空或不存在(matched == 0),任务即失败——宁可报错,绝不产出空壳缓存包。
4.3 阶段三:脏包清理与元数据重建(cache_create)
这是整个角色技术含量最高的部分(roles/cache/tasks/main.yml 第 56-87 行)。任务内部按包管理类型分支执行shell脚本:
RPM 系(EL)分支:
cd "{{ repo_home }}/{{ repo_name }}"; rm -f *.i686.rpm; # EL7:移除 multilib 仓库带入的 32 位包 rm -rf proj-data*; # EL9+:移除可选的大体积地理空间数据(约 500MB+) rm -rf patroni*3.0.4*; # 移除与新版 Patroni 冲突的旧版本 rm -rf *docs*; # 移除文档包以减小体积 createrepo_c {{ repo_home }}/{{ repo_name }} repo2module -s stable . modules.yaml; # 仅 EL8/9 modifyrepo_c --mdtype=modules modules.yaml repodata/; # 仅 EL8/9 md5sum *.rpm > {{ repo_home }}/{{ repo_name }}/repo_complete || /bin/trueDEB 系(Ubuntu/Debian)分支:
cd {{ repo_home }}/{{ repo_name }}; rm -f *i386.deb; # 移除 32 位包 rm -rf Packages.gz; dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz md5sum *.deb > {{ repo_home }}/{{ repo_name }}/repo_complete || /bin/true几个值得注意的实现细节:
- 包清理发生在元数据重建之前,确保
repodata/与Packages.gz只描述保留后的干净集合; - 清理规则按
os_version条件式生效(EL7 才删 i686、EL9+ 才删 proj-data),避免误伤其他平台; - 所有分支最后都会重建
repo_complete标记文件,这与repo角色、bootstrap的判断逻辑保持一致; repo2module依赖 modulemd-tools,EL7(使用 yum)、EL10+(modulemd-tools 不可用)以及 Debian/Ubuntu(APT 体系)都不会执行 DNF 模块元数据生成。
4.4 阶段四:压缩打包(cache_tgz)
tar cvf - -C "{{ repo_home }}" {% for item in cache_repo_list %}{{ item }} {% endfor %} | gzip -9 > /tmp/pkg.tgz chmod a+r /tmp/pkg.tgz;要点解读:
- 使用
gzip -9最高压缩等级换取最小体积,这对大仓库分发尤其关键; - tarball 先落在目标节点的
/tmp/pkg.tgz,作为传输中间产物; chmod a+r确保后续synchronize以普通用户拉取时具有可读权限(cache_fetch阶段become: false)。
4.5 阶段五:回传控制节点(cache_fetch)
- name: fetch cache tarball from target node tags: cache_fetch become: false synchronize: src: /tmp/pkg.tgz dest: "{{ cache_dirname }}/{{ cache_filename }}" mode: pull compress: nomode: pull表示从目标节点拉回控制节点;compress: no是因为 tarball 本身已是 gzip 压缩产物,二次压缩徒增 CPU 消耗。这解释了前置条件中"控制与目标节点都必须安装rsync"的原因。
五、Tag 层级体系
cache角色与cache.ymlplaybook 共同构成了一套细粒度 tag 体系:
cache # 完整角色执行 │ ├── cache_id # 计算输出文件名 ├── cache_check # 校验仓库目录存在且非空 ├── cache_create # 清理脏包并重建元数据 ├── cache_tgz # 创建压缩 tarball ├── cache_fetch # 拉取 tarball 到控制节点外加 playbook 级别的cache_dir(创建本地 dist 目录)、id(探测节点身份)、cache_info(校验和与信息展示)。这意味着你可以只跑某个阶段:比如仅重建元数据而不打包,或跳过元数据直接打包拉取。
六、关键变量与命名规则
6.1 缓存设置(定义于 roles/cache/defaults/main.yml)
| 变量 | 默认值 | 说明 |
|---|---|---|
cache_pkg_name | pigsty-pkg-${version}.${os}.${arch}.tgz | 输出文件名模板 |
cache_pkg_dir | dist/${version} | 控制节点上的输出目录 |
cache_repo | pigsty | 需要打包的仓库名,多个用逗号分隔 |
6.2 引用变量
| 变量 | 默认值 | 说明 |
|---|---|---|
version | v4.5.0 | Pigsty 版本字符串 |
repo_home | /www | 仓库基础目录(软链接) |
repo_name | pigsty | 仓库名称 |
nginx_home | /www | Nginx 内容目录(软链接到/data/nginx) |
node_data | /data | 节点主数据目录 |
6.3 文件名占位符
cache_pkg_name支持三个占位符,由cache_id阶段逐一代换:
| 占位符 | 示例 | 说明 |
|---|---|---|
${version} | v4.5.0 | Pigsty 版本号 |
${os} | el9、u26、d12 | 来自node_id的短 OS 代码 |
${arch} | x86_64、aarch64 | CPU 架构 |
七、输出产物
7.1 产物路径与命名示例
最终 tarball 位于控制节点的dist/<version>/目录下,文件名遵循pigsty-pkg-<version>.<os>.<arch>.tgz模式:
| 平台 | 输出文件名 |
|---|---|
| EL9 x86_64 | dist/v4.5.0/pigsty-pkg-v4.5.0.el9.x86_64.tgz |
| EL8 aarch64 | dist/v4.5.0/pigsty-pkg-v4.5.0.el8.aarch64.tgz |
| Ubuntu 22.04 | dist/v4.5.0/pigsty-pkg-v4.5.0.u22.x86_64.tgz |
| Ubuntu 24.04 | dist/v4.5.0/pigsty-pkg-v4.5.0.u24.x86_64.tgz |
| Ubuntu 26.04 | dist/v4.5.0/pigsty-pkg-v4.5.0.u26.x86_64.tgz |
| Debian 12 | dist/v4.5.0/pigsty-pkg-v4.5.0.d12.x86_64.tgz |
7.2 tarball 内部结构
pigsty/ # repo_name 目录 ├── *.rpm 或 *.deb # 软件包文件 ├── repodata/ # YUM 元数据(仅 RPM) │ ├── repomd.xml │ ├── primary.xml.gz │ └── modules.yaml # DNF 模块元数据(仅 EL8/9) ├── Packages.gz # APT 元数据(仅 DEB) └── repo_complete # MD5 校验和标记文件repo_complete不仅是"仓库已就绪"的标记,其内容就是全部 RPM/DEB 包的 MD5 校验和,可用于传输完整性校验。
八、离线包的两种使用方式
8.1 手动解压
将 tarball 解压到目标节点的repo_home(默认/www,通常软链接到/data/nginx):
tar -xzf pigsty-pkg-v4.5.0.el9.x86_64.tgz -C /www # 验证解压结果 ls -la /www/pigsty/8.2 Bootstrap 自动接入(推荐)
bootstrap脚本原生支持离线包接入(bootstrap 第 22-45 行定义了PKG_PATH=/tmp/pkg.tgz的默认路径约定):
# 通过 -p 指定离线包路径 ./bootstrap -p /path/to/pigsty-pkg-v4.5.0.el9.x86_64.tgz # 或直接将离线包放到 /tmp/pkg.tgz,然后直接运行 ./bootstrapbootstrap 内部(check_repo函数,第 315-366 行)会自动完成:
- 检查
/www软链接与/data/nginx目录就绪; - 若已有
repo_complete标记则直接复用现有仓库; - 校验
/tmp/pkg.tgz是否存在且体积大于 400MB(stat -c%s判断,过小视为无效包并移除); - 将 tarball 解压到
/www/pigsty,配置本地仓库,并安装 Ansible 及依赖。
九、完整离线部署工作流
针对"内网构建机 → 隔离环境"的典型场景,cache.yml 注释中给出了标准五步流程:
# —— 在有外网的构建机上 —— 1. 正常安装 Pigsty: ./bootstrap && ./configure && ./deploy.yml 2. 制作离线包: ./cache.yml -l infra # —— 传输 tarball 到隔离环境(如 scp dist/v4.5.0/*.tgz target:/tmp/)—— # —— 在无外网的目标机器上 —— 3. 离线 bootstrap: ./bootstrap -p pigsty-pkg-*.tgz 4. 配置: ./configure 5. 安装: ./deploy.yml要点:第 1 步必须先完成一次在线安装,因为离线包的内容正是从这次安装生成的本地仓库(/www/pigsty)中打包而来;后续所有新节点都无需再访问外网。
十、常用命令速查
# 从 infra 节点组完整制作离线包 ./cache.yml -l infra # 从指定主机制作 ./cache.yml -l 10.10.10.10 # 仅重建仓库元数据(跳过打包与拉取) ./cache.yml -l infra -t cache_create # 仅打包并拉取(跳过元数据重建) ./cache.yml -l infra -t cache_tgz,cache_fetch # 仅展示缓存信息(md5 与文件大小) ./cache.yml -l infra -t cache_info # 指定自定义版本 ./cache.yml -l infra -e version=v4.5.0 # 打包多个仓库(逗号分隔) ./cache.yml -l infra -e cache_repo=pigsty,minio十一、与其他角色的协作关系
- repo 角色:构建并填充本地仓库,是 cache 的前置依赖(必须先
./infra.yml -t repo); - infra 角色:整体基础设施部署,cache 产物服务于其离线安装场景;
- node_id 角色:为 cache 提供
node_os_code、os_arch等身份变量,是文件名推导的基础。
从实现角度看,cache 角色的巧妙之处在于"就地精简 + 全量打包":它不是在构建机上从零拉取软件包,而是复用已部署节点上的现成仓库,先删掉冗余与冲突的包、重建元数据,再压缩成单一 tarball。配合bootstrap -p的解压即用机制,一条龙打通了"在线构建 → 离线分发 → 隔离部署"的完整链路,是 Pigsty 在无外网、高安全等级环境落地部署的关键基础设施能力。
- 数据库
- 运维
- 云原生
- 高可用
- 监控
【免费下载链接】pigsty
Enterprise-Grade OSS PostgreSQL Distribution with HA, PITR, IaC, Monitor, 12 kernel forks and 575 PG extensions. Best-of-breed products integrated as a platform. Self-host Postgres like a Pro!
相关推荐
终极指南:RedditVideoMakerBot离线安装包制作全流程
终极指南:RedditVideoMakerBot离线安装包制作全流程 痛点直击:无网络环境下的部署困境 你是否遇到过在隔离网络环境中部署RedditVideoM
音视频工作流自动化如何快速掌握STM32 Arduino开发:从零开始到项目实战的完整指南
如何快速掌握STM32 Arduino开发:从零开始到项目实战的完整指南 想要在嵌入式开发中既享受STM32的强大性能,又体验Arduino的易用性吗?STM3
嵌入式固件驱动开发硬件开发macOS离线安装包制作:gibMacOS+BuildmacOSInstallApp教程
macOS离线安装包制作:gibMacOS+BuildmacOSInstallApp教程 痛点直击:告别App Store依赖,5步自制macOS安装包 你是否
开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考