Provisioning, Airflow

Jeonghak Cho·2025년 3월 10일

Provisioning

목록 보기
9/44

Airflow 개요

Apache Airflow는 워크플로우 자동화 및 배치 처리를 위한 오픈소스 도구이다. DAG(Directed Acyclic Graph)를 기반으로 워크플로우를 정의하고, 실행 상태를 모니터링하며, 복잡한 데이터 파이프라인을 손쉽게 관리할 수 있도록 도와준다.

어느때 사용할까

  • 복잡한 배치 및 데이터 파이프라인을 운영해야 할 때
  • 워크플로우 간 의존성을 체계적으로 관리하고 싶을 때
  • 실패한 작업을 자동으로 재시도하고, 모니터링 및 알림 기능이 필요할 때
  • 클라우드 및 다양한 데이터 소스와 쉽게 연동하고 싶을 때

구성 요소

구성 요소설명
DAG (Workflow)Task들의 실행 순서를 정의하는 그래프
Operator개별 작업을 정의하는 단위 (ex: BashOperator, PythonOperator, SQLOperator 등)
TaskDAG 내에서 실행되는 개별 작업
SchedulerDAG 실행을 스케줄링하고 Task를 트리거하는 역할
ExecutorTask 실행을 담당하는 엔진 (LocalExecutor, CeleryExecutor, KubernetesExecutor 등)
Web UIDAG 및 Task 상태를 모니터링할 수 있는 웹 기반 대시보드

일반 버전과 Slim 버전 차이

Apache Airflow의 공식 Docker 이미지에는 일반 버전(Full)과 Slim 버전이 있다. 기본적으로 포함된 패키지의 수와 이미지 크기에서 차이가 난다. Airflow를 처음 사용하거나 빠르게 테스트하고 싶을 때나
대부분의 기능을 바로 사용하고 싶을 때 일반 버전을 사용한다. 운영 환경에서 불필요한 패키지를 줄이고, 보안 이슈로 최소한의 패키지만 포함한 최적화된 환경을 구성할 때 slim 버전을 사용한다.

메타 데이터 베이스

SQLite (별도 설치 불필요)

Airflow는 기본적으로 SQLite를 사용하며, 로컬 테스트 용도로만 적합하다. airflow.cfg에서 sql_alchemy_conn = sqlite:////path/to/airflow.db와 같은 설정이 기본값이다.
SQLite는 단일 프로세스에서만 안정적으로 동작하며, 여러 개의 Airflow 서비스(Pod, Container)와 공유할 수 없다. 운영 환경에서는 다중 인스턴스 지원을 위해 PostgreSQL 또는 MySQL을 사용해야 한다.

PostgreSQL (운영 환경)

프로덕션 환경에서는 PostgreSQL 또는 MySQL을 사용해야 한다. PostgreSQL을 사용하려면 직접 설치하고 설정해야 한다.

쿠버네티스 크롭잡과 Airflow 비교

쿠버네티스 크론잡

장점

  • 간단한 배치 작업: 특정 시간에 실행해야 하는 단순한 작업(Cron 스케줄 기반) 처리에 적합함.
  • 쿠버네티스 네이티브: 이미 쿠버네티스를 사용하고 있다면 별도의 추가 설정 없이 적용 가능.
  • 경량화: Airflow 대비 리소스 소모가 적으며, 복잡한 워크플로우 관리가 필요하지 않은 경우 적합함.
    자원 자동 관리: Job이 완료되면 Pod이 자동으로 제거됨(설정 가능).

단점

  • 복잡한 워크플로우 관리 어려움: 여러 개의 잡(Job) 간 의존성이 있는 경우 수동으로 관리해야 하므로 확장성이 떨어짐.
  • 모니터링 기능 부족: 실패한 잡의 재시도 정책이 제한적이고, 실행 이력이나 디버깅이 어렵다.
  • UI 부족: 실행 상태를 시각적으로 확인하기 어려움.

Apache Airflow

