Commit d062e3a7 authored by BO ZHANG's avatar BO ZHANG 🏀
Browse files

feat: 新增多环境部署支持与前端控制台

parent d393bb10
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -49,3 +49,6 @@ dist/
# Database
db.sqlite3
cookies.txt

# Tests
tests/
+163 −69
Original line number Diff line number Diff line
# csst-airflow
# Airflow 部署指南 (v3.0.5)

# installation
本指南描述如何使用官方 Apache Airflow 3.0.5 镜像部署 CSST Airflow 集群。当前架构包含了 CeleryExecutor、Redis、PostgreSQL,并深度集成了 **Elasticsearch + Kibana** 作为集中的日志采集与展示平台。

## 前提条件

- 已安装 Docker 和 Docker Compose
- Git
- Make
- Linux 环境(因涉及权限与路径映射)

## 架构升级说明

1. **DAG Factory 模式**: `dags/common/dag_factory.py` 提取了通用的 `DockerOperator` 逻辑,支持数十个流程快速接入。
2. **统一镜像仓库变量**: 引入了 `HARBOR` 环境变量控制镜像前缀,可根据部署环境自动切换仓库。
3. **远程日志收集**: 增加了 Elasticsearch (39200)、Kibana (35601) 和 Filebeat 容器,实现了任务日志的统一索引、可视化和快速检索。
4. **统一调度网关 (API Gateway)**: 针对 10 万级并发与异构 JSON 检索需求,新增了基于 FastAPI 和 Postgres JSONB 的轻量级高性能网关,屏蔽了 Airflow 的复杂 API 和鉴权逻辑。

## 部署步骤

本系统支持两种部署方式:**基于 Make 的单机/手动部署****基于 Ansible 的多节点自动化部署**

### 方式一:Ansible 多节点一键部署(推荐用于生产环境)

如果您需要在真实的集群(1个 Master 节点 + 多个 Worker 节点)上部署该系统,我们提供了开箱即用的 Ansible Playbooks。由于我们有多个不同的部署环境(如 `p368`, `csu`, `zjlab`),我们为每个环境准备了专属的 Ansible Inventory 文件。

#### 1. 准备工作
- 确保在执行机上已安装 `ansible`
- 确保执行机配置了到所有目标节点(Master & Workers)的 SSH 免密登录(具有 root 或 sudo 权限)。

#### 2. 配置环境对应的 Inventory 文件
根据您要部署的环境,编辑 `ansible/` 目录下对应的清单文件(例如 `inventory.csu.ini`):

```ini
[master]
# 替换为您的 Master 节点 IP
192.168.25.18 ansible_user=root

[worker]
# 添加您所有的 Worker 节点 IP
192.168.25.19 ansible_user=root
192.168.25.20 ansible_user=root

[all:vars]
# 这里已经预设好了对应的环境名称,无需修改
env_name=csu
# 远程服务器上的部署路径
deploy_dir=/opt/csst-airflow
```

#### 3. 配置环境变量
确保对应环境的 `.env` 文件(例如 `envs/.env.csu`)中的 `MASTER_IP` 配置正确,以便 Worker 节点能找到 Master 节点的服务。

#### 4. 一键部署集群
`docker-celery-3.0.5` 目录下执行(以 `csu` 环境为例):

```bash
# 1. 部署所有节点的基础组件与服务容器
ansible-playbook -i ansible/inventory.csu.ini ansible/deploy.yml

# 2. 同步 DAGs 代码到所有节点 (以后每次更新 DAGs 都可以单独执行此命令)
ansible-playbook -i ansible/inventory.csu.ini ansible/sync_dags.yml
```

---

### 方式二:基于 Make 的单机或手动部署

#### 1. 初始化目录与权限

```bash
git clone https://csst-tb.bao.ac.cn/code/csst-cicd/csst-airflow.git
cd csst-airflow/docker
vim .env
make mkdir
make up
make fix-permission
```
> **注意**: `fix-permission` 会使用 `sudo` 修复 Elasticsearch 数据目录的归属,以防启动时因无权写入数据而失败。

#### 2. 选择部署环境

本系统支持通过 Makefile 动态指定环境变量配置文件。您可以随时通过以下命令查看当前支持的所有环境模板:

```bash
make list-envs
```
*(系统将自动读取 `envs/` 目录下的 `.env.*` 文件后缀)*

