本节摘要:集合是内容的分发单元:一个命名空间下打包模块、角色、插件与文档,用依赖清单声明与锁定版本。本节讲清集合与角色是替代还是互补、fully qualified name 的由来、requirements 文件的写法,以及企业内部的私有分发路线。
2020 年前的 Ansible 把几千个模块与引擎捆绑在同一个包里,随之而来的问题用一个真实场景就能讲清:某团队因业务需要升级引擎版本,升级后发现一个云模块的行为变了——引擎与几千个互不相干的内容单元捆绑发行,任何一侧的变更都被迫捆绑在一起交付。2020 年的架构重组正是针对这个矛盾:引擎瘦身成 ansible-core,原有内容拆分成独立版本、独立发行的集合(Collections),引擎与内容各自按自己的节奏演进。
对使用者的直接改变是全限定名(Fully Qualified Collection Name):所有模块调用必须带命名空间,ansible.builtin.yum、community.general.ufw、amazon.aws.ec2_instance。初见觉得啰嗦,但它解决了一个长期隐患——同名模块在不同来源间的歧义。全限定名让"这个模块从哪来、装了哪个版本"变成可精确回答的问题。
集合与角色不是替代关系。角色是代码组织单元(4.1 节),集合是内容分发单元,一个集合的典型内容结构:
collections/ansible_collections/acme/stardust/ ├── galaxy.yml # 集合清单:命名空间、版本、依赖 ├── plugins/ │ ├── modules/ # 自研模块 │ ├── filter/ # 过滤插件(3.5 节的自定义过滤器可发布于此) │ └── lookup/ ├── roles/ # 集合内角色(4.1 节的成果可装入) │ └── app_runtime/ └── playbooks/ # 集合自带的剧本
galaxy.yml 是集合的身份证:
namespace: acme name: stardust version: 1.4.0 readme: README.md authors: - 星尘运维组 dependencies: community.general: ">=6.0.0" ansible.posix: ">=1.4.0"
dependencies 声明对其他集合的版本约束,安装本集合时自动解析。
新成员入职、CI 环境构建,都需要"一键装齐全部依赖"。requirements.yml 承担这个职责:
--- collections: - name: community.general version: ">=6.0.0,<8.0.0" # 版本区间约束 - name: amazon.aws version: 6.0.0 # 精确锁定 - name: git+内部仓库地址/acme-stardust.git version: main # 从内部仓库安装 roles: - name: geerlingguy.nginx # 集合体系仍兼容直接安装角色 version: 3.4.0
安装与核查命令:
ansible-galaxy collection install -r requirements.yml -p ./collections ansible-galaxy collection list # 已装集合与版本 ansible-galaxy collection verify community.general # 校验完整性
工程纪律有两条。其一,requirements.yml 必须提交进仓库且版本尽量锁定——"floating 版本"(只写 name 不写 version)会让两次构建拿到不同内容,等价于部署抽盲盒。其二,执行环境的集合版本与开发环境保持同步,现代做法是用执行环境(容器化运行时)把"引擎版本加集合版本"整体打包,第 5.1 节展开。
集合是独立版本演进的,升级就会有行为变化。三条守则把风险控住。守则一,小步走:requirements 里的版本约束按"当前版本加一个次版本"升级,跑完全部测试再进下一步,禁止从三年前的版本直接跳最新。守则二,读变更说明:主流集合的每个版本附弃用清单,弃用告警(deprecation warning)会在执行输出里出现——看到告警就排期处理,不要等到硬报错。守则三,灰度:先在 staging 环境完成整套升级验证,生产环境锁定已验证的版本号。
存量资产迁移的推荐路径:第一步,把现有角色仓库原样装进一个内部集合的 roles 目录(目录结构完全兼容,改动几乎为零);第二步,galaxy.yml 声明依赖,原散装的 requirements 合并进来;第三步,发布到内部索引或直接以 git 源分发。迁移过程中旧的调用方式(roles: nginx)对集合内角色同样可用,无需一次性改完全部剧本——这个兼容性让迁移可以按角色逐个推进。

企业内部内容(角色、自研模块)的常见分发路线:轻量路线,git 仓库直装——requirements 里写内部仓库地址,团队已有 git 权限体系即可用;正规路线,搭建私有集合索引服务(社区有开源实现),获得版本管理、检索与下载统计。选择的分界是团队规模与合规要求:少于三个消费团队用 git 路线足够,跨部门分发且需审计的走索引服务。
引擎与集合解耦后的版本矩阵(引擎版本乘以各集合版本)是团队沟通的高频摩擦点,一份标准化的环境描述模板能消掉大部分摩擦。模板四行:引擎版本(core 的精确版本);集合清单(名称与锁定版本,直接贴 requirements 的解析结果);执行环境镜像(若已容器化,贴镜像摘要);已知例外(某集合在某引擎上的临时规避)。新人入职、跨团队求助、缺陷上报,开头贴这份模板,沟通成本立降——"我这里不行"与"我这里 2.16 加 6.0.1 不行"是两种完全不同的求助。更进一步,把模板生成做成一条命令(清单解析加版本汇总的脚本),模板不再依赖手工维护。版本矩阵管理的本质是让环境描述变得廉价且准确——描述环境的成本降下来,环境问题的排查才会勤起来。