장점

  • 워크플로우 관리 최적화: DAG(Directed Acyclic Graph)로 여러 개의 작업을 정의하고, 작업 간 의존성을 쉽게 설정할 수 있음.
  • UI 제공: 웹 기반 UI에서 배치 실행 상태를 모니터링하고, 실패한 태스크를 재실행할 수 있음.
  • 강력한 리트라이 및 모니터링 기능: 실패한 작업을 자동으로 재시도하고, Slack이나 이메일로 알림을 보낼 수 있음.
  • 다양한 연동 기능: 데이터베이스, 클라우드 서비스(GCP, AWS 등)와의 통합이 쉬움.

단점

  • 설치 및 유지보수 필요: Airflow를 실행하기 위한 별도의 인프라(Executor, Scheduler 등)를 관리해야 함.
  • 리소스 소비 많음: Airflow 자체가 실행되면서 CPU 및 메모리를 사용하므로, 단순한 작업에는 과할 수 있음.
  • 학습 곡선이 있음: DAG 및 Airflow 개념을 익히는 데 시간이 필요함.

배치 도구 소개

도구특징적합한 경우
Argo WorkflowsDAG 기반 Kubernetes 워크플로우, UI 제공Kubernetes에서 복잡한 배치를 운영하고 싶은 경우
PrefectPython 코드 기반, Airflow보다 가벼움개발 친화적인 워크플로우 관리가 필요한 경우
KubeCronCronJob 개선, 모니터링/재시도 기능 제공기존 CronJob을 유지하면서 기능을 확장하고 싶은 경우
KestraYAML 기반 설정, UI 제공간편하게 Kubernetes 배치를 운영하고 싶은 경우

설치 (약식)

운영환경에는 Helm 사용을 통해 PostgreSql 등으로 메타 데이터베이스를 교체하고, REDIS 사용을 추천한다. 아래는 Airflow 테스트를 위해 약식 설치 방식이다.

kubectl create namespace airflow
kubectl apply -f airflow-deploy.yml
kubectl apply -f airflow-svc.yml

airflow-svc.yml

apiVersion: v1
kind: Service
metadata:
  name: airflow
  namespace: airflow
spec:
  selector:
    app: airflow
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
  type: NodePort

airflow-deploy.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: airflow
  namespace: airflow
spec:
  replicas: 1  # SQLite는 1개 Replica만 가능
  selector:
    matchLabels:
      app: airflow
  template:
    metadata:
      labels:
        app: airflow
    spec:
      securityContext:
        fsGroup: 50000
      containers:
        - name: airflow
          image: apache/airflow:latest
          securityContext:
            runAsUser: 50000
          imagePullPolicy: IfNotPresent
          env:
            - name: AIRFLOW__CORE__EXECUTOR
              value: "SequentialExecutor"
            - name: AIRFLOW__DATABASE__SQL_ALCHEMY_CONN
              value: "sqlite:////opt/airflow/airflow.db"
          volumeMounts:
            - name: airflow-data
              mountPath: /opt/airflow
          command: ["bash", "-c"]
          args:
            - |
              airflow db init &&
              airflow users create --username admin --password admin --firstname Admin --lastname User --role Admin --email admin@example.com &&
              airflow webserver && 
              airflow scheduler
      volumes:
        - name: airflow-data
          persistentVolumeClaim:
            claimName: mypvc

웹콘솔

vagrant@slave2:~$ k get svc -n airflow
NAME      TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
airflow   NodePort   10.98.56.159   <none>        8080:30838/TCP   16m

웹콘솔은 위의 노드포트를 통해 접속 가능하다. 기본 계정은 admin/admin 이다.

AIRFLOW 버전 확인

vagrant@slave2:~$ k exec airflow-6bf7b46c79-scvks -n airflow  -- airflow version
2.10.5

DAG 저장 위치 확인

airflow@airflow-6bf7b46c79-scvks:/opt/airflow$ airflow config get-value core dags_folder
/opt/airflow/dags

DAG 목록 조회

airflow@airflow-6bf7b46c79-scvks:/opt/airflow$ airflow dags list
dag_id | fileloc | owners | is_paused
==========+========================+=========+==========
hello_dag | /opt/airflow/dags/h.py | airflow | True

DAG 정보 조회

