Airflow 7 — Triển khai & vận hành production
Chạy Airflow trên laptop bằng airflow standalone thì ai cũng làm được. Nhưng đưa Airflow lên production — nơi hàng trăm DAG chạy 24/7, nơi một scheduler chết lúc 2 giờ sáng khiến cả nhà máy dữ liệu đứng hình — lại là câu chuyện khác hẳn. Bài này viết cho người phải vận hành Airflow 3.x: chọn cách triển khai, đưa DAG lên qua CI/CD, quản lý secret an toàn, gom log, giám sát và xử lý sự cố. Xuyên suốt bài, ta lấy ví dụ một nền tảng dữ liệu ngân hàng chạy Airflow trên Kubernetes phục vụ hàng trăm pipeline ETL và báo cáo hằng ngày.
Nếu bạn chưa nắm kiến trúc và các loại executor, hãy đọc trước Tổng quan Airflow và Executors & scaling. Bài này giả định bạn đã hiểu scheduler, executor, worker là gì.
Các cách triển khai
Có ba con đường chính để đưa Airflow 3.x lên production, mỗi con đường phù hợp với một quy mô và mức độ kiểm soát khác nhau.
1. Docker Compose — cho dev và cụm nhỏ
Airflow phát hành sẵn một file docker-compose.yaml tham khảo, khởi động đầy đủ các dịch vụ trong các container trên một máy duy nhất: api-server, scheduler, dag-processor, triggerer, worker (nếu dùng CeleryExecutor), cùng Postgres và Redis. Đây là cách nhanh nhất để có một môi trường gần giống production để thử nghiệm.
Điểm mạnh: dễ dựng, dễ hiểu, đủ cho một nhóm nhỏ hoặc môi trường DEV. Điểm yếu: không có khả năng chịu lỗi (một máy chết là mất tất cả), khó scale ngang worker, và việc nâng cấp/rollback thủ công. Đừng dùng Docker Compose cho production quan trọng — nó không được thiết kế cho việc đó.
2. Helm chart chính thức trên Kubernetes — lựa chọn production phổ biến
Đây là cách triển khai tự quản (self-managed) được dùng nhiều nhất cho production nghiêm túc. Cộng đồng Airflow duy trì một Helm chart chính thức (apache-airflow/airflow) triển khai toàn bộ các thành phần dưới dạng các Deployment/StatefulSet trên Kubernetes:
- api-server: trong Airflow 3, webserver cũ đã trở thành một API server tổng quát, vừa phục vụ UI vừa là backend cho Task SDK. Chart hỗ trợ HorizontalPodAutoscaler cho thành phần này.
- scheduler: quả tim của Airflow, lên lịch và điều phối task. Có thể chạy nhiều bản (HA).
- dag-processor: thành phần tách riêng chuyên parse và serialize DAG. Ở Airflow 3 đây là tiến trình độc lập, giúp cô lập lỗi parse DAG khỏi scheduler.
- workers: nơi task thực sự chạy (với CeleryExecutor); với KubernetesExecutor thì mỗi task là một pod riêng, không có worker thường trực.
- triggerer: chạy các deferrable operator/sensor theo mô hình async, tiết kiệm tài nguyên cho các tác vụ chờ đợi.
- redis (broker cho Celery) và postgres (metadata DB).
Chart còn quản lý các đối tượng phụ trợ như PodDisruptionBudget cho triggerer/worker/dag-processor và các one-off job (ví dụ airflow db migrate khi cài đặt).
Lưu ý production quan trọng: tài liệu chính thức khuyến nghị không dùng Postgres/Redis chạy trong pod của chart cho production — hãy dùng metadata DB ngoài (managed database như RDS/Cloud SQL) trên máy riêng. Ngoài ra ở Airflow 3 bạn phải đặt một JWT secret tĩnh (qua jwtSecretName) để worker và api-server xác thực lẫn nhau ổn định qua các lần restart.
3. Managed — MWAA, Cloud Composer, Astronomer
Nếu không muốn tự vận hành hạ tầng, có ba dịch vụ managed lớn:
- Amazon MWAA (Managed Workflows for Apache Airflow): từ tháng 10/2025 đã hỗ trợ Airflow 3.0, sau khi cộng đồng phát hành Airflow 3 vào tháng 4/2025. MWAA lo scheduler, worker autoscaling, vá lỗi, tích hợp sẵn IAM/VPC/S3.
- Google Cloud Composer: dịch vụ managed Airflow của GCP, tích hợp GCS, BigQuery, IAM.
- Astronomer (Astro): nền tảng thương mại chuyên về Airflow, thường bám sát các phiên bản Airflow mới nhất và cung cấp CLI/CI-CD, observability riêng.
Tự quản vs managed — chọn thế nào?
| Tiêu chí | Tự quản (Helm/K8s) | Managed (MWAA/Composer/Astro) |
|---|---|---|
| Kiểm soát | Toàn quyền: version, provider, plugin, cấu hình | Giới hạn theo dịch vụ |
| Chi phí | Trả cho hạ tầng + công vận hành | Trả phí dịch vụ (thường cao hơn/đơn vị) |
| Vận hành | Bạn tự lo HA, nâng cấp, vá lỗi | Nhà cung cấp lo phần lớn |
| Thời gian lên production | Chậm hơn | Nhanh (vài phút có môi trường) |
| Phù hợp | Đội có kỹ năng K8s/SRE, cần tùy biến sâu | Đội nhỏ, muốn tập trung vào DAG |
Nguyên tắc: nếu bạn chưa có đội platform vững về Kubernetes, managed gần như luôn là lựa chọn đúng. Chỉ tự quản khi bạn cần kiểm soát sâu (compliance, mạng nội bộ ngân hàng, provider tùy biến) và có người trực vận hành.
Kiến trúc triển khai trên Kubernetes
Sơ đồ này là bộ khung chuẩn của một triển khai Airflow 3 trên K8s: các pod cốt lõi, metadata DB và broker tách ngoài, DAG được đồng bộ từ Git, secret lấy từ backend ngoài, log đẩy remote, và toàn bộ metric chảy về Prometheus/Grafana.
Phân phối DAG lên môi trường
Câu hỏi kinh điển: làm sao đưa file DAG vào tay scheduler/worker? Có ba cách.
git-sync sidecar
Một container phụ (sidecar) liên tục git pull repo DAG vào một volume dùng chung, các pod Airflow đọc DAG từ đó. Ưu điểm: cập nhật gần như tức thời khi merge, không cần build lại image. Đây là cách phổ biến với Helm chart.
# values.yaml (minh hoạ) — bật git-sync trong Helm chart
dags:
gitSync:
enabled: true
repo: "[email protected]:ncb/airflow-dags.git"
branch: "main"
subPath: "dags"
period: "30s" # tần suất pull
sshKeySecret: "airflow-git-ssh"
Bake DAG vào image
Đóng gói DAG luôn vào Docker image của Airflow. Ưu điểm: bất biến (immutable), version rõ ràng, rollback = deploy lại image cũ, kiểm thử image trước khi phát hành. Nhược điểm: mỗi lần đổi DAG phải build và roll image. Phù hợp môi trường cần kiểm soát chặt (như ngân hàng).
DAG bundles (Airflow 3, AIP-66)
Airflow 3 giới thiệu khái niệm DAG bundles (AIP-66) — cơ chế mới để đóng gói và phiên bản hóa tập DAG như một "bundle", cho phép tách nguồn DAG khỏi lõi Airflow và quản lý nhiều nguồn/nhiều phiên bản DAG một cách có kiểm soát hơn. Đây là hướng đi dài hạn của dự án cho việc phân phối DAG.
CI/CD cho DAG
Dù chọn cách nào, quy trình CI/CD nên có các bước:
- Lint & static check: chạy
ruff/flake8, kiểm tra cú pháp. - Test DAG import: đảm bảo mọi DAG parse được, không có import error,
dag.test()cho DAG quan trọng. - Build image (nếu bake) và đẩy lên registry.
- Deploy theo môi trường, có phê duyệt cho PROD.
# .gitlab-ci.yml (minh hoạ) — kiểm thử DAG trước khi deploy
lint_test_dags:
stage: test
image: apache/airflow:3.0.0
script:
- pip install -r requirements.txt
- ruff check dags/
- python -c "from airflow.models import DagBag; \
db=DagBag('dags/', include_examples=False); \
assert not db.import_errors, db.import_errors"
Tách môi trường DEV / STAGING / PROD là bắt buộc: mỗi môi trường một namespace/instance riêng, metadata DB riêng, connection/variable riêng. DAG được merge lên develop chạy STAGING, chỉ khi tag/release mới lên PROD. Không bao giờ để lập trình viên chỉnh trực tiếp trên PROD.
Connections & Variables — và secret
Airflow lưu Connections (thông tin kết nối tới DB, API, cloud) và Variables (tham số cấu hình) ở hai nơi.
Mặc định — trong metadata DB: các trường nhạy cảm (password, extra) được mã hóa bằng Fernet key. Fernet key phải được sinh ngẫu nhiên, lưu an toàn (không hardcode trong repo), và giữ ổn định — mất key là mất khả năng giải mã toàn bộ connection. Cách này ổn cho quy mô nhỏ nhưng secret vẫn nằm trong DB của Airflow.
Secrets backend — cho production: cấu hình Airflow lấy connection/variable từ một hệ thống quản lý secret bên ngoài. Airflow hỗ trợ sẵn AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault, v.v. Khi cần một connection, Airflow tra cứu backend trước, rồi mới đến biến môi trường, cuối cùng mới đến metadata DB.
# airflow.cfg / env (minh hoạ) — dùng HashiCorp Vault làm secrets backend
[secrets]
backend = airflow.providers.hashicorp.secrets.vault.VaultBackend
backend_kwargs = {
"connections_path": "airflow/connections",
"variables_path": "airflow/variables",
"url": "https://vault.ncb.internal:8200",
"auth_type": "kubernetes",
"kubernetes_role": "airflow"
}
Ưu điểm của secrets backend: secret không nằm trong DB Airflow, được xoay vòng (rotate) tập trung, phân quyền theo policy của Vault/IAM, và audit tập trung. Với ngân hàng, đây gần như là yêu cầu bắt buộc.
Quy tắc bất di bất dịch: KHÔNG hardcode secret trong code DAG. Không đặt password, API key, chuỗi kết nối ngay trong file .py. DAG chỉ nên tham chiếu tới conn_id / Variable.get(...); giá trị thực do backend cung cấp lúc chạy. Secret lọt vào Git là một sự cố bảo mật, không phải lỗi nhỏ.
Logging
Ở một cluster có nhiều worker/pod ngắn hạn, log task không thể để nằm trên đĩa cục bộ của worker — pod chết là log biến mất. Giải pháp: remote logging.
Airflow ghi log task ra kho lưu trữ ngoài: S3, GCS, hoặc đẩy vào ELK/Loki. Cấu hình remote_logging = True và trỏ remote_base_log_folder tới bucket. Khi bạn mở log của một task trong UI, api-server đọc log từ remote về hiển thị.
Một thay đổi kiến trúc đáng chú ý ở Airflow 3: worker gửi log qua API (Task Execution API) thay vì cần chia sẻ volume log trực tiếp với api-server như trước. Điều này làm việc tách worker khỏi web/API sạch sẽ hơn, phù hợp mô hình bảo mật mới (worker không cần truy cập trực tiếp metadata DB).
# values.yaml (minh hoạ) — remote logging ra S3
config:
logging:
remote_logging: "True"
remote_base_log_folder: "s3://ncb-airflow-logs/prod"
remote_log_conn_id: "aws_logs"
Giám sát
Không giám sát thì bạn chỉ biết Airflow hỏng khi có người phàn nàn pipeline không chạy. Cần chủ động hơn.
Metrics
Airflow phát metric qua StatsD hoặc OpenTelemetry (OTel). Đường phổ biến: Airflow → StatsD exporter → Prometheus → Grafana để trực quan hóa và Alertmanager để cảnh báo. Các metric cần theo dõi sát:
- Scheduler heartbeat: scheduler còn sống không? Mất heartbeat = task ngừng được lên lịch.
- DAG parse time (
dag_processing.total_parse_time): parse chậm dần là dấu hiệu DAG quá nặng hoặc quá nhiều DAG. - Task duration: task chạy lâu bất thường.
- Queue depth / task đang chờ: hàng đợi phình to nghĩa là thiếu worker (xem Executors & scaling).
- Task fail rate, số zombie task, số DAG import error.
Health checks
Airflow cung cấp endpoint /health (trên api-server) và cơ chế heartbeat trong metadata DB. Trong K8s, dùng chúng làm liveness/readiness probe để tự khởi động lại pod hỏng.
Cảnh báo
Cảnh báo nên gắn với hậu quả nghiệp vụ, không chỉ kỹ thuật: task fail, vi phạm deadline/SLA (Airflow 3 chuyển hướng dùng cơ chế Deadline Alerts thay cho SLA kiểu cũ), pipeline trọng yếu chưa hoàn thành trước giờ cắt sổ. Gắn với callback (on_failure_callback) đẩy sang Slack/PagerDuty.
Bảo mật & RBAC
- RBAC: Airflow có mô hình vai trò/quyền (roles/permissions). Gán người dùng vào vai trò như Viewer, Op, Admin; hoặc tự định nghĩa vai trò giới hạn chỉ xem/chạy một nhóm DAG. Nguyên tắc đặc quyền tối thiểu.
- Auth: api-server tích hợp với hệ thống định danh doanh nghiệp (OAuth/OIDC, LDAP) qua auth manager. Không dùng tài khoản admin dùng chung.
- JWT cho worker (Airflow 3): worker giao tiếp với api-server qua Task Execution API, xác thực bằng JWT được ký bằng secret key tĩnh. Đây là một phần của mô hình bảo mật mới — worker không truy cập trực tiếp metadata DB nữa, giảm bề mặt tấn công.
- Network: đặt api-server sau reverse proxy/ingress có TLS; hạn chế truy cập metadata DB và Redis chỉ trong namespace; dùng NetworkPolicy.
- Fernet: bảo vệ Fernet key như bảo vệ khóa két.
- Audit: bật audit log (ai chỉnh connection, trigger DAG, đổi variable) để truy vết.
Sự cố hay gặp và cách xử lý
- DAG import error: DAG không parse được (thiếu thư viện, lỗi cú pháp, import top-level nặng). UI báo lỗi import; kiểm tra log dag-processor. Phòng ngừa: chặn ở CI (bước test DagBag ở trên).
- Task stuck / queued mãi: task ở trạng thái
queuednhưng không chạy. Nguyên nhân thường là hết worker slot / thiếu pool / parallelism thấp, hoặc executor không lấy được task. Kiểm tra số worker,pool,parallelism,max_active_tasks. - DB đầy / phình to: metadata DB tích lũy lịch sử task instance, log, XCom qua thời gian. Dọn định kỳ bằng
airflow db clean:
# (minh hoạ) — dọn bản ghi metadata cũ hơn 90 ngày
airflow db clean --clean-before-timestamp "2026-04-01 00:00:00"
Nên chạy định kỳ (một DAG "housekeeping"), có backup trước, và cân nhắc --skip-archive khi đã hiểu rõ. DB đầy làm scheduler chậm dần.
- Scheduler quá tải: DAG parse chậm, độ trễ lên lịch tăng. Cách chữa: giảm số DAG/độ phức tạp, tăng
min_file_process_interval, tách dag-processor, chạy nhiều scheduler (HA), tối ưu top-level code trong DAG. - Zombie task: task mà tiến trình đã chết nhưng DB vẫn nghĩ đang chạy (thường do worker/pod bị kill). Scheduler phát hiện qua thiếu heartbeat và đánh dấu fail để retry. Nếu nhiều zombie: kiểm tra OOM của worker pod, timeout, ổn định hạ tầng.
Use case thực tế
Ngân hàng dựng Airflow trên K8s với CI/CD + Vault. Đội platform triển khai Airflow 3 bằng Helm chart lên cluster K8s nội bộ. Metadata DB là Postgres managed riêng, Redis làm broker cho CeleryExecutor với worker autoscale. DAG được bake vào image (yêu cầu bất biến của bộ phận rủi ro): pipeline GitLab CI lint, chạy test DagBag, build image tag theo commit, và deploy STAGING tự động; lên PROD phải qua phê duyệt của trưởng nhóm. Tất cả connection tới core banking, data warehouse đều lấy từ HashiCorp Vault qua secrets backend với auth Kubernetes — không một secret nào nằm trong repo. Log task đẩy lên S3 nội bộ; metric qua StatsD → Prometheus → Grafana; cảnh báo SLA/deadline bắn sang PagerDuty. RBAC gắn với LDAP doanh nghiệp, worker xác thực api-server bằng JWT và không chạm metadata DB. Kết quả: rollback bằng cách deploy lại image cũ, audit đầy đủ, và không sự cố lộ secret.
Startup chọn MWAA. Một đội 4 người không có kỹ năng K8s chọn Amazon MWAA (đã hỗ trợ Airflow 3). Họ chỉ cần đẩy DAG lên bucket S3, cấu hình requirements, và AWS lo scheduler/worker/vá lỗi. Secret dùng AWS Secrets Manager (tích hợp sẵn). Đổi lại chi phí cao hơn và ít tùy biến hơn, nhưng đội tập trung 100% vào việc viết pipeline thay vì vận hành hạ tầng — đúng lựa chọn cho quy mô đó.
Ghi nhớ
- Docker Compose cho dev/nhỏ; Helm/K8s cho production tự quản; MWAA/Composer/Astronomer khi muốn managed. Không đội platform vững K8s thì chọn managed.
- Airflow 3 tách rõ api-server, scheduler, dag-processor, triggerer, worker; dùng metadata DB và Redis ngoài cho production, đặt JWT secret tĩnh.
- Phân phối DAG: git-sync (nhanh), bake image (bất biến, dễ rollback), hoặc DAG bundles (AIP-66). Luôn có CI/CD lint + test DagBag, tách DEV/STAGING/PROD.
- KHÔNG hardcode secret trong DAG. Dùng secrets backend (Vault/Secrets Manager/GCP) cho production; Fernet key phải ổn định và bí mật.
- Remote logging ra S3/GCS/ELK; Airflow 3 worker gửi log qua API và không cần chạm metadata DB.
- Giám sát qua StatsD/OTel → Prometheus/Grafana; theo dõi scheduler heartbeat, DAG parse time, queue depth, task duration; cảnh báo theo SLA/deadline và hậu quả nghiệp vụ.
- Bảo mật: RBAC + auth doanh nghiệp, JWT cho worker, TLS/NetworkPolicy, audit log.
- Sự cố quen mặt: DAG import error, task stuck/queued, DB đầy (
airflow db clean), scheduler quá tải, zombie task — phần lớn phòng được bằng CI, giám sát và housekeeping định kỳ.
Đọc tiếp: Executors & scaling để tối ưu năng lực chạy task, và Best practices để viết DAG sạch, dễ vận hành.
Bài viết liên quan
CSV/JSON/Parquet/Avro, lưu trữ theo hàng vs cột, nén, và OLTP vs OLAP.
Vì sao xử lý phân tán, mô hình Spark (RDD/DataFrame), lazy evaluation, shuffle và tối ưu.
Data Engineering là gì, vai trò trong vòng đời dữ liệu, và bức tranh hệ sinh thái công cụ.
Đảm bảo chất lượng & minh bạch dữ liệu bằng dbt: data tests dựng sẵn (unique, not_null, relationships, accepted_values), singular test, unit test, và tài liệu tự sinh kèm lineage graph.