Airflow UI Trigger가 10분 뒤에 실행되던 문제: 원인은 NTP 미동기화였다
Airflow 3.2.1을 Docker Compose로 구축한 뒤, 테스트 DAG를 수동 실행하는 과정에서 이상한 현상이 발생했다.
DAG 자체는 정상적으로 등록되었고, Worker도 정상적으로 동작했다. 그런데 Airflow UI에서 Trigger 버튼을 눌러 DAG를 실행하면, Task가 바로 실행되지 않고 약 10분 동안 running 상태로 대기했다.
반대로 CLI에서 실행하면 즉시 성공했다.
sudo docker compose exec airflow-apiserver airflow dags trigger test_hello
CLI로 실행한 DAG Run은 바로 success 상태가 되었다.
1. 증상
Airflow UI에서 수동 Trigger를 실행하면 DAG Run이 생성되었지만, 바로 실행되지 않았다.
DAG Run 목록을 확인하면 다음과 같은 형태였다.
결과 예시:
===========+==========================================+=========+==================================+===========================
test_hello | manual__2026-04-28T06:39:09.994117+00:00 | running | 2026-04-28T06:39:09.994117+00:00 | 2026-04-28T06:49:22+00:00
핵심은 logical_date였다.
logical_date = 2026-04-28T06:49:22+00:00
즉 DAG Run은 15:39 KST에 생성됐는데, logical date는 15:49 KST로 잡혀 있었다.
Airflow Scheduler 입장에서는 logical date가 아직 도달하지 않은 “미래 시각”이었기 때문에 바로 실행하지 않았다.
Scheduler 로그에도 다음 메시지가 반복적으로 출력되었다.
2. 처음 의심했던 것들
처음에는 다음과 같은 항목을 의심했다.
2. UI timezone 표시 문제
3. Airflow 3.2.1 UI Trigger의 logical date 처리 문제
4. CREATE_CRON_DATA_INTERVALS 설정 문제
Airflow timezone은 이미 다음처럼 설정되어 있었다.
TZ: Asia/Seoul
컨테이너에서도 KST가 정상 표시되었다.
결과:
Airflow 설정값도 정상적으로 Asia/Seoul이었다.
결과:
또 Airflow 3에서 cron schedule 해석 방식이 Airflow 2와 다르기 때문에 아래 설정도 추가했다.
확인:
결과:
하지만 이 설정은 schedule="0 * * * *" 같은 cron DAG의 data interval 해석에 영향을 주는 설정이었다.
이번 문제처럼 schedule=None인 수동 Trigger의 logical date 문제와는 직접적인 관련이 없었다.
3. 결정적인 힌트: 항상 약 10분씩 미래로 잡힘
UI Trigger로 생성된 DAG Run을 계속 확인해보니 항상 비슷한 패턴이 있었다.
Logical Date: 16:08:17
차이: 약 10분
UTC/KST 차이라면 9시간 차이가 나야 한다.
하지만 실제 차이는 약 10분이었다.
이때 의심해야 할 것은 timezone이 아니라 서버 시계 자체였다.
4. 서버 시간 확인
Airflow가 설치된 서버에서 시간을 확인했다.
결과:
확인해보니 로컬 PC 시간보다 서버 시간이 약 10분 느렸다.
더 자세히 확인했다.
초기 상태:
Universal time: 화 2026-04-28 07:00:50 UTC
RTC time: 화 2026-04-28 06:55:50
Time zone: Asia/Seoul (KST, +0900)
NTP enabled: no
NTP synchronized: no
RTC in local TZ: no
핵심은 이 두 줄이다.
NTP synchronized: no
NTP가 꺼져 있었고, 시스템 시간이 실제 시간과 어긋나 있었다.
chrony 상태도 확인했다.
결과:
서비스 상태:
결과:
Loaded: loaded
Active: inactive (dead)
즉, CentOS 서버에서 시간 동기화 서비스인 chronyd가 꺼져 있었다.
5. 해결: chronyd 활성화
chrony 패키지는 이미 설치되어 있었다.
결과:
chronyd를 활성화하고 즉시 실행했다.
이후 NTP 소스를 확인했다.
결과 예시:
===============================================================================
^+ 121.134.215.104 2 6 7 1 +3635ns[-614.1s] +/- 932us
^+ any.time.nl 3 6 7 0 -57us[-614.1s] +/- 70ms
^- 121.174.142.82 3 6 7 1 -3998us[-614.1s] +/- 55ms
^* mail.innotab.com 2 6 7 1 -200us[-614.1s] +/- 6381us
* 표시가 붙은 서버가 현재 동기화 기준으로 선택된 NTP 서버다.
동기화 상태를 확인했다.
결과:
Stratum : 3
System time : 0.000000086 seconds fast of NTP time
Last offset : -0.000075338 seconds
Leap status : Normal
거의 오차가 없는 상태로 맞춰졌다.
다시 timedatectl을 확인했다.
결과:
Universal time: 화 2026-04-28 07:12:31 UTC
RTC time: 화 2026-04-28 07:12:31
Time zone: Asia/Seoul (KST, +0900)
NTP enabled: yes
NTP synchronized: yes
RTC in local TZ: no
DST active: n/a
핵심은 다음 두 줄이다.
NTP synchronized: yes
6. 결과
서버 시간이 동기화된 뒤 Airflow UI에서 다시 Trigger를 실행했다.
이번에는 logical date를 따로 비우지 않아도 바로 실행되었다.
즉 문제의 원인은 Airflow DAG 코드나 Worker, Scheduler, Discord callback이 아니었다.
Airflow 서버 시간이 실제 시간보다 약 10분 느렸음
결과:
UI에서 현재 시간으로 logical_date를 넣으면,
서버 입장에서는 그 시간이 약 10분 미래로 보였음
현상:
Scheduler가 "Logical date is in future"로 판단하고 대기
해결:
chronyd 활성화로 서버 시간 동기화
7. 정리
Airflow UI Trigger가 바로 실행되지 않고 running 상태로 오래 대기한다면, DAG 코드나 Executor 문제만 볼 것이 아니라 서버 시간 동기화 상태를 반드시 확인해야 한다.
특히 다음과 같은 증상이 있으면 NTP 문제를 의심할 수 있다.
2. UI trigger만 일정 시간 대기한다.
3. Scheduler 로그에 "Logical date is in future"가 나온다.
4. list-runs에서 logical_date가 run_after보다 미래다.
5. 미래로 밀리는 시간이 항상 비슷하다.
확인 명령어:
timedatectl
chronyc tracking
sudo systemctl status chronyd
CentOS 7에서 chronyd 활성화:
동기화 상태 확인:
chronyc tracking
timedatectl
정상 상태:
NTP synchronized: yes
8. 추가로 확인한 Airflow 설정
이번 구축에서는 다음 설정도 함께 적용했다.
TZ: Asia/Seoul
AIRFLOW__SCHEDULER__CREATE_CRON_DATA_INTERVALS: 'True'
의미는 다음과 같다.
- Airflow 기본 timezone을 KST로 설정
TZ=Asia/Seoul
- 컨테이너 OS 레벨 timezone을 KST로 설정
AIRFLOW__SCHEDULER__CREATE_CRON_DATA_INTERVALS=True
- Airflow 3에서 cron schedule을 Airflow 2의 data interval 방식에 가깝게 해석하도록 설정
하지만 이번 UI Trigger 대기 문제의 직접 원인은 위 설정이 아니라, 서버 NTP 미동기화였다.
9. DAG 코드 수정 반영 시간
Airflow Docker Compose 환경에서 DAG 파일은 다음 경로에 둔다.
컨테이너 경로: /opt/airflow/dags
DAG 파일을 수정하면 airflow-dag-processor가 주기적으로 스캔하여 변경사항을 반영한다.
이번 환경에서는 로그상 약 30초 주기로 DAG 파일이 다시 파싱되었다.
test_hello.py ... Last Run At 2026-04-28T06:24:07
따라서 일반적으로 DAG 코드 수정 후 30초~1분 정도 기다리면 UI와 실행에 반영된다.
급하게 반영하고 싶으면 DAG Processor를 재시작할 수 있다.
sudo docker compose restart airflow-dag-processor
10. 운영 팁
Airflow는 스케줄링 시스템이므로 서버 시간이 매우 중요하다.
서버 시간이 틀어지면 다음과 같은 문제가 생길 수 있다.
2. Scheduler 실행 시점 오류
3. DAG Run logical_date 혼선
4. 로그 시간 불일치
5. 외부 API/파일 수집 시간 기준 오류
6. 장애 분석 시 타임라인 혼선
Airflow 서버를 구축한 직후에는 반드시 다음을 확인하는 것이 좋다.
chronyc tracking
sudo systemctl status chronyd
정상 기준:
NTP synchronized: yes
chronyd active (running)
이번 사례에서는 Airflow 자체 설정 문제가 아니라, 서버 시간 동기화 문제였기 때문에 NTP를 활성화한 뒤 UI Trigger도 정상 동작했다.
'Daily Commit > Data Engineering' 카테고리의 다른 글
| Airflow3 - 기본 설정 (example, timezone...) (0) | 2026.04.28 |
|---|---|
| Airflow3 - 기본 설정 (example, timezone...) (0) | 2026.04.28 |
| Airflow3 업그레이드 (0) | 2026.04.28 |
| [GCP - BigQuery] 갑자기 사라진 VIEW를 찾기 (0) | 2025.11.06 |
| labelme 에러 : Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0) (0) | 2024.03.05 |