Airflow
KubernetesPodOperator
context extraction
pod management
workflow automation

Get context from Pod launched with Airflow KubernetesPodOperator

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

When a task runs through Airflow's KubernetesPodOperator, the code inside the pod often needs to know which DAG run launched it. Common examples include tagging output files with the run ID, printing task metadata for debugging, or branching behavior based on execution context.

There are three practical ways to get that context inside the pod: use the default Airflow context environment variables, pass exactly the fields you want through templated env_vars, or send structured results back with XCom. Which one is best depends on whether you need to read context, inject context, or return it.

What Airflow Already Provides

Airflow injects a set of context environment variables for task execution. In a pod launched by KubernetesPodOperator, you can typically read values such as:

  • 'AIRFLOW_CTX_DAG_ID'
  • 'AIRFLOW_CTX_TASK_ID'
  • 'AIRFLOW_CTX_RUN_ID'
  • 'AIRFLOW_CTX_TRY_NUMBER'
  • 'AIRFLOW_CTX_EXECUTION_DATE'

That means code inside the container can often read context directly without extra configuration:

python
1import os
2
3print("DAG:", os.environ.get("AIRFLOW_CTX_DAG_ID"))
4print("Task:", os.environ.get("AIRFLOW_CTX_TASK_ID"))
5print("Run:", os.environ.get("AIRFLOW_CTX_RUN_ID"))
6print("Try:", os.environ.get("AIRFLOW_CTX_TRY_NUMBER"))

For quick debugging and lightweight metadata, this is usually enough.

Passing Explicit Context With env_vars

The more robust pattern is to pass the exact values your container should depend on. That keeps the contract visible in the DAG and avoids scattering implicit assumptions through the container code.

Example DAG:

python
1from airflow import DAG
2from airflow.providers.cncf.kubernetes.operators.pod import KubernetesPodOperator
3from pendulum import datetime
4
5with DAG(
6    dag_id="pod_context_demo",
7    start_date=datetime(2024, 1, 1),
8    schedule="@daily",
9    catchup=False,
10) as dag:
11    task = KubernetesPodOperator(
12        task_id="print_context",
13        name="print-context",
14        namespace="default",
15        image="python:3.12-slim",
16        cmds=["python", "-c"],
17        arguments=[
18            (
19                "import os; "
20                "print(os.environ['RUN_ID']); "
21                "print(os.environ['DAG_ID']); "
22                "print(os.environ['LOGICAL_DATE'])"
23            )
24        ],
25        env_vars={
26            "RUN_ID": "{{ run_id }}",
27            "DAG_ID": "{{ dag.dag_id }}",
28            "TASK_ID": "{{ task.task_id }}",
29            "LOGICAL_DATE": "{{ logical_date.isoformat() }}",
30        },
31        get_logs=True,
32        is_delete_operator_pod=True,
33    )

Inside the container, those values are ordinary environment variables:

python
1import os
2
3run_id = os.environ["RUN_ID"]
4dag_id = os.environ["DAG_ID"]
5task_id = os.environ["TASK_ID"]
6logical_date = os.environ["LOGICAL_DATE"]
7
8print(run_id, dag_id, task_id, logical_date)

This approach is explicit and easy to test.

Returning Structured Context With XCom

Sometimes the pod needs to send context or computed metadata back to downstream Airflow tasks. In that case, use XCom rather than trying to scrape logs.

With do_xcom_push=True, the pod can write JSON to /airflow/xcom/return.json:

python
1from airflow.providers.cncf.kubernetes.operators.pod import KubernetesPodOperator
2
3task = KubernetesPodOperator(
4    task_id="emit_context",
5    name="emit-context",
6    namespace="default",
7    image="python:3.12-slim",
8    cmds=["sh", "-c"],
9    arguments=[
10        (
11            "mkdir -p /airflow/xcom && "
12            "printf '%s' '{\"dag_id\":\"'$AIRFLOW_CTX_DAG_ID'\",\"run_id\":\"'$AIRFLOW_CTX_RUN_ID'\"}' "
13            "> /airflow/xcom/return.json"
14        )
15    ],
16    do_xcom_push=True,
17)

Downstream tasks can then pull that value through normal Airflow XCom APIs.

When to Use Each Approach

Use the built-in AIRFLOW_CTX_* variables when you just need quick access to standard metadata. Use templated env_vars when the container should rely on a clear, explicit contract. Use XCom when the pod must return structured data for later tasks.

In practice, many teams combine them: explicit input via env_vars, and explicit output via XCom.

Common Pitfalls

The biggest mistake is assuming the pod automatically receives every value available in Airflow templates. It gets standard context variables, but any custom data should be passed deliberately through templated fields such as env_vars, arguments, labels, or annotations.

Another common mistake is scraping logs to recover structured context. Logs are useful for humans, not as a stable machine interface. If downstream tasks need data, use XCom or write to durable storage.

People also forget that environment variables are not a good place for secrets. For credentials, use Kubernetes secrets or Airflow secret integrations instead of templating sensitive values into plain env vars.

Finally, be careful about which timestamp you pass. In modern Airflow, run_id and logical_date are more precise concepts than the older mental model of one execution_date string for everything.

Summary

  • Pods launched by KubernetesPodOperator can usually read standard AIRFLOW_CTX_* variables directly.
  • Templated env_vars are the clearest way to pass exactly the context fields your container needs.
  • Use XCom with /airflow/xcom/return.json when the pod should return structured metadata.
  • Do not parse logs for machine-readable context if Airflow already provides cleaner channels.
  • Keep secrets out of plain environment variables unless that is an intentional and approved design choice.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.