Airflow2.0使用KubernetesPodOperator出现TemplateNotFound错误求解
问题原因分析
这个错误是Airflow自身的Jinja模板渲染机制触发的,和你镜像内部的逻辑、是否使用宏没有任何关系,错误发生在Airflow调度任务的阶段,还没有到拉取镜像启动容器的步骤。
Airflow的KubernetesPodOperator的arguments属于默认开启Jinja模板渲染的字段,Airflow对模板字符串有个默认规则:如果字符串后缀属于默认模板扩展名列表(默认包含.json、.sql、.yaml、.py等),Airflow会把这个字符串当成模板文件的路径,尝试从DAG的模板搜索路径(一般是DAG文件所在目录及子目录)读取对应文件的内容进行渲染,而不是直接把字符串当成参数值传递。
你传入的参数f'args/{config["INPUT_DIR"]}/{task_id}.json'刚好以.json结尾,Airflow识别后尝试在本地DAG目录下找args/airflow2test/processing-pipeline.json这个文件,找不到就抛出了TemplateNotFound错误。
解决方法
- 方案1:重写Operator的模板字段列表,关闭
arguments的模板渲染
如果你不需要对arguments里的内容做任何Airflow Jinja模板渲染,可以在实例化KubernetesPodOperator时添加template_fields参数,移除arguments字段:
KubernetesPodOperator( namespace=commons.kubernetes_namespace, labels=commons.labels, image=f"myregistry.io/myimage:{config['IMAGE_TAG']}", arguments=[ "python", "run_module.py ", "-i", f'args/{config["INPUT_DIR"]}/{task_id}.json' ], name=dag_name + task_id, task_id=task_id, secrets=[secret_volume], # 重写模板字段,仅保留你需要渲染的字段,去掉arguments template_fields=['namespace', 'image', 'name', 'task_id'] )
- 方案2:用Jinja表达式拼接后缀,避免Airflow识别到
.json后缀
将.json后缀用Jinja字面量表达式拼接,让Airflow在做文件识别时不会匹配到.json后缀,渲染后仍能得到正确的路径:
arguments=[ "python", "run_module.py ", "-i", f'args/{config["INPUT_DIR"]}/{task_id}.{{{{ "json" }}}}' ]
- 方案3:修改DAG的模板扩展名列表,移除
.json
如果整个DAG都不需要把.json文件当成模板加载,可以在DAG定义的参数里修改templates_exts,去掉.json即可:
with DAG( dag_id='your_dag_id', default_args=default_args, schedule_interval=None, # 调整模板扩展名,移除.json templates_exts=['.sql', '.yaml', '.yml', '.py'] ) as dag: # 你的任务定义
内容的提问来源于stack exchange,提问作者salvob
相关产品推荐
相关产品推荐