airflow@airflow-5db85d78ff-x8tqw:/opt/airflow/dags$ airflow dags show hello_dag
[2025-03-10T11:02:49.242+0000] {dagbag.py:588} INFO - Filling up the DagBag from /opt/airflow/dags
digraph hello_dag {
        graph [label=hello_dag labelloc=t rankdir=LR]
        print_date [color="#000000" fillcolor="#f0ede4" label=print_date shape=rectangle style="filled,rounded"]
        print_hello [color="#000000" fillcolor="#f0ede4" label=print_hello shape=rectangle style="filled,rounded"]
        print_date -> print_hello
}

DAG 생성 로그 추적

airflow@airflow-5db85d78ff-x8tqw:/opt/airflow/dags$ cat $AIRFLOW_HOME/logs/scheduler/latest/*.log | grep "DAG"
[2025-03-10T11:01:25.045+0000] {processor.py:925} INFO - DAG(s) 'hello_dag' retrieved from /opt/airflow/dags/h.py
[2025-03-10T11:01:25.138+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.137+0000] {override.py:1912} INFO - Created Permission View: can read on DAG:hello_dag
[2025-03-10T11:01:25.150+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.150+0000] {override.py:1912} INFO - Created Permission View: can edit on DAG:hello_dag
[2025-03-10T11:01:25.159+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.158+0000] {override.py:1912} INFO - Created Permission View: can delete on DAG:hello_dag
[2025-03-10T11:01:25.174+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.174+0000] {override.py:1912} INFO - Created Permission View: can read on DAG Run:hello_dag
[2025-03-10T11:01:25.184+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.183+0000] {override.py:1912} INFO - Created Permission View: menu access on DAG Run:hello_dag
[2025-03-10T11:01:25.192+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.192+0000] {override.py:1912} INFO - Created Permission View: can create on DAG Run:hello_dag
[2025-03-10T11:01:25.202+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.202+0000] {override.py:1912} INFO - Created Permission View: can delete on DAG Run:hello_dag
[2025-03-10T11:01:25.202+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.202+0000] {dag.py:3239} INFO - Sync 1 DAGs
[2025-03-10T11:01:25.211+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.211+0000] {dag.py:3262} INFO - Creating ORM DAG for hello_dag
[2025-03-10T11:01:56.055+0000] {processor.py:925} INFO - DAG(s) 'hello_dag' retrieved from /opt/airflow/dags/h.py
[2025-03-10T11:01:56.073+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:56.072+0000] {dag.py:3239} INFO - Sync 1 DAGs
[2025-03-10T11:02:27.136+0000] {processor.py:925} INFO - DAG(s) 'hello_dag' retrieved from /opt/airflow/dags/h.py
[2025-03-10T11:02:27.150+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:02:27.150+0000] {dag.py:3239} INFO - Sync 1 DAGs
[2025-03-10T11:02:58.040+0000] {processor.py:925} INFO - DAG(s) 'hello_dag' retrieved from /opt/airflow/dags/h.py
[2025-03-10T11:02:58.057+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:02:58.057+0000] {dag.py:3239} INFO - Sync 1 DAGs

DAG 소스 작성

h.py

from airflow import DAG
from airflow.operators.bash import BashOperator
from datetime import datetime, timedelta

default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'start_date': datetime(2024, 6, 29),
    'email_on_failure': False,
    'email_on_retry': False,
    'retries': 1,
    'retry_delay': timedelta(minutes=5),
}

dag = DAG(
    'hello_dag',
    default_args=default_args,
    description='Hello DAG',
    schedule_interval=timedelta(days=1),
)

task1 = BashOperator(
    task_id='print_date',
    bash_command='date',
    dag=dag,
)

task2 = BashOperator(
    task_id='print_hello',
    bash_command='echo "Hello World"',
    dag=dag,
)

task1 >> task2 

DAG 소스 AIRFLOW 복사

vagrant@slave2:~$ k get po -n airflow
NAME                       READY   STATUS    RESTARTS      AGE
airflow-6bf7b46c79-scvks   1/1     Running   1 (33m ago)   26h

kubectl cp hello.py airflow-6bf7b46c79-scvks:/opt/airflow/dags -n airflow

AIRFLOW 결과

위에서 복사한 DAG가 웹콘솔에 나타나는 것을 확인한다.

Airflow 개요

Apache Airflow는 워크플로우 자동화 및 배치 처리를 위한 오픈소스 도구이다. DAG(Directed Acyclic Graph)를 기반으로 워크플로우를 정의하고, 실행 상태를 모니터링하며, 복잡한 데이터 파이프라인을 손쉽게 관리할 수 있도록 도와준다.

어느때 사용할까

  • 복잡한 배치 및 데이터 파이프라인을 운영해야 할 때
  • 워크플로우 간 의존성을 체계적으로 관리하고 싶을 때
  • 실패한 작업을 자동으로 재시도하고, 모니터링 및 알림 기능이 필요할 때
  • 클라우드 및 다양한 데이터 소스와 쉽게 연동하고 싶을 때

구성 요소

구성 요소설명
DAG (Workflow)Task들의 실행 순서를 정의하는 그래프
Operator개별 작업을 정의하는 단위 (ex: BashOperator, PythonOperator, SQLOperator 등)
TaskDAG 내에서 실행되는 개별 작업
SchedulerDAG 실행을 스케줄링하고 Task를 트리거하는 역할
ExecutorTask 실행을 담당하는 엔진 (LocalExecutor, CeleryExecutor, KubernetesExecutor 등)
Web UIDAG 및 Task 상태를 모니터링할 수 있는 웹 기반 대시보드

일반 버전과 Slim 버전 차이

Apache Airflow의 공식 Docker 이미지에는 일반 버전(Full)과 Slim 버전이 있다. 기본적으로 포함된 패키지의 수와 이미지 크기에서 차이가 난다. Airflow를 처음 사용하거나 빠르게 테스트하고 싶을 때나
대부분의 기능을 바로 사용하고 싶을 때 일반 버전을 사용한다. 운영 환경에서 불필요한 패키지를 줄이고, 보안 이슈로 최소한의 패키지만 포함한 최적화된 환경을 구성할 때 slim 버전을 사용한다.

메타 데이터 베이스

SQLite (별도 설치 불필요)

Airflow는 기본적으로 SQLite를 사용하며, 로컬 테스트 용도로만 적합하다. airflow.cfg에서 sql_alchemy_conn = sqlite:////path/to/airflow.db와 같은 설정이 기본값이다.
SQLite는 단일 프로세스에서만 안정적으로 동작하며, 여러 개의 Airflow 서비스(Pod, Container)와 공유할 수 없다. 운영 환경에서는 다중 인스턴스 지원을 위해 PostgreSQL 또는 MySQL을 사용해야 한다.

PostgreSQL (운영 환경)

프로덕션 환경에서는 PostgreSQL 또는 MySQL을 사용해야 한다. PostgreSQL을 사용하려면 직접 설치하고 설정해야 한다.

쿠버네티스 크롭잡과 Airflow 비교

쿠버네티스 크론잡

장점

  • 간단한 배치 작업: 특정 시간에 실행해야 하는 단순한 작업(Cron 스케줄 기반) 처리에 적합함.
  • 쿠버네티스 네이티브: 이미 쿠버네티스를 사용하고 있다면 별도의 추가 설정 없이 적용 가능.
  • 경량화: Airflow 대비 리소스 소모가 적으며, 복잡한 워크플로우 관리가 필요하지 않은 경우 적합함.
    자원 자동 관리: Job이 완료되면 Pod이 자동으로 제거됨(설정 가능).

단점

  • 복잡한 워크플로우 관리 어려움: 여러 개의 잡(Job) 간 의존성이 있는 경우 수동으로 관리해야 하므로 확장성이 떨어짐.
  • 모니터링 기능 부족: 실패한 잡의 재시도 정책이 제한적이고, 실행 이력이나 디버깅이 어렵다.
  • UI 부족: 실행 상태를 시각적으로 확인하기 어려움.

Apache Airflow

장점

  • 워크플로우 관리 최적화: DAG(Directed Acyclic Graph)로 여러 개의 작업을 정의하고, 작업 간 의존성을 쉽게 설정할 수 있음.
  • UI 제공: 웹 기반 UI에서 배치 실행 상태를 모니터링하고, 실패한 태스크를 재실행할 수 있음.
  • 강력한 리트라이 및 모니터링 기능: 실패한 작업을 자동으로 재시도하고, Slack이나 이메일로 알림을 보낼 수 있음.
  • 다양한 연동 기능: 데이터베이스, 클라우드 서비스(GCP, AWS 등)와의 통합이 쉬움.

단점

  • 설치 및 유지보수 필요: Airflow를 실행하기 위한 별도의 인프라(Executor, Scheduler 등)를 관리해야 함.
  • 리소스 소비 많음: Airflow 자체가 실행되면서 CPU 및 메모리를 사용하므로, 단순한 작업에는 과할 수 있음.
  • 학습 곡선이 있음: DAG 및 Airflow 개념을 익히는 데 시간이 필요함.

배치 도구 소개

도구특징적합한 경우
Argo WorkflowsDAG 기반 Kubernetes 워크플로우, UI 제공Kubernetes에서 복잡한 배치를 운영하고 싶은 경우
PrefectPython 코드 기반, Airflow보다 가벼움개발 친화적인 워크플로우 관리가 필요한 경우
KubeCronCronJob 개선, 모니터링/재시도 기능 제공기존 CronJob을 유지하면서 기능을 확장하고 싶은 경우
KestraYAML 기반 설정, UI 제공간편하게 Kubernetes 배치를 운영하고 싶은 경우

설치 (약식)

운영환경에는 Helm 사용을 통해 PostgreSql 등으로 메타 데이터베이스를 교체하고, REDIS 사용을 추천한다. 아래는 Airflow 테스트를 위해 약식 설치 방식이다.

kubectl create namespace airflow
kubectl apply -f airflow-deploy.yml
kubectl apply -f airflow-svc.yml

airflow-svc.yml

apiVersion: v1
kind: Service
metadata:
  name: airflow
  namespace: airflow
spec:
  selector:
    app: airflow
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
  type: NodePort

airflow-deploy.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: airflow
  namespace: airflow
spec:
  replicas: 1  # SQLite는 1개 Replica만 가능
  selector:
    matchLabels:
      app: airflow
  template:
    metadata:
      labels:
        app: airflow
    spec:
      securityContext:
        fsGroup: 50000
      containers:
        - name: airflow
          image: apache/airflow:latest
          securityContext:
            runAsUser: 50000
          imagePullPolicy: IfNotPresent
          env:
            - name: AIRFLOW__CORE__EXECUTOR
              value: "SequentialExecutor"
            - name: AIRFLOW__DATABASE__SQL_ALCHEMY_CONN
              value: "sqlite:////opt/airflow/airflow.db"
          volumeMounts:
            - name: airflow-data
              mountPath: /opt/airflow
          command: ["bash", "-c"]
          args:
            - |
              airflow db init &&
              airflow users create --username admin --password admin --firstname Admin --lastname User --role Admin --email admin@example.com &&
              airflow webserver && 
              airflow scheduler
      volumes:
        - name: airflow-data
          persistentVolumeClaim:
            claimName: mypvc

웹콘솔

vagrant@slave2:~$ k get svc -n airflow
NAME      TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
airflow   NodePort   10.98.56.159   <none>        8080:30838/TCP   16m

웹콘솔은 위의 노드포트를 통해 접속 가능하다. 기본 계정은 admin/admin 이다.

AIRFLOW 버전 확인

vagrant@slave2:~$ k exec airflow-6bf7b46c79-scvks -n airflow  -- airflow version
2.10.5

DAG 저장 위치 확인

airflow@airflow-6bf7b46c79-scvks:/opt/airflow$ airflow config get-value core dags_folder
/opt/airflow/dags

DAG 목록 조회

airflow@airflow-6bf7b46c79-scvks:/opt/airflow$ airflow dags list
dag_id | fileloc | owners | is_paused
==========+========================+=========+==========
hello_dag | /opt/airflow/dags/h.py | airflow | True

DAG 정보 조회

airflow@airflow-5db85d78ff-x8tqw:/opt/airflow/dags$ airflow dags show hello_dag
[2025-03-10T11:02:49.242+0000] {dagbag.py:588} INFO - Filling up the DagBag from /opt/airflow/dags
digraph hello_dag {
        graph [label=hello_dag labelloc=t rankdir=LR]
        print_date [color="#000000" fillcolor="#f0ede4" label=print_date shape=rectangle style="filled,rounded"]
        print_hello [color="#000000" fillcolor="#f0ede4" label=print_hello shape=rectangle style="filled,rounded"]
        print_date -> print_hello
}

DAG 생성 로그 추적

airflow@airflow-5db85d78ff-x8tqw:/opt/airflow/dags$ cat $AIRFLOW_HOME/logs/scheduler/latest/*.log | grep "DAG"
[2025-03-10T11:01:25.045+0000] {processor.py:925} INFO - DAG(s) 'hello_dag' retrieved from /opt/airflow/dags/h.py
[2025-03-10T11:01:25.138+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.137+0000] {override.py:1912} INFO - Created Permission View: can read on DAG:hello_dag
[2025-03-10T11:01:25.150+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.150+0000] {override.py:1912} INFO - Created Permission View: can edit on DAG:hello_dag
[2025-03-10T11:01:25.159+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.158+0000] {override.py:1912} INFO - Created Permission View: can delete on DAG:hello_dag
[2025-03-10T11:01:25.174+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.174+0000] {override.py:1912} INFO - Created Permission View: can read on DAG Run:hello_dag
[2025-03-10T11:01:25.184+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.183+0000] {override.py:1912} INFO - Created Permission View: menu access on DAG Run:hello_dag
[2025-03-10T11:01:25.192+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.192+0000] {override.py:1912} INFO - Created Permission View: can create on DAG Run:hello_dag
[2025-03-10T11:01:25.202+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.202+0000] {override.py:1912} INFO - Created Permission View: can delete on DAG Run:hello_dag
[2025-03-10T11:01:25.202+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.202+0000] {dag.py:3239} INFO - Sync 1 DAGs
[2025-03-10T11:01:25.211+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:25.211+0000] {dag.py:3262} INFO - Creating ORM DAG for hello_dag
[2025-03-10T11:01:56.055+0000] {processor.py:925} INFO - DAG(s) 'hello_dag' retrieved from /opt/airflow/dags/h.py
[2025-03-10T11:01:56.073+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:01:56.072+0000] {dag.py:3239} INFO - Sync 1 DAGs
[2025-03-10T11:02:27.136+0000] {processor.py:925} INFO - DAG(s) 'hello_dag' retrieved from /opt/airflow/dags/h.py
[2025-03-10T11:02:27.150+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:02:27.150+0000] {dag.py:3239} INFO - Sync 1 DAGs
[2025-03-10T11:02:58.040+0000] {processor.py:925} INFO - DAG(s) 'hello_dag' retrieved from /opt/airflow/dags/h.py
[2025-03-10T11:02:58.057+0000] {logging_mixin.py:190} INFO - [2025-03-10T11:02:58.057+0000] {dag.py:3239} INFO - Sync 1 DAGs

DAG 소스 작성

h.py

from airflow import DAG
from airflow.operators.bash import BashOperator
from datetime import datetime, timedelta

default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'start_date': datetime(2024, 6, 29),
    'email_on_failure': False,
    'email_on_retry': False,
    'retries': 1,
    'retry_delay': timedelta(minutes=5),
}

dag = DAG(
    'hello_dag',
    default_args=default_args,
    description='Hello DAG',
    schedule_interval=timedelta(days=1),
)

task1 = BashOperator(
    task_id='print_date',
    bash_command='date',
    dag=dag,
)

task2 = BashOperator(
    task_id='print_hello',
    bash_command='echo "Hello World"',
    dag=dag,
)

task1 >> task2 

DAG 소스 AIRFLOW 복사

vagrant@slave2:~$ k get po -n airflow
NAME                       READY   STATUS    RESTARTS      AGE
airflow-6bf7b46c79-scvks   1/1     Running   1 (33m ago)   26h

kubectl cp hello.py airflow-6bf7b46c79-scvks:/opt/airflow/dags -n airflow

AIRFLOW 결과

위에서 복사한 DAG가 웹콘솔에 나타나는 것을 확인한다.

0개의 댓글