TaskAction Resource Definition
The TaskAction Custom Resource Definition (CRD) is the primary mechanism Flyte uses to execute and track individual tasks within a workflow. It acts as a bridge between the Flyte control plane (which decides what needs to run) and the execution engine (which manages the actual Kubernetes resources or external service calls).
Defining the Task with TaskActionSpec
When Flyte needs to execute a task, it creates a TaskAction resource. The TaskActionSpec (defined in executor/api/v1/taskaction_types.go) contains all the information required to identify the task, provide its inputs, and determine which plugin should handle the execution.
You define a task execution by populating the Spec with identifiers and execution context:
taskAction := &executorv1.TaskAction{
ObjectMeta: metav1.ObjectMeta{
Name: "my-run-a0", // Generated name
Namespace: "flyte-tasks",
Labels: map[string]string{
"flyte.org/project": "my-project",
"flyte.org/domain": "production",
"flyte.org/run": "my-run",
"flyte.org/action": "task1",
},
},
Spec: executorv1.TaskActionSpec{
Project: "my-project",
Domain: "production",
RunName: "my-run",
ActionName: "task1",
TaskType: "container",
InputURI: "s3://my-bucket/inputs.pb",
RunOutputBase: "s3://my-bucket/outputs/",
TaskTemplate: serializedTemplate, // Proto-serialized core.TaskTemplate
},
}
Key Specification Fields
- TaskType: This string (e.g.,
"container","spark","ray") is used by theTaskActionControllerto look up the appropriate plugin to handle the task. - TaskTemplate: A
[]bytefield containing the proto-serializedcore.TaskTemplate. This contains the actual command, image, and resource requirements for the task. - InputURI and RunOutputBase: These define where the task should read its input data and where it is expected to write its results.
- CacheKey: If set, the executor will attempt to look up previous results in the Flyte Catalog before executing the task.
Tracking Execution with TaskActionStatus
The TaskActionStatus tracks the observed state of the task as it moves through its lifecycle. Unlike standard Kubernetes resources that might only use conditions, TaskAction maintains detailed plugin state and a full history of transitions.
Plugin State and Phases
The PluginPhase field provides a human-readable string of the current execution stage (e.g., "Queued", "Running", "Succeeded"). Internally, the PluginState field stores Gob-encoded data that allows plugins to resume their work across reconciliation loops without losing context.
Phase History and Conditions
Flyte uses two complementary ways to track progress in executor/api/v1/taskaction_types.go:
- Conditions: A Kubernetes-native list of
metav1.Conditionobjects. TheTaskActionControllerupdates these in-place. Common types includeProgressing,Succeeded, andFailed. - PhaseHistory: An append-only log of
PhaseTransitionobjects. This preserves the timeline of every state change, including timestamps and optional messages.
type PhaseTransition struct {
Phase string `json:"phase"`
OccurredAt metav1.Time `json:"occurredAt"`
Message string `json:"message,omitempty"`
}
Handling Failures
Flyte distinguishes between user-level task failures and system-level infrastructure errors:
- SystemFailures: This counter tracks transient errors (like Kubernetes API timeouts or admission webhook denials). If
SystemFailuresexceeds the configured maximum (defaulting to 3), theTaskActionis transitioned to a permanent failure. - ErrorState: When a task fails, the
ErrorStatestruct captures the structured error returned by the plugin. This includes aCode(e.g.,"OOMKilled"), aKind(USERorSYSTEM), and a human-readableMessage.
Resource Lifecycle
The lifecycle of a TaskAction is managed by several components within the Flyte executor:
- Creation: The Actions service (
actions/k8s/client.go) instantiates theTaskActionCR. It sets up labels and owner references to ensure that if a parent run is deleted, the child tasks are cleaned up automatically. - Reconciliation: The
TaskActionController(executor/pkg/controller/taskaction_controller.go) watches for these resources. It identifies the correct plugin based onSpec.TaskType, calls the plugin'sHandlemethod, and updates theStatusbased on the result. - Finalization: Flyte attaches a finalizer (
flyte.org/plugin-finalizer) to the resource. This ensures that even if the CR is deleted, the plugin has a chance to perform cleanup (like killing a remote Spark job or deleting a pod) before the Kubernetes resource is fully removed. - Garbage Collection: Once a task reaches a terminal state (Succeeded or Failed), the
GarbageCollector(executor/pkg/controller/garbage_collector.go) monitors it. After a grace period, it deletes the terminalTaskActionto prevent etcd bloat.