# REST API

```shell
# 定义ENDPOINT_URL
ENDPOINT_URL="http://localhost:8080"
# 空间应用中心
ENDPOINT_URL="http://192.168.25.153:38080"
# 之江实验室
ENDPOINT_URL="http://10.200.60.244:38080"

# 获取token
TOKEN=$(curl -X POST "${ENDPOINT_URL}/auth/token" \
  -H "Content-Type: application/json" \
  -d '{"username":"csst", "password":"pipeline"}' | jq -r '.access_token')
echo $TOKEN

# 获取DAG列表
curl -X 'GET' \
  "${ENDPOINT_URL}/api/v2/dags" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json"
  
# 触发DAG(https://airflow.apache.org/docs/apache-airflow/stable/stable-rest-api-ref.html#operation/trigger_dag_run)
curl -X 'POST' \
  "${ENDPOINT_URL}/api/v2/dags/csst-msc-l1.conditional-trigger/dagRuns" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '
    {
      "dag_run_id": null,
      "logical_date": null,
      "conf": {
        "dag_group": "csst-msc-l1.conditional-trigger",
        "dags": [
          "csst-msc-l1-qc0",
          "csst-msc-l1-mbi",
          "csst-msc-l1-ast",
          "csst-msc-l1-sls"
        ],
        "dataset": "csst-msc-c9-25sqdeg-v3",
        "instrument": "MSC",
        "obs_type": "WIDE",
        "obs_group": "W2",
        "obs_id": "10100232366",
        "detector": "09",
        "prc_status": "",
        "qc_status": "",
        "pmapname": "csst_000094.pmap",
        "ref_cat": "trilegal_093",
        "batch_id": "__airflow_default_batch__",
        "priority": "1",
        "verbose": true,
        "submit": false,
        "force": false,
        "top_n": -1,
        "final_prc_status": -2
      },
      "note": null
    }
    '
  
# 更多API
https://airflow.apache.org/docs/apache-airflow/stable/stable-rest-api-ref.html
#### 3. 初始化 Airflow 数据库

在首次部署的**主控节点**上执行数据库初始化(假设您使用的是 `csu` 环境):

```bash
make init ENV=csu
```

#### 4. 启动核心服务

> **⚠️ 部署强烈建议**:
> 系统采用 Master/Worker 分离架构,主节点负责调度与监控网关,子节点负责计算。

##### 主控节点 (Master Node) 部署:
在作为 Master 的机器上执行,此命令会启动数据库、消息队列、API Gateway、Prometheus/Grafana 监控大盘以及 Airflow 控制平面:

```bash
make up-master ENV=csu
```

##### 计算节点 (Worker Node) 部署:
在提供算力的机器上执行,此命令**仅启动** Celery Worker 和该机器专属的日志采集与监控探针 (Filebeat / cAdvisor / Node Exporter):

```bash
make up-worker ENV=csu
```
> **提示**: 探针会自动启动,以供 Master 节点的 Prometheus 和 ES 抓取该 Worker 机器的资源与日志状态。

---

## Makefile 命令速查

| 命令 | 描述 |
|------|------|
| `make all` | **一键完整部署**:停止、拉取、建目录、修权限、初始化、启动 |
| `make mkdir` | 创建所有必需的挂载目录 |
| `make fix-permission` | 修复 `es_data` 目录的属主权限 (UID 1000) |
| `make copy-env-*` | 复制对应的预设环境变量文件 |
| `make init` | 初始化 Airflow 数据库 |
| `make up` | 启动核心调度器、API 网关与基础设施 (不含 Worker) |
| `make up-master` | 启动核心组件并附带开启 Flower 监控 |
| `make up-worker` | 启动 Celery Worker 以执行具体的 Task |
| `make down` | 停止所有服务 |
| `make clean` | 停止服务并清理容器 |
| `make ps` | 列出运行中的服务 |

## 访问服务与系统端口映射

在完整的分布式或单机部署中,各个组件所占用的宿主机端口如下。**请在部署前确保宿主机的这些防火墙端口已开放且未被占用**。

### 主控节点 (Master Node)
执行 `make up` 或 `make up-master` 的机器上将暴露以下核心服务端口:

| 服务组件 | 宿主机端口 | 用途说明 | 访问地址示例 |
| :--- | :--- | :--- | :--- |
| **API Gateway** | `38000` | **业务系统唯一对接入口**。提供高并发任务提交与基于 JSONB 的状态检索 | `http://<MASTER_IP>:38000` |
| **Airflow Web UI** | `38080` | Airflow 原生控制台与官方 API (账号密码默认: `airflow`/`airflow`) | `http://<MASTER_IP>:38080` |
| **Kibana** | `35601` | 集中式日志可视化中心 (直接在 Discover 页面选择 `airflow-*` 视图检索日志) | `http://<MASTER_IP>:35601` |
| **Flower** | `35555` | Celery 集群状态监控面板 (**仅在执行 `make up-master` 时启动**) | `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` 的机器:
*   **不暴露任何宿主机端口**。
*   Worker 节点只需通过 `.env` 中的 `MASTER_IP` 主动连接到主控节点的 Redis 和 Postgres 即可静默消费任务。

