CDE 는 DAG 파일을 Job 에 묶어 관리하므로 Airflow UI 에서 DAG 를 지워도 Job 이 남아 있으면 dag_dir_list_interval 주기마다 다시 나타난다. 삭제는 Job 부터 한다.
cde job delete --name <job-name>
cde resource delete-file --name <resource-name> --resource-file <dag-filename.py>
cde resource delete --name <resource-name>
cde airflow delete-dag --dag-id <dag-id> # Job 과 연결이 끊긴 고아 DAG 만
순서는 Job 삭제 → 연결된 Resource(파일) 삭제 → 그래도 남으면 cde airflow delete-dag 다.
오픈소스 Airflow 의 Variable · Connection UI 는 CDE 에서 제한된다. 여러 Job 이 공유할 값은 Airflow Variable(UI 에서 등록 가능한 범위) 이나 DAG inline code 상단 상수로 두고, 민감 정보는 Airflow Connection 에 넣어 BaseHook.get_connection() 으로 읽는다.
Spark Job Pod 에서 호스트의 NAS 마운트 경로에 바로 쓰는 것은 CDE 가 임의 볼륨 마운트를 열어 주지 않아 사실상 불가능하다. 볼륨 타입별 요건은 다음과 같다.
| 볼륨 타입 | 노드 요건 |
|---|---|
| hostPath | Pod 이 배치될 수 있는 모든 워커 노드에 같은 경로로 NAS 가 마운트돼 있어야 한다 |
| NFS (Kubernetes 네이티브) | 노드에 NFS 클라이언트만 있으면 된다. Kubernetes 가 직접 NFS 서버에 붙는다 |
| PVC (NFS 백엔드) | provisioner 가 있으면 자동 처리 |
현실적인 대안은 두 가지다.
[CDE Spark Job] → HDFS 에 write
↓
[edge 노드의 cron] → hdfs dfs -get 으로 받아 NAS 경로에 저장
CDE 쪽은 추가 설정이 없다. 주의할 점은 Spark Job 완료 시점과 cron 타이밍 동기화(_SUCCESS 파일 확인 등)와, HDFS 에 접근 가능하면서 NAS 가 마운트된 게이트웨이 노드가 있어야 한다는 것이다.
Spark 드라이버에서 paramiko 로 NAS 가 마운트된 서버에 SFTP 전송하는 방법도 있다. python-env Resource 의 requirements.txt 에 paramiko 를 넣고, SSH 키는 Resource 로 올려 /app/mount/keys/ 에서 읽는다. 다만 CDE Pod → edge 노드 SSH 통신이 네트워크 정책상 열리는지 먼저 확인해야 한다.
result = spark.sql("SELECT * FROM my_table WHERE part_ymd = '20260401'")
result.coalesce(1).write.mode("overwrite").option("header", "true").csv("hdfs:///tmp/my_output")
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='nas-gateway-host', username='svc_account', key_filename='/app/mount/keys/id_rsa')
sftp = ssh.open_sftp()