Learning Platform
Глоссарий Troubleshooting
Урок 19.08 · 24 мин
Продвинутый
InfrastructureDAG ProcessorFastAPIFABREST API v2Helm 2.x

Migration infrastructure — DAG Processor, FastAPI, FAB removal, REST API v2

DAG code migrated (previous lessons), но это только половина работы. 3.x фундаментально меняет infrastructure: standalone DAG Processor становится mandatory, webserver — это FastAPI API server, FAB убран в pluggable auth providers, REST API v1 deprecated в пользу v2. Этот урок — practical guide для infrastructure migration в Helm-based deployments.

Infrastructure changes 2.x → 3.x — Helm chart components transformation
webserver (Flask + FAB)2.x: Flask + Flask-AppBuilder, Gunicorn WSGI, Jinja templates server-rendered. webserverConfig для FAB auth (AUTH_TYPE = AUTH_OAUTH etc). Custom Flask views работают.
renamed → React UI separate
apiServer (FastAPI)3.x: webserver renamed к apiServer. FastAPI async + OpenAPI auto-generated spec. React UI как static files отдельно. Custom Flask views broken — нужен React+FastAPI rewrite. Helm values: webserver → apiServer.
dagProcessor.enabled: true (optional)2.x: DAG Processor может быть inline (default) или standalone (opt-in). Heavy DAGs (TensorFlow imports) замедляют scheduler main loop в inline mode. Capstone deployment уже enables standalone — preview к 3.x.
always-on в 3.x
dagProcessor (mandatory)3.x: standalone DAG Processor mandatory. No 'enabled' option. Separate process с own concurrency, dedicated к parsing. Scheduler — pure scheduling logic, faster ticks. Multiple replicas для multiple DAG bundles.
dags.gitSync sidecar2.x: gitSync sidecar container в каждом pod (scheduler, worker, webserver). Init container git pull-ит DAGs из repo. Single source. Overhead — sidecar в каждом pod.
replaced AIP-66
dagBundles (AIP-66)3.x: pluggable DAG sources. dagBundles array — GitDagBundle, S3DagBundle, HTTPDagBundle. Multi-source: production DAGs из Git, experimental из S3, dev local. Per-bundle refresh intervals и versioning. DAG Processor pulls centrally — no sidecar.
FAB built-in auth2.x: Flask-AppBuilder bundled, webserver_config.py с AUTH_TYPE = AUTH_OAUTH, OAUTH_PROVIDERS. Built-in DB users + OIDC/LDAP. RBAC через FAB roles.
REST API v1 (Flask-RESTful)2.x: /api/v1/* endpoints. Basic auth common. Response format snake_case.
AIP-79 + FastAPI
Pluggable AuthManager (AIP-79)3.x: FAB removed. AuthManager providers: apache-airflow-providers-fab (drop-in compat), AwsIamAuthManager, custom OIDC/JWT. [api] auth_backends config. Migration option 1: install fab provider — 30 min. Option 2: custom AuthManager — major rewrite.
REST API v2 (FastAPI OpenAPI)3.x: /api/v2/* endpoints. Bearer JWT preferred. HATEOAS _links. camelCase в places. v1 deprecated parallel 6-12 months. apache-airflow-client Python package auto-generated от OpenAPI spec.

Helm commands — install, upgrade, rollback

Change 1: Standalone DAG Processor — mandatory

В 2.x — DAG Processor opcional standalone (default — внутри scheduler). В 3.x — mandatory standalone.

Почему

В 2.x scheduler делает DAG parsing inline:

Scheduler main loop:
  Phase 0: DAG parsing (slow, IO-bound)
  Phase 1: Create DagRuns
  Phase 2: Schedule TIs
  Phase 3: Enqueue (critical section)

Heavy DAGs (TensorFlow imports, complex factories) slowed Phase 0 → entire scheduler tick slow.

В 3.x DAG Processor — separate process с own concurrency, dedicated к parsing. Scheduler — pure scheduling logic, faster.

Helm 2.x configuration

# values 2.x (uses optional dagProcessor)
dagProcessor:
  enabled: true  # was optional
  replicas: 1

# values 3.x (mandatory)
dagProcessor:
  # No 'enabled' option — always on
  replicas: 1
  # Multiple replicas для multiple DAG bundles

Migration: enable dagProcessor.enabled: true в 2.x already — preview к 3.x mandatory. Capstone deployment (модуль 18.04) already does this.


Change 2: Webserver Flask → FastAPI API Server

В 2.x — Flask + Flask-AppBuilder. UI server-rendered Jinja templates.

В 3.x — FastAPI API Server + separate React UI. Architecture:

Client (browser)
   ↓ HTTPS
React UI (static files)
   ↓ /api/v2/* AJAX
FastAPI API Server
   ↓ async
PostgreSQL

What this means

  • Webserver renamed to API Server в Helm values
  • Custom webserver_config.py (Flask) — broken
  • Custom Flask views — broken (need React + FastAPI rewrites)
  • Static assets served separately
  • WebSocket support better (FastAPI native)

Helm config

# values 2.x
webserver:
  replicas: 3
  webserverConfig: |
    # Flask config
    AUTH_TYPE = AUTH_OAUTH
    OAUTH_PROVIDERS = [...]

# values 3.x
apiServer:    # renamed from webserver
  replicas: 3
  # No more webserverConfig — auth via provider config
  config: {}

Migration:

  1. Verify no custom Flask views в webserver_config.py
  2. Custom plugins with Flask blueprints → rewrite (или live without)
  3. UI customizations (CSS overrides) — apply through React UI config

Change 3: FAB removed → pluggable auth providers (AIP-79)

Biggest infrastructure change. FAB (Flask-AppBuilder) was bundled in 2.x, providing built-in auth (DB-based users, OIDC, LDAP).

В 3.x — FAB removed. Auth через AuthManager providers:

Available auth providers (2026)

ProviderDescriptionMaintainer
apache-airflow-providers-fabLegacy FAB compatApache (provider package)
apache-airflow-providers-amazon (AwsIamAuthManager)AWS IAMApache
Custom AuthManager classesOIDC, SAML, JWT, customCommunity

Migration option 1 — use FAB provider for backward compat

Simplest path: install apache-airflow-providers-fab — works almost as drop-in.

pip install apache-airflow-providers-fab
# airflow.cfg 3.x
[api]
auth_backends = "airflow.providers.fab.auth_manager.FabAuthManager"

Configuration almost identical к 2.x webserver_config.py. Migrating to FAB provider — 30 minutes for most setups.

Migration option 2 — switch to native AuthManager

For modern OIDC setups, native auth provider may be cleaner:

# plugins/auth/okta_auth_manager.py
from airflow.auth.managers.base_auth_manager import BaseAuthManager

class OktaAuthManager(BaseAuthManager):
    # Implement abstract methods
    def get_user(self): ...
    def is_logged_in(self): ...
    def get_url_login(self): ...
    # etc.
[api]
auth_backends = "plugins.auth.okta_auth_manager.OktaAuthManager"

Major rewrite. Postpone unless really need it.

Helm config example

# values 3.x
apiServer:
  config:
    api:
      auth_backends: "airflow.providers.fab.auth_manager.FabAuthManager"
  # FAB-specific config:
  fabConfig: |
    AUTH_TYPE = AUTH_OAUTH
    OAUTH_PROVIDERS = [{...}]

Change 4: REST API v1 → v2

В 2.x — REST API v1 (Flask-RESTful) at /api/v1/*.

В 3.x — REST API v2 (FastAPI) at /api/v2/*. Differences:

Response format

// 2.x v1 example
{
  "dag_id": "my_dag",
  "is_paused": false,
  "last_parsed_time": "2026-05-12T10:00:00+00:00"
}

// 3.x v2 example
{
  "dag_id": "my_dag",
  "is_paused": false,
  "last_parsed_time": "2026-05-12T10:00:00+00:00",
  "_links": {  // HATEOAS links новые
    "self": "/api/v2/dags/my_dag"
  }
}

Most fields identical. Some renames:

  • execution_datelogical_date
  • camelCase introduced в places

Auth headers

# 2.x v1 — Basic auth common
Authorization: Basic <base64>

# 3.x v2 — Bearer token preferred
Authorization: Bearer <jwt>

Migration consumers

API consumers (CI/CD scripts, monitoring tools, custom integrations):

# 2.x consumer
import requests
r = requests.get("https://airflow.example.com/api/v1/dags", auth=("admin", "pass"))
dags = r.json()["dags"]

# 3.x consumer
import requests
# Bearer token (obtained from /api/v2/security/login)
token = "..."
r = requests.get(
    "https://airflow.example.com/api/v2/dags"
    headers={"Authorization": f"Bearer {token}"}
)
dags = r.json()["dags"]

For Python clients — apache-airflow-client package auto-generated from OpenAPI spec:

pip install apache-airflow-client
from airflow_client.client import Client
client = Client(host="https://airflow.example.com", token="...")
dags = client.dags.list()  # auto-typed responses

Change 5: gitSync → DAG Bundles (AIP-66)

В 2.x — gitSync sidecar в каждом pod (модуль 15.03).

В 3.x — DAG Bundles abstraction. Pluggable DAG sources.

# 2.x values
dags:
  gitSync:
    enabled: true
    repo: [email protected]:org/dags.git
    branch: main
    subPath: "dags"

# 3.x values
dagBundles:
  - name: production-dags
    classpath: airflow.dag_bundles.git.GitDagBundle
    kwargs:
      repo_url: https://github.com/org/dags
      branch: main
      subdir: dags
      refresh_interval: 60
  - name: experimental-dags
    classpath: airflow.dag_bundles.s3.S3DagBundle
    kwargs:
      bucket: airflow-experimental-dags
      refresh_interval: 300

DAG Bundles superior:

  • Multiple sources (git, S3, HTTP) one Airflow instance
  • Per-bundle refresh intervals
  • Per-bundle versioning
  • No sidecar overhead (DAG Processor pulls)

Migration: переписать dags.gitSync config на dagBundles array. Helm chart 2.x handles.


Change 6: Helm chart 1.x → 2.x

В 2026 — official Apache Airflow Helm chart 2.x released aligned с Airflow 3.x. Major changes:

# Major key renames в values.yaml
# 1.x → 2.x

webserver:       → apiServer:
dags.gitSync:    → dagBundles: [...]
fernetKey:       → (unchanged)
data:            → (unchanged)
postgresql:      → (deprecated, use external)
redis:           → (deprecated, use external)

Full Helm migration:

# 1. Backup current values
helm get values airflow -n airflow > values-2x-backup.yaml

# 2. Translate manually (or use chart migration script)
# (Helm 2.x chart will provide migration script)

# 3. Upgrade
helm upgrade airflow apache-airflow/airflow \
  --version 2.0.0 \  # Helm chart 2.0+
  --values values-3x.yaml \
  --namespace airflow \
  --wait

Reading Helm chart 2.x docs essential — many key renames.


Change 7: Per-component DB users (модуль 15.08 — even more important)

В 3.x Task SDK enforces stricter boundaries. Per-component DB users (модуль 15.08) become more important:

-- airflow_api_server — для API server (replaces airflow_webserver)
-- airflow_scheduler — same as 2.x
-- airflow_dag_processor — new, for DAG Processor
-- airflow_task_worker — for workers (TASK SDK через API, limited DB access)

Task SDK enforces “tasks don’t query metadata DB directly” — но still need DB connection для intermediate result writes. Setup users carefully.


Helm migration example — capstone values

Before (2.x):

# values-capstone-2x.yaml
executor: "CeleryExecutor,KubernetesExecutor"

webserver:
  replicas: 3

dags:
  gitSync:
    enabled: true
    repo: ...

scheduler:
  replicas: 2

triggerer:
  replicas: 2

dagProcessor:
  enabled: true

After (3.x):

# values-capstone-3x.yaml
executor: "CeleryExecutor,KubernetesExecutor"

apiServer:           # renamed
  replicas: 3
  config:
    api:
      auth_backends: "airflow.providers.fab.auth_manager.FabAuthManager"
  fabConfig: |
    AUTH_TYPE = AUTH_OAUTH
    OAUTH_PROVIDERS = [...]

dagBundles:          # was dags.gitSync
  - name: production
    classpath: airflow.dag_bundles.git.GitDagBundle
    kwargs:
      repo_url: https://github.com/org/dags
      branch: main
      subdir: dags

scheduler:
  replicas: 2

triggerer:
  replicas: 2

dagProcessor:        # no 'enabled' — always on
  replicas: 1

Key changes:

  1. webserverapiServer
  2. dags.gitSyncdagBundles
  3. FAB config preserved через provider
  4. dagProcessor.enabled removed (always on)

Migration ordering

Recommended infrastructure migration sequence:

Week 1: Pre-flight
  - upgrade-check warnings = 0
  - Staging environment ready
  - Backup all DBs
  - Document current Helm values

Week 2: Staging upgrade (parallel deployment)
  - Deploy 3.x Helm chart в new namespace
  - airflow db migrate (на staging Postgres copy)
  - Verify all DAGs parse
  - Run sample DagRuns
  - Test API consumers с new v2 endpoints

Week 3-4: Validation
  - Soak test 1-2 weeks
  - Compare metrics 2.x vs 3.x
  - Verify performance regression < 10%
  - User acceptance testing для UI changes

Week 5: Production migration
  - Saturday morning (low traffic)
  - Blue/green switch
  - Monitor for 48 hours
  - Decommission 2.x

Production gotchas

Helm chart 2.x release timing. Apache Airflow Helm chart 2.0+ released some time after Airflow 3.0 release. Use Astronomer Astro или wait для official chart до production migration. Don’t migrate just code — wait для chart maturity.

Custom Flask plugins — major rewrite. If you have custom webserver views (sidebar items, custom pages) — completely rewrite в React + FastAPI. Estimate weeks per plugin.

REST API v1 deprecation period. 3.x deprecates v1 но likely supports for 6-12 months parallel с v2. Don’t rush API consumer migration day 1.

FAB provider stable, but limited. apache-airflow-providers-fab provides legacy compat — but not all FAB features перенесены. If you used obscure FAB hooks, check provider docs.

Multiple-Executors AIP-61 syntax may evolve. 3.x may add Edge Executor (AIP-69), updates к executor selection syntax. Stay current с release notes.

Backup before migration imperative. Migration tools на production без backup = career-ending mistake. RDS snapshot + pg_dump before airflow db migrate.

Test rollback procedure. Practice in staging — что delete 3.x namespace + restore 2.x. Document exact steps.


Проверка знанийKnowledge check
Production deployment в 2026 на Helm chart 1.15 с Airflow 2.10. Команда хочет минимизировать risk при migration к 3.x. Какие infrastructure changes incremental — что можно сделать на 2.x для smooth 3.x cut over?
ОтветAnswer
Incremental infrastructure preparation для 3.x — multiple steps на 2.x: (1) **Enable standalone DAG Processor сейчас** на 2.x — set `dagProcessor.enabled: true` в Helm values. Already does это в module 15 capstone. Это preview к 3.x mandatory standalone — verify that DAGs parse correctly, performance не regression. Если работает на 2.x — 3.x easy upgrade. (2) **Use multi-component DB users** (модуль 15.08) — even в 2.x: `airflow_scheduler`, `airflow_webserver`, `airflow_worker`, `airflow_readonly`. В 3.x Task SDK enforces boundaries; perpiece preparation. (3) **Setup pluggable auth уже на 2.x** — use OIDC через `apache-airflow-providers-fab` или `apache-airflow-providers-google` already в 2.x. Don't rely on built-in FAB — when migrate, FAB provider drop-in. (4) **REST API consumers** — upgrade к use `apache-airflow-client` Python package (auto-generated client). На 2.x it works against v1 endpoints; в 3.x same client uses v2 — transparent migration. (5) **OpenLineage emission verified** — capstone uses OL. Ensure Marquez stable, lineage continues после migration. (6) **DAG code preparations** — ruff AIR301/AIR302 enforcement. By migration time — 0 violations. (7) **External secrets backend** (Vault) — already на 2.x. 3.x uses same — no changes. (8) **Multiple Executors** — already configured (capstone), no changes в 3.x. (9) **Test SDK adoption in custom operators** — refactor custom operators to use Task SDK-friendly patterns. Avoid `airflow.utils.db.create_session()` direct usage. Use Hooks instead. Custom XCom backend uses BaseXCom interface — stable. (10) **External Iceberg/ClickHouse hooks** — keep abstracted, не tied к Airflow internals. They keep working unchanged. **What CAN'T be done на 2.x**: (a) Use Assets syntax (3.x-only), use Dataset aliases в 2.x; (b) Use HITL operator (3.1+), use sensor pattern; (c) DAG Versioning UI (3.x only); (d) Multi-Team isolation (3.2+). These wait for 3.x. **What CAN be deferred к 3.x migration day**: (a) Final ruff AIR301/AIR302 strict mode (warning OK на 2.x); (b) `schedule_interval` rename (still works in 2.x с warning); (c) `execution_date` references в Jinja templates. **Result of incremental approach**: by migration time most production infra already 3.x-compatible style. Actual migration day = Helm chart switch + airflow db migrate. ~1 day cut over vs 1 month если все changes одновременно. **Lesson**: big version upgrades — gradual via continuous preparation, not big-bang weekend.

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 4. В 3.x standalone DAG Processor — mandatory. Что это значит для migration?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 10