Commit 06c9e940 authored by BO ZHANG's avatar BO ZHANG 🏀
Browse files

docs: 重构 README 并添加顶层 Makefile 以简化使用说明

parent 587870c6
Loading
Loading
Loading
Loading

Makefile

0 → 100644
+21 −0
Original line number Diff line number Diff line
# CSST Airflow repo-level convenience Makefile

SUBDIR ?= docker-celery-3.0.5

.PHONY: help list-envs pull build push clean all \
        ansible-deploy ansible-update ansible-down ansible-check ansible-sync-dags \
        viewer-test viewer-test-down update-code

help:
	@echo "Repo-level wrapper. Commands are executed in $(SUBDIR)/"
	@echo ""
	@echo "Common usage:"
	@echo "  make build IMAGE_TAG=test HARBOR_PROJECT=harbor.csst.nao:10443/csst/"
	@echo "  make ansible-update ENV=p368"
	@echo ""
	@$(MAKE) -C $(SUBDIR) help

list-envs pull build push clean all \
ansible-deploy ansible-update ansible-down ansible-check ansible-sync-dags \
viewer-test viewer-test-down update-code:
	@$(MAKE) -C $(SUBDIR) $@
+92 −181
Original line number Diff line number Diff line
# Airflow 部署指南 (v3.0.5)
# CSST Airflow (Apache Airflow 3.0.5)

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

## 前提条件
## 快速上手

