cloudlab-ansible

用 Ansible 把 CloudLab 自托管服务平台声明式、可重复、跨环境地批量部署到任意主机。
从「手工敲 docker-compose」升级为「一条命令拉起整套服务」,覆盖系统基线、容器运行时、业务服务与监控体系。

技术栈

Ansible · Docker · Docker Compose · Nginx Proxy Manager · Vaultwarden · Halo · Prometheus · Node Exporter · Grafana(可选,D2 决策)


一、架构概览

                       浏览器 / Internet
                             │
                  ┌──────────────────────┐
                  │  NPM 网关 :80/443/81 │  反向代理 · SSL 证书 · 子域名分流
                  └──────────────────────┘
                             │  cloudlab-net(外部 Docker 网桥)
                ┌────────────┴────────────┐
          Vaultwarden                   Halo
          :8080                         :8090
                             │
              ┌──────────────┼────────────────┐
        Node Exporter   Prometheus      (Grafana :3000 可选)
        :9100 采集       :9090 pull 拉取

服务

Ansible 角色

镜像

主机端口

分组

说明

NPM 网关

npm

jc21/nginx-proxy-manager

80 / 443 / 81

webservers

统一入口、反代、HTTPS

Vaultwarden

vaultwarden

vaultwarden/server

8080

webservers

密码管理

Halo

halo

halohub/halo:2.27

8090

webservers

博客(JVM 内存受限)

Node Exporter

node-exporter

prom/node-exporter

9100

monitoring(现状;待按 docs/execution-plan.md §3.8 移至 all)

主机指标采集

Prometheus

monitoring-prometheus

prom/prometheus

9090

monitoring

指标拉取与时序存储

Grafana

monitoring-grafana

grafana/grafana

3000

monitoring(可选,D2 决策,见执行计划 §5.2)

大盘展示(本期可选)

系统基线

common

—

—

all

时区/工具/swap/内核参数/时间同步

容器运行时

docker

—

—

all

安装/加速源/外部网络/日志轮转

已裁剪:Alist(云盘聚合,与运维主线无关)、Uptime Kuma(与多机监控重复);对应角色骨架暂留目录,D0 后从 playbook 移除。


二、目录结构

cloudlab-ansible/
├── ansible.cfg                  # 全局配置(清单路径、SSH、日志、角色路径)
├── requirements.yml             # Collection 依赖清单
├── README.md
├── inventory/
│   ├── dev.ini                  # 开发环境:WSL Docker 模拟节点(练手主战场)
│   ├── staging.ini              # 预发环境:可选第二台节点
│   └── prod.ini                 # 生产环境:真实云服务器
├── group_vars/
│   ├── all.yml                  # 所有环境公共变量(时区/Docker/目录/资源限制)
│   ├── webservers.yml           # Web 服务分组变量
│   ├── monitoring.yml           # 监控分组变量
│   └── vault.yml                # 敏感变量(ansible-vault 加密,禁止明文入库)
├── host_vars/
│   └── prod-01.yml              # 单机覆盖变量
├── playbooks/
│   ├── site.yml                 # 总入口:基线 + Docker + 全部业务 + 监控
│   ├── init.yml                 # 仅系统基线 + Docker
│   ├── deploy-services.yml      # 仅业务服务(假定基线与 Docker 就绪)
│   └── check.yml                # 部署后健康检查(容器状态 + HTTP 探活)
├── roles/
│   ├── common/                      # 系统基线(已实现,参照模板)
│   ├── docker/                      # 容器运行时(已实现,参照模板)
│   ├── npm/                         # 网关(已实现,参照模板)
│   ├── monitoring-prometheus/      # 指标采集(半实现:缺 compose 模板与断言,待补)
│   ├── node-exporter/ halo/ vaultwarden/   # TODO 骨架,待实现
│   ├── monitoring-grafana/                # 可选角色(D2 决策是否保留)
│   └── alist/ uptime-kuma/                # 已裁剪:骨架暂留,D0 后从 playbook 移除
└── docs/
    ├── cloud-service-selection.md   # 多环境云服务器选型调研
    └── execution-plan.md            # 三节点实验 D0–D4 修正版执行计划

三、环境分组与变量分层

三套环境(同一套代码,不同变量)

环境

inventory

用途

节点来源

dev

inventory/dev.ini

日常联调、反复重建、零成本

WSL Docker 模拟节点

staging

inventory/staging.ini

上线前预发验证(可选)

第二台便宜节点

prod

inventory/prod.ini

真实生产

云服务器

变量优先级(由低到高,后者覆盖前者)

role defaults  <  group_vars/all  <  group_vars/<组>  <  host_vars/<主机>
            <  playbook vars  <  命令行 -e 覆盖
  • 公共默认写 role/defaults;跨环境公共项写 group_vars/all;

  • 某组服务特有写 group_vars/<组>;某台主机特有写 host_vars/<主机>;

  • 密码、令牌、域名等敏感信息全部进 group_vars/vault.yml,用 ansible-vault 加密。


四、快速开始

0. 安装 Collection 依赖

ansible-galaxy collection install -r requirements.yml

1. 检查连通性(不做任何变更)

ansible all -i inventory/dev.ini -m ping

2. 加密敏感变量(首次)

