Loading README.md +136 −146 Original line number Diff line number Diff line Loading @@ -6,218 +6,208 @@ - 已安装 Docker 和 Docker Compose - **目标机器账号权限要求**:用于部署的执行账号(无论是手动执行 `make` 的当前用户,还是 Ansible Inventory 中的 `ansible_user`)**必须具有免 `sudo` 执行 Docker 命令的权限**(即该用户已加入 `docker` 用户组),或者拥有完整的 `root/sudo` 权限。 - Git - Make - Git、Make、Ansible - Linux 环境(因涉及权限与路径映射) ## 部署步骤 ## 核心运维入口说明 (Operations Entry Points) 本系统将所有的日常运维操作抽象为了两个高度内聚的工具入口: 1. **`make`**:负责上游开发侧的镜像构建、重命名与交付入库(Push)。 2. **`ansible`**:负责下游实施侧的环境预检、配置分发与集群容器生命周期管理。 本系统支持两种部署方式:**基于 Make 的单机/手动部署** 和 **基于 Ansible 的多节点自动化部署**。 ### 方式一:Ansible 多节点一键部署(推荐用于生产环境) 如果您需要在真实的集群(1个 Master 节点 + 多个 Worker 节点)上部署该系统,我们提供了开箱即用的 Ansible Playbooks。由于我们有多个不同的部署环境(如 `p368`, `csu`, `zjlab`),我们为每个环境准备了专属的 Ansible Inventory 文件。 **💡 进阶:为每个 Worker 单独指定并发度** 您可以直接在 Inventory 文件(例如 `inventory.p368.ini`)的每个 Worker 节点条目上设置 `worker_concurrency`,从而让不同机器使用不同的 Celery 并发数: ```ini [worker] worker-a ansible_host=192.168.25.19 ansible_user=root deploy_dir=/opt/csst-airflow-worker-a worker_concurrency=16 worker-b ansible_host=192.168.25.20 ansible_user=root deploy_dir=/opt/csst-airflow-worker-b worker_concurrency=64 worker-c ansible_host=192.168.25.21 ansible_user=root deploy_dir=/opt/csst-airflow-worker-c worker_concurrency=8 ``` --- - `worker_concurrency`:该节点上 Airflow Celery Worker 的并发槽位数。 - 建议按机器 CPU / 内存资源分别设置,不要所有 Worker 都使用同一个值。 - 如无特殊需要,请在每个 Worker 上显式写出该值,避免依赖默认值。 ### 1. 镜像的构建与交付 (`make` 命令组) #### 1. 准备工作 - **安装 Ansible**:如果您的执行机(通常是您的本地电脑或 Master 节点)尚未安装 Ansible,请先通过以下命令安装: 在有外网环境的机器或 CI/CD 系统中,通过 `make` 命令将业务自定义镜像和第三方依赖镜像全部构建并同步到私有 Harbor 镜像仓库。所有需要拉取的官方依赖镜像都显式地定义在根目录的 `required-images.txt` 中。 **Ubuntu / Debian:** 您可以随时在项目根目录运行 `make help` 查看说明: ```bash sudo apt update sudo apt install -y software-properties-common sudo apt-add-repository --yes --update ppa:ansible/ansible sudo apt install -y ansible make help ``` *(系统会自动打印出即将处理的全部 12 个镜像列表,包含 postgres、redis 等 9 个第三方镜像,以及 airflow、api-gateway 等 3 个自建镜像。)* #### 常用构建命令 为了简化操作,建议在执行 `make` 之前,**先在终端导出目标环境变量**,后续的所有 `make` 命令都可以直接复用这些变量而无需每次指定: **Python pip (跨平台推荐):** ```bash pip3 install ansible # 【方案一:常规部署环境,如 p368】 # 设置部署环境名称 (例如 p368) export ENV=p368 # 设置镜像推送的 Harbor 仓库地址前缀 (必须以斜杠结尾) export HARBOR_PROJECT=harbor.csst.nao:10443/csst/ # 设置构建镜像的版本号 export IMAGE_TAG=test # 设置内部构建号 (将展示在 Portal 前端),如果不设置将默认使用 IMAGE_TAG 的值 export BUILD_NUMBER=123456 # ---------------------------------------- # 【方案二:本地单机开发测试环境】 # 如果是本地开发机直接打包运行,不需要推送到远端 Harbor,可留空 export ENV=local export HARBOR_PROJECT= export IMAGE_TAG=latest export BUILD_NUMBER=dev ``` - **配置 SSH 免密与权限**:确保执行机配置了到所有目标节点(Master & Workers)的 SSH 免密登录。此外,清单中配置的 `ansible_user` 用户必须在目标机器上具有执行 `docker` 和 `docker compose` 命令的权限(将其加入 docker 组或具有 sudo 权限)。 #### 2. 配置环境对应的 Inventory 文件 根据您要部署的环境,编辑 `ansible/inventories/` 目录下对应的清单文件(例如 `inventory.csu.ini`)。 配置好环境变量后,您可以执行以下精简命令: **关于部署路径 (`deploy_dir`) 的重要说明:** 为了确保在各种环境(尤其是包含 NFS/NAS 共享存储,或者单机混合部署)下不会产生文件覆盖与权限冲突,**我们强烈推荐在 Inventory 中为每个节点(或组)显式指定独立的 `deploy_dir`**。 即使您的 Master 和 Worker 在不同的物理机上,如果在 `/opt/` 下挂载了同一块共享存储,不区分路径也会导致容器配置被互相覆盖。 ```bash # 1. 仅拉取外部依赖 # 从 required-images.txt 清单中拉取 13 个基础和组件依赖镜像(自动跳过已存在的) make pull 推荐部署示例(为不同角色或节点指定不同路径与别名): ```ini [master] # node-master 为节点的别名,后续可通过 ansible node-master 进行针对性操作 node-master ansible_host=192.168.25.18 ansible_user=root deploy_dir=/opt/csst-airflow-master # 2. 仅构建 (不推送到私有仓库) # 基于依赖镜像构建业务镜像,并将所有镜像重命名为统一样式 (例如 harbor.../csst-airflow:v0.0.0) make build [worker] node-worker1 ansible_host=192.168.25.19 ansible_user=root deploy_dir=/opt/csst-airflow-worker1 worker_concurrency=16 node-worker2 ansible_host=192.168.25.20 ansible_user=root deploy_dir=/opt/csst-airflow-worker2 worker_concurrency=32 # 3. 仅推送 # 将已打好 Tag 的全量 16 个镜像推送到远端 Harbor make push [all:vars] env_name=csu # 全局默认部署路径(仅在未明确指定的节点上生效) deploy_dir=/opt/csst-airflow # 4. 一键完成全套交付 (最常用) # 依次执行清理旧镜像、拉取依赖、构建业务镜像到全量推送,一气呵成 make all ``` *(在构建和推送过程中,终端会以 `[BUILD/TAG] Processing Postgres...` 或 `[PUSH] Pushing harbor.csst.nao...` 的形式清晰打印当前进度。)* 如果多个 Worker 机器规格相同,也可以在 `[worker:vars]` 中统一配置默认值,再在个别节点上单独覆盖: ```ini [worker:vars] worker_concurrency=16 [worker] node-worker1 ansible_host=192.168.25.19 ansible_user=root deploy_dir=/opt/csst-airflow-worker1 node-worker2 ansible_host=192.168.25.20 ansible_user=root deploy_dir=/opt/csst-airflow-worker2 node-worker3 ansible_host=192.168.25.21 ansible_user=root deploy_dir=/opt/csst-airflow-worker3 worker_concurrency=32 ``` --- 上述配置会在部署时写入目标节点的 `.env`,并在启动 Worker 容器时传递给 `AIRFLOW__CELERY__WORKER_CONCURRENCY`,因此只需要修改 Inventory 后重新执行 Ansible 部署或更新即可生效。 ### 2. 自动化部署与启停 (`ansible` 命令组) #### 3. 配置环境变量 为了让集群中的所有组件(特别是 Worker 节点)能够正确找到主节点和其他依赖,您需要为该环境配置专用的 `.env` 文件。 在 `envs/` 目录下,复制或编辑对应环境的 `.env` 文件(例如 `envs/csu.env`)。您**必须**修改 `MASTER_IP` 和 `HARBOR` 这两个关键变量: 本系统**唯一推荐**的部署方式为基于 Ansible 的一键部署。所有多环境(如 `p368`, `csu`, `zjlab`)的配置都已严格隔离在 `deploy_configs/<env>/` 目录下。 ```env # --- Airflow Core Config --- AIRFLOW_IMAGE_NAME=apache/airflow:3.0.5 AIRFLOW_UID=50000 为了简化操作,建议在执行部署前,**先在终端导出目标环境名称变量**,后续的所有 Ansible 命令都可以直接复用该变量: # --- Cluster & Network Config --- # 必须修改:将其替换为 Master 节点的实际 IP 地址 MASTER_IP=192.168.25.18 # 必须修改:将其替换为您当前环境使用的镜像仓库地址 HARBOR=csu-harbor.csst.nao:10443 # --- API Gateway Config (其余端口和内部 IP 默认会自动引用 MASTER_IP,通常无需修改) --- POSTGRES_HOST=${MASTER_IP} AIRFLOW_HOST=${MASTER_IP} REDIS_HOST=${MASTER_IP} ELASTICSEARCH_HOST=${MASTER_IP} ```bash # 例如要部署 p368 环境,只需执行一次: export ENV=p368 ``` #### 4. 一键部署集群 在 `docker-celery-3.0.5` 目录下执行(以 `csu` 环境为例): 目前为您内置了 5 个不同场景的自动化剧本(Playbook),设置好变量后即可运行: #### ① 部署前环境预检 (`check.yml`) 在正式部署前,验证网络连通性及基础环境是否齐备。它会自动 ping 所有节点、检查 Docker 和 Compose 插件是否安装,并校验目标机器的部署路径与磁盘剩余空间: ```bash # 1. 部署所有节点的基础组件与服务容器 ansible-playbook -i ansible/inventories/inventory.csu.ini ansible/deploy.yml # 2. 同步 DAGs 代码到所有节点 (仅更新 DAGs 业务代码时执行此命令即可) ansible-playbook -i ansible/inventories/inventory.csu.ini ansible/sync_dags.yml ansible-playbook ansible/check.yml -i deploy_configs/${ENV}/inventory.ini ``` #### 5. 软件升级与更新 当您在 Master 节点上通过 `git pull` 拉取了最新的框架代码、修改了 `docker-compose.yaml` 或者是更新了自定义的镜像版本后,您只需要执行以下一键更新命令: #### ② 首次部署或全量更新部署 (`deploy.yml` 或 `playbook.yml`) 自动分发环境配置、解析变量、拉取最新镜像(支持 fallback 到本地镜像),并从零拉起所有 Master 和 Worker 节点的容器集群: ```bash ansible-playbook -i ansible/inventories/inventory.csu.ini ansible/update.yml ansible-playbook ansible/deploy.yml -i deploy_configs/${ENV}/inventory.ini ``` *(该脚本会自动将最新的代码同步给所有集群节点,并让各节点拉取最新镜像、重启发生了变更的服务容器,而不会中断未发生变更的服务。)* --- ### 方式二:基于 Make 的单机或手动部署 #### 1. 初始化目录与权限 #### ③ 软件升级与全量重启 (`update.yml`) 当修改了 `docker-compose.yaml` 或者是更新了镜像版本后,此命令会优雅地下线旧容器,拉取最新配置并启动新容器。特别是结合 `make build` 之后,利用此剧本能完美重启集群并应用新镜像: ```bash make mkdir make fix-permission ansible-playbook ansible/update.yml -i deploy_configs/${ENV}/inventory.ini ``` > **注意**: `fix-permission` 会使用 `sudo` 修复 Elasticsearch 数据目录的归属,以防启动时因无权写入数据而失败。 #### 2. 选择部署环境 本系统支持通过 Makefile 动态指定环境变量配置文件。您可以随时通过以下命令查看当前支持的所有环境模板: #### ④ 业务代码轻量更新 (`sync_dags.yml`) 如果只修改了 `dags/` 目录下的 Python 脚本,无需全量重启容器,直接执行轻量级同步即可将脚本分发给所有节点: ```bash ansible-playbook ansible/sync_dags.yml -i deploy_configs/${ENV}/inventory.ini ``` #### ⑤ 停止与卸载服务 (`down.yml`) 完全停止并移除所有节点上的服务(等价于在所有机器上批量执行 `docker compose down`): ```bash make list-envs ansible-playbook ansible/down.yml -i deploy_configs/${ENV}/inventory.ini ``` *(系统将自动读取 `envs/` 目录下的 `*.env` 文件)* #### 3. 初始化 Airflow 数据库 --- ## 配置环境参数 (部署前的必要准备) 在为一个新的环境(例如 `p368`)进行部署前,您必须了解 `deploy_configs/` 目录下的 **4 份**配置文件的作用: 在首次部署的**主控节点**上执行数据库初始化(假设您使用的是 `csu` 环境): ### 一、全局静态配置 (通常无需修改) ```bash make init ENV=csu #### ① `deploy_configs/airflow.env` (必需) **作用**:存放所有环境通用的底层系统级静态配置(例如 `AIRFLOW_UID=50000`)。 **注意**:由于它是静态的,我们将其放置在 `deploy_configs/` 根目录下,由所有环境共享。Ansible 部署时会自动将此文件分发给对应环境。 ```env # --- Airflow 核心静态配置 --- AIRFLOW_UID=50000 AIRFLOW_PROJ_DIR=. _AIRFLOW_WWW_USER_USERNAME=airflow _AIRFLOW_WWW_USER_PASSWORD=airflow ``` #### 4. 启动核心服务 ### 二、环境特异性配置 (每个环境独立维护) > **⚠️ 部署强烈建议**: > 系统采用 Master/Worker 分离架构,主节点负责调度与监控网关,子节点负责计算。 #### ② `deploy_configs/<env>/inventory.ini` (必需:定义 Ansible 部署拓扑与变量) **作用**:这是基础设施配置的**唯一入口**。它不仅决定了集群机器拓扑,还控制了镜像来源与核心安全密钥,您**只需修改这一个文件**即可适配不同环境。 **配置指南**: - 配置 Master/Worker 节点的 IP (`ansible_host`)、SSH 用户。系统会自动将 `master` 组内第一个节点的 IP 作为集群内部通信的 `MASTER_IP`,**无需再手动指定**。 - **`deploy_dir`**:为避免冲突,强烈建议为每个节点显式指定独立的部署路径。例如 `/opt/csst-airflow`。 - **`worker_concurrency`**:控制该节点上 Celery Worker 的并发处理能力。 - **环境声明**:必须在该文件底部的 `[all:vars]` 中声明当前的环境名称。 - **`harbor_project` 与 `image_tag`**: 强烈建议利用环境变量与 `make all` 的工作流生成带动态 Tag 的镜像,然后在 `inventory.ini` 中填写。Ansible 会结合这两个变量自动组装镜像名称,拉取最新版本。 - **JWT 密钥**:通过 `jwt_secret` 指定,用于 API Gateway 与 Airflow Apiserver 通信。 ##### 主控节点 (Master Node) 部署: 在作为 Master 的机器上执行,此命令会启动数据库、消息队列、API Gateway、Prometheus/Grafana 监控大盘以及 Airflow 控制平面: ```ini [master] p368-master ansible_host=127.0.0.1 ansible_connection=local ```bash make up-master ENV=csu ``` [worker] p368-worker1 ansible_host=127.0.0.1 ansible_connection=local ##### 计算节点 (Worker Node) 部署: 在提供算力的机器上执行,此命令**仅启动** Celery Worker 和该机器专属的日志采集与监控探针 (Filebeat / cAdvisor / Node Exporter): [all:vars] env=p368 deploy_dir=/opt/csst-airflow ```bash make up-worker ENV=csu # 镜像仓库前缀 (以斜杠结尾) harbor_project=harbor.csst.nao:10443/csst/ image_tag=test # API Gateway 与 Airflow Apiserver 通信所用的 JWT 密钥 jwt_secret=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVC... ``` > **提示**: 探针会自动启动,以供 Master 节点的 Prometheus 和 ES 抓取该 Worker 机器的资源与日志状态。 --- #### ③ `deploy_configs/<env>/variables.toml` (可选:定义 Airflow 业务环境变量) **作用**:存放与外部系统(如 DFS、CCDS、OSS/S3 对象存储等)交互的业务级环境变量。Ansible 部署时会自动将该 TOML 文件解析,并通过 `airflow variables import` 命令导入到 Airflow 的 Postgres 数据库中。 **配置指南**: 相比 JSON,TOML 格式更易于阅读和维护,您可以使用 section `[块]` 的方式对不同服务的变量进行分组: ```toml [dfs] gateway = "10.80.1.22:28000" timeout = 30 [oss] endpoint_url = "http://10.80.1.10:9000" bucket = "csst-data" ``` ## Makefile 命令速查 #### ④ `deploy_configs/<env>/connections.json` (可选:定义 Airflow 加密连接) 如果需要预置 Airflow 的连接配置,可将其存放在这里,Ansible 部署时会自动将这些配置导入到 Airflow 的 DB 中。 | 命令 | 描述 | |------|------| | `make list-envs` | 列出 `envs/` 目录下所有可用的环境名称 | | `make mkdir` | 创建所有必需的挂载目录 | | `make fix-permission` | 修复 `es_data` 目录的属主权限 (UID 50000) | | `make init ENV=<env>` | 初始化 Airflow 数据库 | | `make up-master ENV=<env>` | 启动主控节点 (包含网关与所有监控大盘) | | `make up-worker ENV=<env>` | 启动计算节点 (仅包含 Worker 和监控探针) | | `make down ENV=<env>` | 停止并移除指定环境的容器 | | `make clean ENV=<env>` | 停止服务并清理容器 | | `make ps ENV=<env>` | 列出当前运行中的服务 | > **💡 容错机制说明 (Local Fallback)**: > 部署脚本在启动容器前会执行 `docker compose pull` 从 Harbor 拉取镜像。如果当前环境无法连接外网/Harbor,只要该节点上预先 `make build` 过本地镜像,`pull` 失败的报错会被自动忽略并直接使用本地镜像启动服务。 ## 访问服务与系统端口映射 在完整的分布式或单机部署中,各个组件所占用的宿主机端口如下。**请在部署前确保宿主机的这些防火墙端口已开放且未被占用**。 ### 主控节点 (Master Node) 执行 `make up` 或 `make up-master` 的机器上将暴露以下核心服务端口: 执行 Ansible 部署后,主节点机器上将暴露以下核心服务端口: | 服务组件 | 宿主机端口 | 用途说明 | 访问地址示例 | | :--- | :--- | :--- | :--- | | **Task Portal** | `38501` | **统一任务与监控控制台**。提供带进度预估的 JSON 筛选及 Grafana 资源大盘内嵌页 | `http://<MASTER_IP>:38501` | | **API Gateway** | `38000` | **业务系统唯一对接入口**。提供高并发任务提交、任务控制(取消/重试)与状态检索 | `http://<MASTER_IP>:38000` | | **Airflow Web UI** | `38080` | Airflow 原生控制台与官方 API (已开启 `SimpleAuthManager` 免密 Admin 登录) | `http://<MASTER_IP>:38080` | | **Airflow Apiserver** | `38080` | Airflow 3 原生控制台与官方 API (已开启 `SimpleAuthManager` 免密 Admin 登录) | `http://<MASTER_IP>:38080` | | **Grafana** | `33000` | 时间序列数据监控与仪表盘可视化 (账号密码默认: `admin`/`admin`) | `http://<MASTER_IP>:33000` | | **Prometheus** | `39090` | 集群监控指标拉取服务器 | `http://<MASTER_IP>:39090` | | **Kibana** | `35601` | 集中式日志可视化中心 (直接在 Discover 页面选择 `airflow-*` 视图检索日志) | `http://<MASTER_IP>:35601` | | **Flower** | `35555` | Celery 集群状态监控面板 (**仅在执行 `make up-master` 时启动**) | `http://<MASTER_IP>:35555` | | **Flower** | `35555` | Celery 集群状态监控面板 | `http://<MASTER_IP>:35555` | | **Elasticsearch** | `39200` | 存储运行日志的底层搜索引擎 API | `http://<MASTER_IP>:39200` | | **PostgreSQL** | `35432` | 核心元数据库,存储 Airflow 数据及 API Gateway 的 `csst_task_records` 表 | `postgresql://<MASTER_IP>:35432` | | **Redis** | `36379` | Celery 消息队列中间件 | `redis://<MASTER_IP>:36379` | ### 计算节点 (Worker Node) 执行 `make up-worker ENV=<env>` 的机器: Worker 节点: * **不暴露核心业务端口**,仅暴露 `cAdvisor` (38081) 和 `Node Exporter` (通过 Host 网络) 供主节点拉取监控指标。 * Worker 节点只需通过 `*.env` 中的 `MASTER_IP` 环境变量,主动连接到主控节点的 Redis 和 Postgres 即可静默消费任务。 * Worker 节点只需通过 `system.env` 中的 `MASTER_IP` 环境变量,主动连接到主控节点的 Redis 和 Postgres 即可静默消费任务。 --- Loading @@ -231,10 +221,10 @@ make up-worker ENV=csu ## 故障排除 - 确保 Docker 正在运行 - 确保宿主机端口未被占用:`38080` (Airflow), `39200` (ES), `35601` (Kibana) - 若 Elasticsearch 启动失败 (Unhealthy),请查看权限问题,再次执行 `make fix-permission` 并 `docker compose restart elasticsearch` (或 `docker-compose restart elasticsearch`) - 确保宿主机端口未被占用:`38080` (Airflow), `39200` (ES), `35601` (Kibana) 等 - **Celery Worker 监控数据丢失**:如果在 Flower 面板看不到 Worker 或在 Task Portal 的 Workers 列表中为空,请确保在部署 Worker 的 `docker-compose` 里的 `${HOSTNAME}` 等变量配置了正确的双美元符(`$$`)转义,以免在宿主机上被提前解析。 - 若 Elasticsearch 启动失败 (Unhealthy),系统可能会存在权限问题,Ansible 脚本在执行时通常会自动修复(将 `es_data` 属主设为 50000)。如遇意外,可尝试手动执行 `sudo chown -R 50000:0 volumes/es_data` 并重启容器。 - 检查容器日志以了解错误: ```bash docker compose logs -f # 或者使用老版本:docker-compose logs -f ``` Loading
README.md +136 −146 Original line number Diff line number Diff line Loading @@ -6,218 +6,208 @@ - 已安装 Docker 和 Docker Compose - **目标机器账号权限要求**:用于部署的执行账号(无论是手动执行 `make` 的当前用户,还是 Ansible Inventory 中的 `ansible_user`)**必须具有免 `sudo` 执行 Docker 命令的权限**(即该用户已加入 `docker` 用户组),或者拥有完整的 `root/sudo` 权限。 - Git - Make - Git、Make、Ansible - Linux 环境(因涉及权限与路径映射) ## 部署步骤 ## 核心运维入口说明 (Operations Entry Points) 本系统将所有的日常运维操作抽象为了两个高度内聚的工具入口: 1. **`make`**:负责上游开发侧的镜像构建、重命名与交付入库(Push)。 2. **`ansible`**:负责下游实施侧的环境预检、配置分发与集群容器生命周期管理。 本系统支持两种部署方式:**基于 Make 的单机/手动部署** 和 **基于 Ansible 的多节点自动化部署**。 ### 方式一:Ansible 多节点一键部署(推荐用于生产环境) 如果您需要在真实的集群(1个 Master 节点 + 多个 Worker 节点)上部署该系统,我们提供了开箱即用的 Ansible Playbooks。由于我们有多个不同的部署环境(如 `p368`, `csu`, `zjlab`),我们为每个环境准备了专属的 Ansible Inventory 文件。 **💡 进阶:为每个 Worker 单独指定并发度** 您可以直接在 Inventory 文件(例如 `inventory.p368.ini`)的每个 Worker 节点条目上设置 `worker_concurrency`,从而让不同机器使用不同的 Celery 并发数: ```ini [worker] worker-a ansible_host=192.168.25.19 ansible_user=root deploy_dir=/opt/csst-airflow-worker-a worker_concurrency=16 worker-b ansible_host=192.168.25.20 ansible_user=root deploy_dir=/opt/csst-airflow-worker-b worker_concurrency=64 worker-c ansible_host=192.168.25.21 ansible_user=root deploy_dir=/opt/csst-airflow-worker-c worker_concurrency=8 ``` --- - `worker_concurrency`:该节点上 Airflow Celery Worker 的并发槽位数。 - 建议按机器 CPU / 内存资源分别设置,不要所有 Worker 都使用同一个值。 - 如无特殊需要,请在每个 Worker 上显式写出该值,避免依赖默认值。 ### 1. 镜像的构建与交付 (`make` 命令组) #### 1. 准备工作 - **安装 Ansible**:如果您的执行机(通常是您的本地电脑或 Master 节点)尚未安装 Ansible,请先通过以下命令安装: 在有外网环境的机器或 CI/CD 系统中,通过 `make` 命令将业务自定义镜像和第三方依赖镜像全部构建并同步到私有 Harbor 镜像仓库。所有需要拉取的官方依赖镜像都显式地定义在根目录的 `required-images.txt` 中。 **Ubuntu / Debian:** 您可以随时在项目根目录运行 `make help` 查看说明: ```bash sudo apt update sudo apt install -y software-properties-common sudo apt-add-repository --yes --update ppa:ansible/ansible sudo apt install -y ansible make help ``` *(系统会自动打印出即将处理的全部 12 个镜像列表,包含 postgres、redis 等 9 个第三方镜像,以及 airflow、api-gateway 等 3 个自建镜像。)* #### 常用构建命令 为了简化操作,建议在执行 `make` 之前,**先在终端导出目标环境变量**,后续的所有 `make` 命令都可以直接复用这些变量而无需每次指定: **Python pip (跨平台推荐):** ```bash pip3 install ansible # 【方案一:常规部署环境,如 p368】 # 设置部署环境名称 (例如 p368) export ENV=p368 # 设置镜像推送的 Harbor 仓库地址前缀 (必须以斜杠结尾) export HARBOR_PROJECT=harbor.csst.nao:10443/csst/ # 设置构建镜像的版本号 export IMAGE_TAG=test # 设置内部构建号 (将展示在 Portal 前端),如果不设置将默认使用 IMAGE_TAG 的值 export BUILD_NUMBER=123456 # ---------------------------------------- # 【方案二:本地单机开发测试环境】 # 如果是本地开发机直接打包运行,不需要推送到远端 Harbor,可留空 export ENV=local export HARBOR_PROJECT= export IMAGE_TAG=latest export BUILD_NUMBER=dev ``` - **配置 SSH 免密与权限**:确保执行机配置了到所有目标节点(Master & Workers)的 SSH 免密登录。此外,清单中配置的 `ansible_user` 用户必须在目标机器上具有执行 `docker` 和 `docker compose` 命令的权限(将其加入 docker 组或具有 sudo 权限)。 #### 2. 配置环境对应的 Inventory 文件 根据您要部署的环境,编辑 `ansible/inventories/` 目录下对应的清单文件(例如 `inventory.csu.ini`)。 配置好环境变量后,您可以执行以下精简命令: **关于部署路径 (`deploy_dir`) 的重要说明:** 为了确保在各种环境(尤其是包含 NFS/NAS 共享存储,或者单机混合部署)下不会产生文件覆盖与权限冲突,**我们强烈推荐在 Inventory 中为每个节点(或组)显式指定独立的 `deploy_dir`**。 即使您的 Master 和 Worker 在不同的物理机上,如果在 `/opt/` 下挂载了同一块共享存储,不区分路径也会导致容器配置被互相覆盖。 ```bash # 1. 仅拉取外部依赖 # 从 required-images.txt 清单中拉取 13 个基础和组件依赖镜像(自动跳过已存在的) make pull 推荐部署示例(为不同角色或节点指定不同路径与别名): ```ini [master] # node-master 为节点的别名,后续可通过 ansible node-master 进行针对性操作 node-master ansible_host=192.168.25.18 ansible_user=root deploy_dir=/opt/csst-airflow-master # 2. 仅构建 (不推送到私有仓库) # 基于依赖镜像构建业务镜像,并将所有镜像重命名为统一样式 (例如 harbor.../csst-airflow:v0.0.0) make build [worker] node-worker1 ansible_host=192.168.25.19 ansible_user=root deploy_dir=/opt/csst-airflow-worker1 worker_concurrency=16 node-worker2 ansible_host=192.168.25.20 ansible_user=root deploy_dir=/opt/csst-airflow-worker2 worker_concurrency=32 # 3. 仅推送 # 将已打好 Tag 的全量 16 个镜像推送到远端 Harbor make push [all:vars] env_name=csu # 全局默认部署路径(仅在未明确指定的节点上生效) deploy_dir=/opt/csst-airflow # 4. 一键完成全套交付 (最常用) # 依次执行清理旧镜像、拉取依赖、构建业务镜像到全量推送,一气呵成 make all ``` *(在构建和推送过程中,终端会以 `[BUILD/TAG] Processing Postgres...` 或 `[PUSH] Pushing harbor.csst.nao...` 的形式清晰打印当前进度。)* 如果多个 Worker 机器规格相同,也可以在 `[worker:vars]` 中统一配置默认值,再在个别节点上单独覆盖: ```ini [worker:vars] worker_concurrency=16 [worker] node-worker1 ansible_host=192.168.25.19 ansible_user=root deploy_dir=/opt/csst-airflow-worker1 node-worker2 ansible_host=192.168.25.20 ansible_user=root deploy_dir=/opt/csst-airflow-worker2 node-worker3 ansible_host=192.168.25.21 ansible_user=root deploy_dir=/opt/csst-airflow-worker3 worker_concurrency=32 ``` --- 上述配置会在部署时写入目标节点的 `.env`,并在启动 Worker 容器时传递给 `AIRFLOW__CELERY__WORKER_CONCURRENCY`,因此只需要修改 Inventory 后重新执行 Ansible 部署或更新即可生效。 ### 2. 自动化部署与启停 (`ansible` 命令组) #### 3. 配置环境变量 为了让集群中的所有组件(特别是 Worker 节点)能够正确找到主节点和其他依赖,您需要为该环境配置专用的 `.env` 文件。 在 `envs/` 目录下,复制或编辑对应环境的 `.env` 文件(例如 `envs/csu.env`)。您**必须**修改 `MASTER_IP` 和 `HARBOR` 这两个关键变量: 本系统**唯一推荐**的部署方式为基于 Ansible 的一键部署。所有多环境(如 `p368`, `csu`, `zjlab`)的配置都已严格隔离在 `deploy_configs/<env>/` 目录下。 ```env # --- Airflow Core Config --- AIRFLOW_IMAGE_NAME=apache/airflow:3.0.5 AIRFLOW_UID=50000 为了简化操作,建议在执行部署前,**先在终端导出目标环境名称变量**,后续的所有 Ansible 命令都可以直接复用该变量: # --- Cluster & Network Config --- # 必须修改:将其替换为 Master 节点的实际 IP 地址 MASTER_IP=192.168.25.18 # 必须修改:将其替换为您当前环境使用的镜像仓库地址 HARBOR=csu-harbor.csst.nao:10443 # --- API Gateway Config (其余端口和内部 IP 默认会自动引用 MASTER_IP,通常无需修改) --- POSTGRES_HOST=${MASTER_IP} AIRFLOW_HOST=${MASTER_IP} REDIS_HOST=${MASTER_IP} ELASTICSEARCH_HOST=${MASTER_IP} ```bash # 例如要部署 p368 环境,只需执行一次: export ENV=p368 ``` #### 4. 一键部署集群 在 `docker-celery-3.0.5` 目录下执行(以 `csu` 环境为例): 目前为您内置了 5 个不同场景的自动化剧本(Playbook),设置好变量后即可运行: #### ① 部署前环境预检 (`check.yml`) 在正式部署前,验证网络连通性及基础环境是否齐备。它会自动 ping 所有节点、检查 Docker 和 Compose 插件是否安装,并校验目标机器的部署路径与磁盘剩余空间: ```bash # 1. 部署所有节点的基础组件与服务容器 ansible-playbook -i ansible/inventories/inventory.csu.ini ansible/deploy.yml # 2. 同步 DAGs 代码到所有节点 (仅更新 DAGs 业务代码时执行此命令即可) ansible-playbook -i ansible/inventories/inventory.csu.ini ansible/sync_dags.yml ansible-playbook ansible/check.yml -i deploy_configs/${ENV}/inventory.ini ``` #### 5. 软件升级与更新 当您在 Master 节点上通过 `git pull` 拉取了最新的框架代码、修改了 `docker-compose.yaml` 或者是更新了自定义的镜像版本后,您只需要执行以下一键更新命令: #### ② 首次部署或全量更新部署 (`deploy.yml` 或 `playbook.yml`) 自动分发环境配置、解析变量、拉取最新镜像(支持 fallback 到本地镜像),并从零拉起所有 Master 和 Worker 节点的容器集群: ```bash ansible-playbook -i ansible/inventories/inventory.csu.ini ansible/update.yml ansible-playbook ansible/deploy.yml -i deploy_configs/${ENV}/inventory.ini ``` *(该脚本会自动将最新的代码同步给所有集群节点,并让各节点拉取最新镜像、重启发生了变更的服务容器,而不会中断未发生变更的服务。)* --- ### 方式二:基于 Make 的单机或手动部署 #### 1. 初始化目录与权限 #### ③ 软件升级与全量重启 (`update.yml`) 当修改了 `docker-compose.yaml` 或者是更新了镜像版本后,此命令会优雅地下线旧容器,拉取最新配置并启动新容器。特别是结合 `make build` 之后,利用此剧本能完美重启集群并应用新镜像: ```bash make mkdir make fix-permission ansible-playbook ansible/update.yml -i deploy_configs/${ENV}/inventory.ini ``` > **注意**: `fix-permission` 会使用 `sudo` 修复 Elasticsearch 数据目录的归属,以防启动时因无权写入数据而失败。 #### 2. 选择部署环境 本系统支持通过 Makefile 动态指定环境变量配置文件。您可以随时通过以下命令查看当前支持的所有环境模板: #### ④ 业务代码轻量更新 (`sync_dags.yml`) 如果只修改了 `dags/` 目录下的 Python 脚本,无需全量重启容器,直接执行轻量级同步即可将脚本分发给所有节点: ```bash ansible-playbook ansible/sync_dags.yml -i deploy_configs/${ENV}/inventory.ini ``` #### ⑤ 停止与卸载服务 (`down.yml`) 完全停止并移除所有节点上的服务(等价于在所有机器上批量执行 `docker compose down`): ```bash make list-envs ansible-playbook ansible/down.yml -i deploy_configs/${ENV}/inventory.ini ``` *(系统将自动读取 `envs/` 目录下的 `*.env` 文件)* #### 3. 初始化 Airflow 数据库 --- ## 配置环境参数 (部署前的必要准备) 在为一个新的环境(例如 `p368`)进行部署前,您必须了解 `deploy_configs/` 目录下的 **4 份**配置文件的作用: 在首次部署的**主控节点**上执行数据库初始化(假设您使用的是 `csu` 环境): ### 一、全局静态配置 (通常无需修改) ```bash make init ENV=csu #### ① `deploy_configs/airflow.env` (必需) **作用**:存放所有环境通用的底层系统级静态配置(例如 `AIRFLOW_UID=50000`)。 **注意**:由于它是静态的,我们将其放置在 `deploy_configs/` 根目录下,由所有环境共享。Ansible 部署时会自动将此文件分发给对应环境。 ```env # --- Airflow 核心静态配置 --- AIRFLOW_UID=50000 AIRFLOW_PROJ_DIR=. _AIRFLOW_WWW_USER_USERNAME=airflow _AIRFLOW_WWW_USER_PASSWORD=airflow ``` #### 4. 启动核心服务 ### 二、环境特异性配置 (每个环境独立维护) > **⚠️ 部署强烈建议**: > 系统采用 Master/Worker 分离架构,主节点负责调度与监控网关,子节点负责计算。 #### ② `deploy_configs/<env>/inventory.ini` (必需:定义 Ansible 部署拓扑与变量) **作用**:这是基础设施配置的**唯一入口**。它不仅决定了集群机器拓扑,还控制了镜像来源与核心安全密钥,您**只需修改这一个文件**即可适配不同环境。 **配置指南**: - 配置 Master/Worker 节点的 IP (`ansible_host`)、SSH 用户。系统会自动将 `master` 组内第一个节点的 IP 作为集群内部通信的 `MASTER_IP`,**无需再手动指定**。 - **`deploy_dir`**:为避免冲突,强烈建议为每个节点显式指定独立的部署路径。例如 `/opt/csst-airflow`。 - **`worker_concurrency`**:控制该节点上 Celery Worker 的并发处理能力。 - **环境声明**:必须在该文件底部的 `[all:vars]` 中声明当前的环境名称。 - **`harbor_project` 与 `image_tag`**: 强烈建议利用环境变量与 `make all` 的工作流生成带动态 Tag 的镜像,然后在 `inventory.ini` 中填写。Ansible 会结合这两个变量自动组装镜像名称,拉取最新版本。 - **JWT 密钥**:通过 `jwt_secret` 指定,用于 API Gateway 与 Airflow Apiserver 通信。 ##### 主控节点 (Master Node) 部署: 在作为 Master 的机器上执行,此命令会启动数据库、消息队列、API Gateway、Prometheus/Grafana 监控大盘以及 Airflow 控制平面: ```ini [master] p368-master ansible_host=127.0.0.1 ansible_connection=local ```bash make up-master ENV=csu ``` [worker] p368-worker1 ansible_host=127.0.0.1 ansible_connection=local ##### 计算节点 (Worker Node) 部署: 在提供算力的机器上执行,此命令**仅启动** Celery Worker 和该机器专属的日志采集与监控探针 (Filebeat / cAdvisor / Node Exporter): [all:vars] env=p368 deploy_dir=/opt/csst-airflow ```bash make up-worker ENV=csu # 镜像仓库前缀 (以斜杠结尾) harbor_project=harbor.csst.nao:10443/csst/ image_tag=test # API Gateway 与 Airflow Apiserver 通信所用的 JWT 密钥 jwt_secret=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVC... ``` > **提示**: 探针会自动启动,以供 Master 节点的 Prometheus 和 ES 抓取该 Worker 机器的资源与日志状态。 --- #### ③ `deploy_configs/<env>/variables.toml` (可选:定义 Airflow 业务环境变量) **作用**:存放与外部系统(如 DFS、CCDS、OSS/S3 对象存储等)交互的业务级环境变量。Ansible 部署时会自动将该 TOML 文件解析,并通过 `airflow variables import` 命令导入到 Airflow 的 Postgres 数据库中。 **配置指南**: 相比 JSON,TOML 格式更易于阅读和维护,您可以使用 section `[块]` 的方式对不同服务的变量进行分组: ```toml [dfs] gateway = "10.80.1.22:28000" timeout = 30 [oss] endpoint_url = "http://10.80.1.10:9000" bucket = "csst-data" ``` ## Makefile 命令速查 #### ④ `deploy_configs/<env>/connections.json` (可选:定义 Airflow 加密连接) 如果需要预置 Airflow 的连接配置,可将其存放在这里,Ansible 部署时会自动将这些配置导入到 Airflow 的 DB 中。 | 命令 | 描述 | |------|------| | `make list-envs` | 列出 `envs/` 目录下所有可用的环境名称 | | `make mkdir` | 创建所有必需的挂载目录 | | `make fix-permission` | 修复 `es_data` 目录的属主权限 (UID 50000) | | `make init ENV=<env>` | 初始化 Airflow 数据库 | | `make up-master ENV=<env>` | 启动主控节点 (包含网关与所有监控大盘) | | `make up-worker ENV=<env>` | 启动计算节点 (仅包含 Worker 和监控探针) | | `make down ENV=<env>` | 停止并移除指定环境的容器 | | `make clean ENV=<env>` | 停止服务并清理容器 | | `make ps ENV=<env>` | 列出当前运行中的服务 | > **💡 容错机制说明 (Local Fallback)**: > 部署脚本在启动容器前会执行 `docker compose pull` 从 Harbor 拉取镜像。如果当前环境无法连接外网/Harbor,只要该节点上预先 `make build` 过本地镜像,`pull` 失败的报错会被自动忽略并直接使用本地镜像启动服务。 ## 访问服务与系统端口映射 在完整的分布式或单机部署中,各个组件所占用的宿主机端口如下。**请在部署前确保宿主机的这些防火墙端口已开放且未被占用**。 ### 主控节点 (Master Node) 执行 `make up` 或 `make up-master` 的机器上将暴露以下核心服务端口: 执行 Ansible 部署后,主节点机器上将暴露以下核心服务端口: | 服务组件 | 宿主机端口 | 用途说明 | 访问地址示例 | | :--- | :--- | :--- | :--- | | **Task Portal** | `38501` | **统一任务与监控控制台**。提供带进度预估的 JSON 筛选及 Grafana 资源大盘内嵌页 | `http://<MASTER_IP>:38501` | | **API Gateway** | `38000` | **业务系统唯一对接入口**。提供高并发任务提交、任务控制(取消/重试)与状态检索 | `http://<MASTER_IP>:38000` | | **Airflow Web UI** | `38080` | Airflow 原生控制台与官方 API (已开启 `SimpleAuthManager` 免密 Admin 登录) | `http://<MASTER_IP>:38080` | | **Airflow Apiserver** | `38080` | Airflow 3 原生控制台与官方 API (已开启 `SimpleAuthManager` 免密 Admin 登录) | `http://<MASTER_IP>:38080` | | **Grafana** | `33000` | 时间序列数据监控与仪表盘可视化 (账号密码默认: `admin`/`admin`) | `http://<MASTER_IP>:33000` | | **Prometheus** | `39090` | 集群监控指标拉取服务器 | `http://<MASTER_IP>:39090` | | **Kibana** | `35601` | 集中式日志可视化中心 (直接在 Discover 页面选择 `airflow-*` 视图检索日志) | `http://<MASTER_IP>:35601` | | **Flower** | `35555` | Celery 集群状态监控面板 (**仅在执行 `make up-master` 时启动**) | `http://<MASTER_IP>:35555` | | **Flower** | `35555` | Celery 集群状态监控面板 | `http://<MASTER_IP>:35555` | | **Elasticsearch** | `39200` | 存储运行日志的底层搜索引擎 API | `http://<MASTER_IP>:39200` | | **PostgreSQL** | `35432` | 核心元数据库,存储 Airflow 数据及 API Gateway 的 `csst_task_records` 表 | `postgresql://<MASTER_IP>:35432` | | **Redis** | `36379` | Celery 消息队列中间件 | `redis://<MASTER_IP>:36379` | ### 计算节点 (Worker Node) 执行 `make up-worker ENV=<env>` 的机器: Worker 节点: * **不暴露核心业务端口**,仅暴露 `cAdvisor` (38081) 和 `Node Exporter` (通过 Host 网络) 供主节点拉取监控指标。 * Worker 节点只需通过 `*.env` 中的 `MASTER_IP` 环境变量,主动连接到主控节点的 Redis 和 Postgres 即可静默消费任务。 * Worker 节点只需通过 `system.env` 中的 `MASTER_IP` 环境变量,主动连接到主控节点的 Redis 和 Postgres 即可静默消费任务。 --- Loading @@ -231,10 +221,10 @@ make up-worker ENV=csu ## 故障排除 - 确保 Docker 正在运行 - 确保宿主机端口未被占用:`38080` (Airflow), `39200` (ES), `35601` (Kibana) - 若 Elasticsearch 启动失败 (Unhealthy),请查看权限问题,再次执行 `make fix-permission` 并 `docker compose restart elasticsearch` (或 `docker-compose restart elasticsearch`) - 确保宿主机端口未被占用:`38080` (Airflow), `39200` (ES), `35601` (Kibana) 等 - **Celery Worker 监控数据丢失**:如果在 Flower 面板看不到 Worker 或在 Task Portal 的 Workers 列表中为空,请确保在部署 Worker 的 `docker-compose` 里的 `${HOSTNAME}` 等变量配置了正确的双美元符(`$$`)转义,以免在宿主机上被提前解析。 - 若 Elasticsearch 启动失败 (Unhealthy),系统可能会存在权限问题,Ansible 脚本在执行时通常会自动修复(将 `es_data` 属主设为 50000)。如遇意外,可尝试手动执行 `sudo chown -R 50000:0 volumes/es_data` 并重启容器。 - 检查容器日志以了解错误: ```bash docker compose logs -f # 或者使用老版本:docker-compose logs -f ```