- 已安装 Docker 和 Docker Compose
- **目标机器账号权限要求**:用于部署的执行账号(无论是手动执行 `make` 的当前用户,还是 Ansible Inventory 中的 `ansible_user`**必须具有免 `sudo` 执行 Docker 命令的权限**(即该用户已加入 `docker` 用户组),或者拥有完整的 `root/sudo` 权限。
- Git、Make、Ansible
- Linux 环境(因涉及权限与路径映射)

## 核心运维入口说明 (Operations Entry Points)
本系统将所有的日常运维操作抽象为了两个高度内聚的工具入口:
1. **`make`**:负责上游开发侧的镜像构建、重命名与交付入库(Push)。
2. **`ansible`**:负责下游实施侧的环境预检、配置分发与集群容器生命周期管理。

---

### 1. 镜像的构建与交付 (`make` 命令组)
本仓库约定:
- **构建/打包/推送镜像**使用 `make`
- **部署/升级/启停集群**使用 `make ansible-*`(内部调用 Ansible Playbook)

在有外网环境的机器或 CI/CD 系统中,通过 `make` 命令将业务自定义镜像和第三方依赖镜像全部构建并同步到私有 Harbor 镜像仓库。所有需要拉取的官方依赖镜像都显式地定义在根目录的 `required-images.txt` 中。

您可以随时在项目根目录运行 `make help` 查看说明:
```bash
make help
```
*(系统会自动打印出即将处理的全部 12 个镜像列表,包含 postgres、redis 等 9 个第三方镜像,以及 airflow、api-gateway 等 3 个自建镜像。)*

#### 常用构建命令
为了简化操作,建议在执行 `make` 之前,**先在终端导出目标环境变量**,后续的所有 `make` 命令都可以直接复用这些变量而无需每次指定:

```bash
# 【方案一:常规部署环境,如 p368】
# 设置部署环境名称 (例如 p368)
# 0) 建议:先一次性设定环境变量(后续命令更简洁)
export ENV=p368
# 设置镜像推送的 Harbor 仓库地址前缀 (必须以斜杠结尾)
export HARBOR_PROJECT=harbor.csst.nao:10443/csst/
# 设置构建镜像的版本号
export IMAGE_TAG=test
# 设置内部构建号 (将展示在 Portal 前端),如果不设置将默认使用 IMAGE_TAG 的值
export BUILD_NUMBER=test

# ----------------------------------------
# 【方案二:本地单机开发测试环境】
# 如果是本地开发机直接打包运行,不需要推送到远端 Harbor,可留空
export ENV=local
export HARBOR_PROJECT=
export IMAGE_TAG=latest
export BUILD_NUMBER=dev
```

配置好环境变量后,您可以执行以下精简命令:

```bash
# 1. 仅拉取外部依赖
# 从 required-images.txt 清单中拉取 13 个基础和组件依赖镜像(自动跳过已存在的)
make pull
export BUILD_NUMBER=100000
export HARBOR_PROJECT=harbor.csst.nao:10443/csst/

# 2. 仅构建 (不推送到私有仓库)
# 基于依赖镜像构建业务镜像,并将所有镜像重命名为统一样式 (例如 harbor.../csst-airflow:v0.0.0)
# 1) 构建镜像
make build

# 3. 仅推送
# 将已打好 Tag 的全量 16 个镜像推送到远端 Harbor
make push

# 4. 一键完成全套交付 (最常用)
# 依次执行清理旧镜像、拉取依赖、构建业务镜像到全量推送,一气呵成
make all
# 2) 更新集群(等价于 ansible-playbook ansible/update.yml ...)
make ansible-update
```
*(在构建和推送过程中,终端会以 `[BUILD/TAG] Processing Postgres...` 或 `[PUSH] Pushing harbor.csst.nao...` 的形式清晰打印当前进度。)*

---
提示:仓库根目录的 `Makefile` 是 wrapper,默认转发到 `docker-celery-3.0.5/` 目录执行。如果未来目录变更,可通过 `SUBDIR=...` 指定。

### 2. 自动化部署与启停 (`ansible` 命令组)
## 前置条件

本系统**唯一推荐**的部署方式为基于 Ansible 的一键部署。所有多环境(如 `p368`, `csu`, `zjlab`)的配置都已严格隔离在 `deploy_configs/<env>/` 目录下。
- Docker、Docker Compose
- Git、Make、Ansible
- Linux 环境(涉及权限与路径映射)
- 目标机器执行账号需要具备 Docker 权限(加入 `docker` 用户组或具备 sudo/root)

为了简化操作,建议在执行部署前,**先在终端导出目标环境名称变量**,后续的所有 Ansible 命令都可以直接复用该变量:
## 仓库结构

```bash
# 例如要部署 p368 环境,只需执行一次:
export ENV=p368
```
- `docker-celery-3.0.5/`:主部署目录(镜像构建、Compose、Ansible Playbooks)
- `docker-celery-3.0.5/required-images.txt`:第三方依赖镜像清单
- `docker-celery-3.0.5/deploy_configs/<env>/`:多环境配置目录(inventory、variables、connections 等)
- `docker-celery-3.0.5/api_gateway/`:FastAPI API Gateway(见其 README)
- `docker-celery-3.0.5/frontend_vue/`:Task Portal 前端(见其 README)

目前为您内置了 5 个不同场景的自动化剧本(Playbook),设置好变量后即可运行:
## 镜像构建与推送

#### ① 部署前环境预检 (`check.yml`)
在正式部署前,验证网络连通性及基础环境是否齐备。它会自动 ping 所有节点、检查 Docker 和 Compose 插件是否安装,并校验目标机器的部署路径与磁盘剩余空间:
```bash
ansible-playbook ansible/check.yml -i deploy_configs/${ENV}/inventory.ini
```
第三方镜像来源于 `required-images.txt`,业务自定义镜像包含:
- `csst-airflow`
- `csst-airflow-api-gateway`
- `csst-airflow-task-portal`
- `csst-airflow-js9`

#### ② 首次部署或全量更新部署 (`deploy.yml` 或 `playbook.yml`)
自动分发环境配置、解析变量、拉取最新镜像(支持 fallback 到本地镜像),并从零拉起所有 Master 和 Worker 节点的容器集群:
```bash
ansible-playbook ansible/deploy.yml -i deploy_configs/${ENV}/inventory.ini
```
常用命令(在仓库根目录执行即可):

#### ③ 软件升级与全量重启 (`update.yml`)
当修改了 `docker-compose.yaml` 或者是更新了镜像版本后,此命令会优雅地下线旧容器,拉取最新配置并启动新容器。特别是结合 `make build` 之后,利用此剧本能完美重启集群并应用新镜像:
```bash
ansible-playbook ansible/update.yml -i deploy_configs/${ENV}/inventory.ini
```
export IMAGE_TAG=test
export BUILD_NUMBER=100000
export HARBOR_PROJECT=harbor.csst.nao:10443/csst/

#### ④ 业务代码轻量更新 (`sync_dags.yml`)
如果只修改了 `dags/` 目录下的 Python 脚本,无需全量重启容器,直接执行轻量级同步即可将脚本分发给所有节点:
```bash
ansible-playbook ansible/sync_dags.yml -i deploy_configs/${ENV}/inventory.ini
make help
make pull
make build
make push
make all
```

#### ⑤ 停止与卸载服务 (`down.yml`)
完全停止并移除所有节点上的服务(等价于在所有机器上批量执行 `docker compose down`):
```bash
ansible-playbook ansible/down.yml -i deploy_configs/${ENV}/inventory.ini
```
## Ansible 部署与运维

---
已封装为 Make targets(推荐方式):

## 配置环境参数 (部署前的必要准备)
在为一个新的环境(例如 `p368`)进行部署前,您必须了解 `deploy_configs/` 目录下的 **4 份**配置文件的作用:
```bash
make list-envs

### 一、全局静态配置 (通常无需修改)
export ENV=p368

#### ① `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
make ansible-check
make ansible-deploy
make ansible-update
make ansible-sync-dags
make ansible-down
```

### 二、环境特异性配置 (每个环境独立维护)

#### ② `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 通信。

```ini
[master]
p368-master ansible_host=127.0.0.1 ansible_connection=local
说明:
- `make pull` 只负责从 `required-images.txt` 拉取第三方镜像,不依赖 `IMAGE_TAG/BUILD_NUMBER/HARBOR_PROJECT`
- `make push` 只负责把已有 tag 的镜像推送到仓库,不依赖 `BUILD_NUMBER`
- `make ansible-*` 主要依赖 `ENV` 选择 inventory;镜像来源与 tag 由 `deploy_configs/<env>/inventory.ini` 中的 `harbor_project/image_tag` 控制。

[worker]
p368-worker1 ansible_host=127.0.0.1 ansible_connection=local
底层执行的命令形式为:

[all:vars]
env=p368
deploy_dir=/opt/csst-airflow
```bash
ansible-playbook -i deploy_configs/<env>/inventory.ini ansible/<playbook>.yml -e env=<env>
```

# 镜像仓库前缀 (以斜杠结尾)
harbor_project=harbor.csst.nao:10443/csst/
image_tag=test
## 环境配置文件

# API Gateway 与 Airflow Apiserver 通信所用的 JWT 密钥
jwt_secret=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVC...
```
所有环境配置位于 `docker-celery-3.0.5/deploy_configs/`

#### ③ `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"
```
1) `deploy_configs/airflow.env`(必需,全环境共享)
- 存放 Airflow 容器基础静态配置(如 `AIRFLOW_UID`)。

#### ④ `deploy_configs/<env>/connections.json` (可选:定义 Airflow 加密连接)
如果需要预置 Airflow 的连接配置,可将其存放在这里,Ansible 部署时会自动将这些配置导入到 Airflow 的 DB 中
2) `deploy_configs/<env>/inventory.ini`(必需)
- 定义部署拓扑(master/worker)、SSH 连接与关键变量(如 `deploy_dir``harbor_project``image_tag``jwt_secret`

> **💡 容错机制说明 (Local Fallback)**:
> 部署脚本在启动容器前会执行 `docker compose pull` 从 Harbor 拉取镜像。如果当前环境无法连接外网/Harbor,只要该节点上预先 `make build` 过本地镜像,`pull` 失败的报错会被自动忽略并直接使用本地镜像启动服务
3) `deploy_configs/<env>/variables.toml`(可选)
- 业务级变量导入(DFS/CCDS/OSS 等)

## 访问服务与系统端口映射
4) `deploy_configs/<env>/connections.json`(可选)
- Airflow Connections 预置。

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

### 主控节点 (Master Node)
执行 Ansible 部署后,主节点机器上将暴露以下核心服务端口:
主控节点(Master)常见端口:

| 服务组件 | 宿主机端口 | 用途说明 | 访问地址示例 |
| :--- | :--- | :--- | :--- |
| **Task Portal** | `38501` | **统一任务与监控控制台**。提供带进度预估的 JSON 筛选及 Grafana 资源大盘内嵌页 | `http://<MASTER_IP>:38501` |
| **API Gateway** | `38000` | **业务系统唯一对接入口**。提供高并发任务提交、任务控制(取消/重试)与状态检索 | `http://<MASTER_IP>:38000` |
| **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 集群状态监控面板 | `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` |
| 服务组件 | 宿主机端口 | 访问示例 |
| :--- | :--- | :--- |
| Task Portal | `38501` | `http://<MASTER_IP>:38501` |
| API Gateway | `38000` | `http://<MASTER_IP>:38000` |
| Airflow Apiserver | `38080` | `http://<MASTER_IP>:38080` |
| Grafana | `33000` | `http://<MASTER_IP>:33000` |
| Prometheus | `39090` | `http://<MASTER_IP>:39090` |
| Kibana | `35601` | `http://<MASTER_IP>:35601` |
| Flower | `35555` | `http://<MASTER_IP>:35555` |
| Elasticsearch | `39200` | `http://<MASTER_IP>:39200` |
| PostgreSQL | `35432` | `postgresql://<MASTER_IP>:35432` |
| Redis | `36379` | `redis://<MASTER_IP>:36379` |

### 计算节点 (Worker Node)
Worker 节点:
*   **不暴露核心业务端口**,仅暴露 `cAdvisor` (38081) 和 `Node Exporter` (通过 Host 网络) 供主节点拉取监控指标。
*   Worker 节点只需通过 `system.env` 中的 `MASTER_IP` 环境变量,主动连接到主控节点的 Redis 和 Postgres 即可静默消费任务。
Worker 节点通常不暴露核心业务端口,仅暴露监控相关端口供 Master 拉取。

---
## 对外接口

## DAG 任务的触发与状态查询
为了避免 Airflow 3 升级鉴权体系(强制 JWT)带来的对接复杂性,以及为了解决海量异构任务数据的检索问题,本系统**强力推荐业务方直接对接自定义的 API Gateway**
推荐业务方直接对接 API Gateway(避免 Airflow 侧鉴权变化带来的耦合,同时提供 JSONB 查询与批量触发能力)。接口与示例见 [api.md](file:///home/cham/PycharmProjects/csst-airflow/api.md)

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

请查阅配套的 **[`api.md`](./api.md)** 获取完整的接口文档和 cURL 调用示例。
- API Gateway:`docker-celery-3.0.5/api_gateway/README.md`
- Portal 前端:`docker-celery-3.0.5/frontend_vue/README.md`

## 故障排除

- 确保 Docker 正在运行
- 确保宿主机端口未被占用:`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 权限:确保执行用户已加入 `docker` 组或具备 sudo/root。
- 端口冲突:检查 `38501/38000/38080/33000/35601/35555/39200/35432/36379/39090` 是否被占用。
- Worker 不显示:优先检查部署环境变量与 worker 启动参数是否正确;必要时执行 `make ansible-update ENV=<env>` 触发重启发现。
- ES Unhealthy:常见为数据卷权限问题,可尝试修复 `volumes/es_data` 的属主权限后重启相关容器。
- 查看日志:在部署目录执行 `docker compose logs -f`