You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PythonKubernetesOperator and kubernetes taskflow decorator #19135
After the implementation of the Docker Taskflow Operator in 2.2, having a simple function on Kubernetes should be quite simple to accomplish.
One major difference I see is how to get the Code into the Pod.
My prefered way here would be to add an init container which takes care of this - much similar on how we use a Sidecar to extract XCom.
I would also prefer to add more defaults than the KubernetesPodOperator does by default to keep the call as simple and straightforward as possible. We could for example default the namespace to the namespace Airflow is running in if it is a Kubernetes Deployment. Also, we could generate a reasonable pod name from DAG-ID and Task ID.
would be awesome!
It would cleanly separate environments and resources between tasks just as the Docker or Virtualenv Operators do - and unlinke the @task.python decorator. We could specify the resources and environment of each task freely by specifying a resources Argument.
changed the title [-]Python Kubernetes Operator and kubernetes taskflow Operator[/-][+]PythonKubernetesOperator and kubernetes taskflow decorator[/+]on Oct 21, 2021
I just found out about TaskFlow recently while looking through some docs, it looks fantastic! It reminds me of what Prefect is doing and providing an easier interface to convert code -> running in dags.
We heavily use kubernetes-based operators, and would love to see this feature add.
Hello @subkanthi,
I just looked through your pull request and have a couple of remarks. Also from my side thanks for picking this up!!!
Regarding the default namespace - should we at least for in-cluster deployments default to the namespace of the current pod? This is very helpful if Airflow is run on kubernetes as it will rarely run in the default namespace. We can determine the namspace from "/var/run/secrets/kubernetes.io/serviceaccount/namespace"
Script Path
Currently the script is always been written to /tmp/script.py. I think it would be nice if this was a parameter.
Pod Name
Should we maybe try to get the dag_id and task_id in there?
I am currently using:
defgenerate_pod_name(task_id, dag_id=None):
"""Given a task_id and a dag_id, get a kubernetes pod name"""dag_id=dag_idifdag_idisnotNoneelse"xxx-unspecified"name=f"airflow-task-{_to_k8s_name(dag_id)}-{_to_k8s_name(task_id)}"name=re.sub(r"[^a-z0-9.-]+", "-", name.lower())
name=name[:62]
ifname.endswith("-"):
name=name[:-1]
returnname
Which is also not perfect I guess. The KubernetesPodOperator itself then adds another suffix. Edit: The problem with the DAG ID is that it might be bound to the task a little too late. xxx-unspecified is of course a bad thing to do ;)
do_xcom_push
Similar to the VirtualEnvOperator (I think?), we could determine a sensible default using:
I would advice you to look into the Airlflow Kubernetes Scheduler. If you already use Kubernetes as your main airflow scheduler you can simply use taskflow and have python functions running in kubernetes as default. If you don't use the scheduler but want to have some tasks running in kubernetes anyway, there is still a lot of useful functions to reuse or take inspiration from in the scheduler code. For example washing dag ids to be compatible to kubernetes and adding them as labels and annotations on the Pod.
See construct_pod function in airflow/kubernetes/pod_generator.py
@hterik I also think the Scheduler bit can be good inspiration.
I just want to address your first point briefly: I really do think that there are many use-cases for this: Having an operator allows much more freedoms than using the KubernetesExecutor only - for example in specifying the exact dependencies you need for individual tasks. Additionaly, spawning pods for every little thing really might stress the cluster. In our deployment we are runnig ~20 thousand tasks each morning in an hour and then a few more over the day. We tried the KubernetesExecutor but having to schedule a new pod for every sensor and mundane task was a bit too much for our control plane. Thus we are using Celery with lots of KubernetesOperator with self implemented taskflow API.
Can also recommend ["executor_config"]["pod_override"] on taskflow api if you have need to specify exact dependencies per task. We have custom wrappers on top of this so you just have to write:
@node_type=HighPerformance
@task
def foo():
....
Actually it is a lot more granular than this but you get the idea.
Activity
[-]Python Kubernetes Operator and kubernetes taskflow Operator[/-][+]PythonKubernetesOperator and kubernetes taskflow decorator[/+]uranusjr commentedon Oct 22, 2021
cc @dimberman
subkanthi commentedon Nov 29, 2021
Can I try this please if its not being worked on.
potiuk commentedon Nov 29, 2021
Feel fre3 @subkanthi !
Asciotti commentedon Jan 6, 2022
I just found out about
TaskFlowrecently while looking through some docs, it looks fantastic! It reminds me of what Prefect is doing and providing an easier interface to convert code -> running in dags.We heavily use kubernetes-based operators, and would love to see this feature add.
It there a PR I can track on this @subkanthi ?
subkanthi commentedon Jan 7, 2022
Not yet, will have it in a week hopefully.
amin-rashidi-sp commentedon Jan 20, 2022
Thanks for doing this @subkanthi, any update on the progress?
c-thiel commentedon Jan 31, 2022
Hello @subkanthi,
I just looked through your pull request and have a couple of remarks. Also from my side thanks for picking this up!!!
Currently the script is always been written to /tmp/script.py. I think it would be nice if this was a parameter.
Should we maybe try to get the dag_id and task_id in there?
I am currently using:
Which is also not perfect I guess. The KubernetesPodOperator itself then adds another suffix.
Edit: The problem with the DAG ID is that it might be bound to the task a little too late. xxx-unspecified is of course a bad thing to do ;)
Similar to the VirtualEnvOperator (I think?), we could determine a sensible default using:
Let me know what you think!
hterik commentedon Jan 31, 2022
I would advice you to look into the Airlflow Kubernetes Scheduler. If you already use Kubernetes as your main airflow scheduler you can simply use taskflow and have python functions running in kubernetes as default. If you don't use the scheduler but want to have some tasks running in kubernetes anyway, there is still a lot of useful functions to reuse or take inspiration from in the scheduler code. For example washing dag ids to be compatible to kubernetes and adding them as labels and annotations on the Pod.
See
construct_podfunction inairflow/kubernetes/pod_generator.pyc-thiel commentedon Feb 3, 2022
@hterik I also think the Scheduler bit can be good inspiration.
I just want to address your first point briefly: I really do think that there are many use-cases for this: Having an operator allows much more freedoms than using the KubernetesExecutor only - for example in specifying the exact dependencies you need for individual tasks. Additionaly, spawning pods for every little thing really might stress the cluster. In our deployment we are runnig ~20 thousand tasks each morning in an hour and then a few more over the day. We tried the KubernetesExecutor but having to schedule a new pod for every sensor and mundane task was a bit too much for our control plane. Thus we are using Celery with lots of KubernetesOperator with self implemented taskflow API.
hterik commentedon Feb 4, 2022
Did you see the CeleryKubernetes executor ? That allows mixing K8 with celery
Can also recommend
["executor_config"]["pod_override"]on taskflow api if you have need to specify exact dependencies per task. We have custom wrappers on top of this so you just have to write:Actually it is a lot more granular than this but you get the idea.
For small lightweight sensors there is possibility to batch them into https://airflow.apache.org/docs/apache-airflow/stable/concepts/smart-sensors.html or https://airflow.apache.org/docs/apache-airflow/stable/concepts/deferring.html
Not against your idea of a custom operator, just handing out tips :)