ansible-vault encrypt group_vars/vault.yml
# 查看 / 编辑:
ansible-vault view  group_vars/vault.yml
ansible-vault edit group_vars/vault.yml

3. 预演(check mode + diff,只看会改什么,不落地)

ansible-playbook playbooks/site.yml -i inventory/dev.ini --check --diff

4. 全量执行 dev 环境

ansible-playbook playbooks/site.yml -i inventory/dev.ini --ask-vault-pass

5. 部署后健康检查

ansible-playbook playbooks/check.yml -i inventory/dev.ini

五、命令速查

# 只做系统基线初始化
ansible-playbook playbooks/init.yml -i inventory/dev.ini --tags baseline

# 只部署某个服务(tag 与 site.yml 中 role tags 对应)
ansible-playbook playbooks/deploy-services.yml -i inventory/dev.ini --tags halo
ansible-playbook playbooks/deploy-services.yml -i inventory/dev.ini --tags prometheus

# 只在某台主机执行(灰度/排错)
ansible-playbook playbooks/site.yml -i inventory/dev.ini --limit node1

# 分批灰度:先 webservers,再 monitoring
ansible-playbook playbooks/deploy-services.yml -i inventory/dev.ini --tags gateway

# 变更后强制刷新所有 handler
ansible-playbook playbooks/site.yml --flush-cache

常用开关:

参数

作用

--check

预演模式,不产生真实变更

--diff

显示配置文件前后差异

--tags <tag>

只执行带指定 tag 的任务

--limit <主机/组>

限定执行范围

--ask-vault-pass

交互式输入 vault 密码

--vault-password-file

从文件读取 vault 密码(文件已被 .gitignore 排除)

--flush-cache

清空 fact 缓存后重新采集


六、落地清单(按阶段自己动手实现)

面向 3 台真实节点的 D0–D4 修正版执行计划见 docs/execution-plan.md(含本地缺陷修复步骤、价格口径、验收命令与计费红线);本节旧清单仅作为 WSL 单机练手参考。

  • 阶段 0:git init,安装 collection,确认 ansible.cfg 生效

  • 阶段 1:补齐 inventory/dev.ini 节点信息,完善 group_vars 变量

  • 阶段 2:跑通 common 角色(基线),在 dev 三节点验证时区/工具/swap/内核参数

  • 阶段 3:跑通 docker 角色,确认外部网络 cloudlab-net 创建成功

  • 阶段 4:逐角色实现并逐个验证(下列为旧 WSL 单机顺序;真实三节点实验的角色裁剪、分工与实现顺序以 docs/execution-plan.md §0、§5.1、§5.2 为准):
    npm → vaultwarden → halo → node-exporter → monitoring-prometheus(monitoring-grafana 可选;alist、uptime-kuma 已裁剪)

  • 阶段 5:ansible-vault encrypt group_vars/vault.yml,敏感信息不进 Git

  • 阶段 6:--check --diff 全量预演 → 正式执行 → check.yml 探活

  • 阶段 7:补全 README 架构说明,推送 GitHub,沉淀学习笔记

每个待实现角色的 tasks/main.yml 内已用 TODO 注释列出步骤、模块名与注意事项,参照 npm 角色即可。


七、企业级设计要点(对比个人脚本)

维度

个人脚本(早期 web-deploy)

本项目(企业级做法)

配置组织

单 playbook、变量写死

Role 模块化、职责单一、可跨环境复用

环境管理

只有一组节点

dev / staging / prod 三套清单,隔离误操作

变量管理

硬编码、密码明文

分层覆盖 + ansible-vault 加密

执行安全

直接落地

--check 预演、--diff 看差异、check.yml 探活

服务重启

无条件 restart

Handler 机制:配置变更后才触发 reload

任务粒度

整包一起跑

tags 分批灰度、--limit 单主机验证

工程规范

无依赖管理

requirements.yml 管 Collection、ansible.cfg 统一配置

幂等性

重复执行可能重复变更

模块状态参数 + creates 判断,重复执行不产生变更


八、已知约束与历史踩坑

  1. CentOS 7 纳管受限:ansible-core 2.19 已移除 yum 模块,且 CentOS 7 默认 Python 3.6 不满足要求;prod 纳管前需降级控制端到 2.12,或在被控端安装 Python 3.8+ 并指定 ansible_python_interpreter。

  2. 2 核 2G 内存紧张:Halo(JVM) 必须限制堆内存(Xms/Xmx),Prometheus 设内存上限;保留 Grafana 时另设 256m 上限;common 角色已提供 swap 方案。

  3. 未备案域名 80/443 被运营商阻断:国内节点仅靠 NPM + DNS-Challenge 完成证书签发,公网访问受备案限制。

  4. Halo 探活路径:全新无主题时根路径返回 404,探活应打 /console(302 登录跳转)。

  5. Kuma 监控目标(角色已裁剪,经验备查):避免用公网 IP 监控自身(NAT hairpin 误报),优先用容器名或内网地址。

  6. 本地代码现存阻塞缺陷:ansible.cfg 默认清单指向 prod、logs/ 目录缺失、module_lang 未适配;npm 模板变量跨 play undefined、Prometheus 模板过滤器不存在、compose 模块版本旧、check.yml 未做断言等问题,已逐条列入 docs/execution-plan.md §3,D0 先在本地修完再开机。