准备集中做一些事情

准备集中做一些事情

<think> 我们正在讨论Airflow通过SSHOperator连接目标服务器执行任务时,Airflow所在服务器和目标服务器各自需要完成的工作。根据引用[1]中提到的架构思维,我们需要明确两个服务器的职责边界。 关键点: 1. Airflow所在服务器(控制端):负责任务调度和连接管理 2. 目标服务器(执行端):负责接收并执行命令 根据SSH协议的工作机制,我们可以这样分解: ### Airflow所在服务器(控制端)职责 1. **身份认证**:使用私钥(如`id_rsa`)向目标服务器证明身份。注意:这里必须使用私钥文件,而不是公钥(引用[1]中已明确)[^1]。 2. **任务调度**:根据DAG定义,在指定时间触发SSH连接请求。 3. **连接建立**:通过SSH协议与目标服务器建立安全通道(包括TCP三次握手、密钥交换、加密通道建立等)。 4. **命令传输**:将需要执行的命令(如`bash script.sh`)通过安全通道发送至目标服务器。 5. **结果获取**:接收目标服务器返回的命令执行结果(标准输出、标准错误)和退出状态码。 6. **日志记录**:将执行结果和日志存入Airflow元数据库,供用户查看。 ### 目标服务器(执行端)职责 1. **身份验证**:检查Airflow控制端提供的公钥是否存在于目标用户的`~/.ssh/authorized_keys`文件中(引用[1]中强调公钥部署于此)[^1]。 2. **权限验证**:确认连接用户是否有权执行请求的命令(通过操作系统的权限控制)。 3. **命令执行**:在安全通道建立后,接收命令并在目标用户的上下文环境中执行(如通过`bash`解释器执行)。 4. **结果返回**:将命令执行的输出流(stdout/stderr)和退出状态码通过SSH通道返回给控制端。 5. **资源释放**:命令执行结束后,释放相关进程资源并关闭会话。 ### 安全配置要点(双方协作) | 步骤 | 控制端(Airflow服务器) | 目标服务器 | |------|-------------------------|------------| | 密钥准备 | 生成密钥对(`ssh-keygen`),私钥本地保存(如`/opt/airflow/.ssh/id_rsa`) | 将控制端公钥(`id_rsa.pub`内容)追加到目标用户的`~/.ssh/authorized_keys`文件 | | 权限设置 | 私钥文件权限设为`600`:`chmod 600 id_rsa` | `authorized_keys`文件权限设为`600`,`.ssh`目录权限设为`700` | | 连接测试 | 使用`ssh -i /path/to/private_key user@host`手动测试 | 检查`/var/log/auth.log`(Ubuntu)或`/var/log/secure`(CentOS)中的登录日志 | ### 典型错误场景分析 1. **控制端私钥权限过宽**: - 现象:连接失败,日志报错`Permissions 0644 for 'id_rsa' are too open`。 - 解决:`chmod 600 id_rsa`。 2. **目标服务器公钥未部署**: - 现象:认证失败,日志报错`Permission denied (publickey)`。 - 解决:检查`authorized_keys`文件是否存在且内容正确(注意换行符问题)。 3. **目录权限问题**: - 现象:SSH连接时忽略`.ssh`目录。 - 解决:确保目标服务器上用户主目录、`.ssh`目录、`authorized_keys`文件的权限正确(依次为`755`、`700`、`600`)。 ### 配置流程示例(以引用[1]为基准)[^1] 1. **控制端操作**(Airflow服务器): ```bash # 生成密钥对(若尚未生成) ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_airflow -N "" # 记录公钥路径 cat ~/.ssh/id_rsa_airflow.pub ``` 2. **目标服务器操作**: ```bash # 切换到目标用户(如airflow_user) su - airflow_user # 确保.ssh目录存在 mkdir -p ~/.ssh && chmod 700 ~/.ssh # 将控制端公钥写入authorized_keys echo "ssh-rsa AAAAB3NzaC1yc2E..." >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys ``` ### 在Airflow中的配置 - **Connection配置**: - Host:目标服务器IP - Username:目标服务器用户(如`airflow_user`) - Extra:`{"key_file": "/opt/airflow/.ssh/id_rsa_airflow"}` 通过以上步骤,Airflow即可安全地调度远程任务。这种分离设计(控制与执行分离)体现了引用[2]中提到的“存算分离”架构思想,提升了系统的灵活性和可维护性[^2]。 §§相关问题§§ 1. 如何为多台目标服务器配置不同的SSH密钥? 2. 目标服务器如何限制Airflow用户的命令执行权限(如仅允许运行特定脚本)? 3. Airflow SSHOperator执行失败时如何自动重试? 4. 如何加密存储Airflow中的SSH私钥以避免明文保存? 5. 目标服务器的SSH端口非标准(非22)时如何配置? </think>### Airflow 所在服务器与目标服务器的职责分工 以下从**控制流**(Airflow 服务器)和**执行流**(目标服务器)两个维度详细说明各自职责,结合引用[1]的架构思维和引用[4]的分层设计原则[^1][^4]: --- ### **一、Airflow 所在服务器(控制端)职责** 1. **任务调度与触发** - 解析 DAG 定义,按计划触发 SSH 任务 - 管理任务依赖关系(如 Task A 成功后再执行 SSH 任务) 2. **连接管理与认证** - 读取 SSH Connection 配置(包括 `key_file` 指向的**私钥文件**)[^1] - 建立 SSH 连接前验证私钥有效性(格式、权限等) - 发起 SSH 握手协议(如 Diffie-Hellman 密钥交换) 3. **命令编排与传输** - 通过 `SSHOperator` 发送待执行命令(如 `bash /scripts/etl.sh`) - 传输必要的辅助文件(通过 `SSHHook` 的 `put_file()` 方法) 4. **结果监控与处理** - 捕获目标服务器返回的: - 标准输出(`stdout`) - 标准错误(`stderr`) - 退出状态码(`exit_status`) - 根据状态码决定任务成功/失败(非 0 视为失败) - 将日志写入 Airflow 元数据库 --- ### **二、目标服务器(执行端)职责** 1. **身份验证** - 检查 Airflow 服务器公钥是否存在于 `~/.ssh/authorized_keys` 中 - 验证 SSH 握手过程中的签名(用公钥解密私钥生成的签名) 2. **命令执行与环境准备** - 在**目标用户上下文**中执行接收到的命令(如 `airflow_user`) - 确保执行环境满足要求(如 Python 版本、依赖库等) - 为命令分配临时资源(进程、内存等) 3. **权限控制** - 根据系统权限策略(如 `sudoers` 配置)限制操作范围 - 若需特权操作,需提前配置免密 sudo(如添加 `airflow_user ALL=(ALL) NOPASSWD: /path/to/script.sh`) 4. **结果返回** - 实时传输命令输出流(通过 SSH Channel) - 返回最终退出状态码(通过 `$?` 捕获) --- ### **三、双端协作流程示例** ```mermaid sequenceDiagram participant A as Airflow服务器 participant T as 目标服务器 A->>T: 1. 发起SSH连接请求(携带私钥签名) T->>A: 2. 发送随机质询码 A->>T: 3. 用私钥加密质询码后返回 T->>T: 4. 用authorized_keys公钥解密验证 T->>A: 5. 验证成功,建立加密通道 A->>T: 6. 发送命令: bash run_etl.sh T->>T: 7. 执行命令并捕获输出 T->>A: 8. 返回stdout/stderr/exit_code A->>A: 9. 记录日志并更新任务状态 ``` --- ### **四、关键配置对比表** | **配置项** | **Airflow 服务器** | **目标服务器** | |---------------------|----------------------------------------|-------------------------------------| | **密钥文件** | 存储私钥 (`id_rsa`) | 存储公钥 (`authorized_keys`) | | **权限要求** | 私钥权限 600 | `.ssh` 目录 700, `authorized_keys` 600 | | **网络配置** | 允许访问目标服务器的 SSH 端口(默认 22) | 防火墙放行 Airflow 服务器的 IP | | **用户环境** | 无需特殊配置 | 确保目标用户有脚本执行权限 | | **日志存储** | 在 Airflow 元数据库集中存储 | 本地生成临时日志(可选) | --- ### **五、常见问题定位技巧** 1. **连接失败** - 控制端检查:`ssh -vvv -i /path/to/private_key user@host` - 目标端检查:`tail -f /var/log/auth.log`(Ubuntu) 2. **权限不足** - 确保目标服务器脚本有可执行权限:`chmod +x /path/to/script.sh` - 检查 `sudo` 免密配置(如需特权命令) 3. **环境差异** - 在目标服务器预先验证命令:`sudo -u airflow_user bash /path/to/script.sh` > 如同引用[3]的案例启示:若忽略执行环境差异(如实验室 vs 工厂),即使模型完美也会失败[^3]。务必在目标服务器充分验证执行环境。 --- ### **六、最佳实践** 1. **最小权限原则** - 为目标服务器创建专属用户(如 `airflow_executor`) - 通过 `sudo` 精细控制可执行命令列表 2. **环境隔离** - 使用 Docker 容器执行命令(需目标服务器安装 Docker) - 或通过 `virtualenv` 隔离 Python 环境 3. **密钥轮转** - 定期更新密钥对(如每 90 天) - Airflow 中使用 `Variables` 动态管理密钥路径 如同引用[2]的架构演进思想:将控制与执行分离,正像“轻薄笔记本+云存储”模式提升系统灵活性[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值