---

## DAG 任务的触发与状态查询
为了避免 Airflow 3 升级鉴权体系(强制 JWT)带来的对接复杂性,以及为了解决海量异构任务数据的检索问题,本系统**强力推荐业务方直接对接自定义的 API Gateway**。

外部系统仅需维护一个环境变量 `export AIRFLOW_API_GATEWAY=http://<MASTER_IP>:38000`,即可进行批量任务提交、JSONB 高性能状态检索等操作。

请查阅配套的 **[`api.md`](./api.md)** 获取完整的接口文档和 cURL 调用示例。

## 故障排除

- 确保 Docker 正在运行
- 确保宿主机端口未被占用:`38080` (Airflow), `39200` (ES), `35601` (Kibana)
- 若 Elasticsearch 启动失败 (Unhealthy),请查看权限问题,再次执行 `make fix-permission` 并 `docker compose restart elasticsearch`
- 检查容器日志以了解错误:
  ```bash
  docker compose logs -f
  ```
+0 −0

File moved.

+5 −0
Original line number Diff line number Diff line
FROM apache/airflow:3.0.5

# Install additional python dependencies required for our DAGs
# Specifically the docker provider which is heavily used by CSST DAG Factory
RUN pip install --no-cache-dir apache-airflow-providers-docker
+21 −19
Original line number Diff line number Diff line

# 默认环境(可被传入的 ENV 参数覆盖,例如 make up-master ENV=csu)
ENV ?= csu
ENV_FILE := envs/.env.$(ENV)

list-envs:
	@echo "Available environments (Usage: make up-master ENV=<name>):"
	@ls envs/.env.* 2>/dev/null | sed 's|envs/.env.||' | sed 's/^/  - /' || echo "  No environment files found."

all: down pull mkdir fix-permission init up

pull:
@@ -14,38 +22,32 @@ rmdir:
	rm -rf ./volumes

init:
	docker compose up airflow-init
	docker compose --env-file $(ENV_FILE) up airflow-init

up:
	docker compose up -d

up-master:
	docker compose -f docker-compose.yaml --env-file .env --profile flower up --force-recreate

up-worker:
	docker compose -f docker-compose.yaml --env-file .env up worker --force-recreate
	docker compose --env-file $(ENV_FILE) up -d

copy-env-csu:
	cp envs/.env.csu .env
check-env:
	@if [ ! -f $(ENV_FILE) ]; then echo "Error: Environment file $(ENV_FILE) does not exist!"; exit 1; fi

copy-env-p368:
	cp envs/.env.p368 .env
up-master: check-env
	docker compose -f docker-compose.yaml --env-file $(ENV_FILE) --profile flower --profile master up -d --force-recreate

copy-env-zjlab:
	cp envs/.env.zjlab .env
up-worker: check-env
	docker compose -f docker-compose.yaml --env-file $(ENV_FILE) --profile worker up -d --force-recreate

down:
	docker compose down
	docker compose --env-file $(ENV_FILE) down

migrate:
	docker compose run --rm airflow-init airflow db upgrade
	docker compose --env-file $(ENV_FILE) run --rm airflow-init airflow db upgrade

clean:
	# 停止服务并清理旧数据
	docker compose rm -sf
	docker compose --env-file $(ENV_FILE) rm -sf

ps:
	docker compose ps
	docker compose --env-file $(ENV_FILE) ps

restart:
	docker compose restart
	docker compose --env-file $(ENV_FILE) restart
Loading