
Kubernetes Kubernetes
CertifiedEnterprise EditionRun tasks inside Kubernetes pods
Kubernetes Kubernetes
Run tasks inside Kubernetes pods
This plugin is only available in the Enterprise Edition (EE).
To generate output files you can:
- Use the
outputFilesproperty of the task and create a file with the same name in the task’s working directory, or - Create any file in the output directory, which can be accessed with the
{{outputDir}}Pebble expression or theOUTPUT_DIRenvironment variable.
When the Kestra Worker running this task is terminated, the pod continues until completion. After restarting, the Worker will resume processing on the existing pod unless resume is set to false.
If your cluster is configured with RBAC, the service account running your pod must have the following authorizations:
pods: get, create, delete, watch, listpods/log: get, watchpods/exec: get, watchsecrets: create, delete (only required whencredentialsis set, to manage the ephemeral imagePullSecret)
Here is an example role that grants these authorizations:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: task-runner
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "create", "delete", "watch", "list"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["get", "watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get", "watch"]
When job.enabled is set to true, the pod is wrapped in a batch/v1 Job instead of being submitted directly: the Job controller then owns retrying a failed or evicted pod (up to job.backoffLimit attempts) instead of failing the task outright. This additionally requires:
jobs: get, create, delete, listjobs/status: get
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: task-runner
rules:
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["get", "create", "delete", "list"]
- apiGroups: ["batch"]
resources: ["jobs/status"]
verbs: ["get"]
type: io.kestra.plugin.ee.kubernetes.runner.KubernetesExamples
Execute a Shell command.
id: new-shell
namespace: company.team
tasks:
- id: shell
type: io.kestra.plugin.scripts.shell.Commands
taskRunner:
type: io.kestra.plugin.ee.kubernetes.runner.Kubernetes
commands:
- echo "Hello World"
Pass input files to the task, execute a Shell command, then retrieve output files.
id: new-shell-with-file
namespace: company.team
inputs:
- id: file
type: FILE
tasks:
- id: shell
type: io.kestra.plugin.scripts.shell.Commands
inputFiles:
data.txt: "{{ inputs.file }}"
outputFiles:
- out.txt
containerImage: centos
taskRunner:
type: io.kestra.plugin.ee.kubernetes.runner.Kubernetes
commands:
- cp {{ workingDir }}/data.txt {{ workingDir }}/out.txt
Run the task as a Kubernetes Job so an evicted or otherwise failed pod is automatically retried instead of failing the task.
id: new-shell-as-job
namespace: company.team
tasks:
- id: shell
type: io.kestra.plugin.scripts.shell.Commands
taskRunner:
type: io.kestra.plugin.ee.kubernetes.runner.Kubernetes
job:
enabled: true
backoffLimit: 3
commands:
- echo "Hello World"
Properties
pullPolicy *Requiredstring
ALWAYSIF_NOT_PRESENTALWAYSNEVERImage pull policy for the task container
config Non-dynamic
Configure Kubernetes cluster connection
Cluster endpoint, auth, and TLS settings used by the runner.
containerDefaultSpec object
Default container spec applied to all containers
Merged into every container in the pod: the Kestra main container, user-defined sidecars from podSpec.containers, and Kestra's file-transfer init/sidecar containers.
This is the correct place for settings that must be uniform across all containers:
volumeMounts— declare a shared volume mount once instead of repeating it per containersecurityContext— enforce a consistent security posture across all containersresources— set default limits/requests that containers can override individuallyenv— inject common environment variables into all containers
Nested objects (securityContext, resources) are deep-merged; container-specific values win. Lists (volumeMounts, env) are prepended from the default; for env vars the last entry with a given name wins (container-specific overrides the default).
To apply settings only to Kestra's file-transfer containers, use fileSideCarSpec instead.
Example — mounting a shared Docker socket into all containers:
containerDefaultSpec:
volumeMounts:
- name: docker-socket
mountPath: /dind
containerSpec object
Augment main container spec
Merged into the Kestra-generated main container before defaults; supports template expressions.
Environment variables defined here are preserved and merged with Kestra-injected vars (e.g. WORKING_DIR, OUTPUT_DIR). When a variable name collides, the Kestra-injected value takes precedence.
credentials Non-dynamic
When set, the runner creates an ephemeral kubernetes.io/dockerconfigjson imagePullSecret in the pod namespace, references it from the task pod, and deletes it together with the pod. Field names mirror the Docker task runner's credentials block, so a flow can switch runner type without changing its credentials definition. Requires the runner ServiceAccount to be allowed to create/delete secrets in the namespace.
Credentials for a private container registry
Turned into an ephemeral kubernetes.io/dockerconfigjson imagePullSecret created in the pod namespace, referenced by the task pod, and deleted with the pod. The runner ServiceAccount must be allowed to create and delete secrets in that namespace.
The registry authentication
A base64-encoded username: password string. When set, it is used as-is; otherwise it is computed from username and password.
The registry password
The registry URL
If not defined, the registry host is extracted from the image name.
The registry username
delete booleanstring
trueDelete pod after completion
Defaults to true; set false to keep the pod for debugging.
fileSideCarSpec object
Augment file sidecar spec
Merged into init/sidecar containers used for file transfer; supports template expressions.
fileSidecar Non-dynamic
{
"image": "busybox"
}File transfer sidecar settings
Configure image, resources, and defaults for init/sidecar containers handling uploads/downloads.
inheritClusterConfig booleanstring
falseInherit cluster auto-config
When true, the client config is seeded from the ambient auto-config (in-cluster service account, kube config, env) before applying config, so tuning like config.enableHttp2 works in-cluster without re-declaring credentials. Only applies when config is set; default false.
job Non-dynamic
{
"enabled": "false",
"backoffLimit": "6"
}Run the task as a Kubernetes Job
When enabled, the runner wraps the pod in a batch/v1 Job instead of submitting a raw pod. The Job controller then owns retrying a failed or evicted pod (up to backoffLimit attempts) instead of failing the task outright — an evicted pod is an infrastructure event, not a task/script error.
Requires the runner service account to additionally be allowed get, create, delete, list on jobs, and get on jobs/status.
io.kestra.plugin.ee.kubernetes.runner.Kubernetes-JobConfiguration
6Maximum pod retries before the Job is marked Failed
Passed as the Job's backoffLimit. Default 6, matching the Kubernetes default. Only applies when enabled is true.
Detecting a force-deleted/evicted pod can take up to several minutes per attempt (the underlying wait falls back to a plain status check only after a polling chunk elapses), and waitUntilCompletion is a single budget shared across every attempt. Size waitUntilCompletion generously relative to backoffLimit so eviction-detection latency alone cannot exhaust it before real work has had a chance to run.
falseRun the task as a Kubernetes Job
When true, the pod runs inside a batch/v1 Job instead of as a raw pod, so an evicted or otherwise failed pod is automatically retried by the Job controller instead of failing the task. Default false.
Without podFailurePolicy, the Job controller retries on any pod failure, including the task's own script/command exiting non-zero — not only infrastructure events like eviction. Set podFailurePolicy to distinguish the two.
Raw Kubernetes PodFailurePolicy for the Job
Optional podFailurePolicy merged into the generated Job spec, letting the Job controller distinguish infrastructure failures (e.g. eviction) from application failures based on exit codes or pod conditions. Passed through as-is: refer to the Pod failure policy documentation for the schema. Requires the JobPodFailurePolicy feature gate (enabled by default since Kubernetes 1.31); older or feature-gated clusters reject this field with a clear error. Only applies when enabled is true.
labels object
Add custom pod labels
Merged with Kestra default flow/execution/taskrun labels.
namespace string
defaultNamespace for created pod
Defaults to 'default'; template expressions are allowed.
nodeSelector object
Node selector for scheduling
Assigns the pod to nodes matching the selector (see Assign Pod Nodes).
pluginDefaultsRef Non-dynamicstring
Reference (ref) of the pluginDefaults to apply to this task runner.
podSpec object
Additional YAML spec for the pod
Optional PodSpec merged into the generated pod; Kestra still sets the main container, restartPolicy=Never, volumes, and sidecars. Supports template expressions including {{ workingDir }} resolving to /kestra/working-dir when file I/O is enabled.
To define a spec, refer to the using pods guide from the official Kubernetes documentation.
Any container listed under containers whose name is not "main" is preserved as a user-defined sidecar alongside the Kestra main container. A container named "main" is merged into the Kestra-built main container as a set of defaults — fields such as ports, env, and imagePullPolicy from the user entry are applied first, then containerSpec and Kestra-injected values (image, commands, env vars like WORKING_DIR) take precedence on collision.
For settings that must apply to all containers (e.g. volumeMounts, per-container securityContext), use containerDefaultSpec rather than repeating them per container.
resources
Set main container resources
CPU and memory requests/limits for the main task container.
io.kestra.plugin.ee.kubernetes.runner.Kubernetes-Resources
io.kestra.plugin.ee.kubernetes.runner.Kubernetes-Resource
io.kestra.plugin.ee.kubernetes.runner.Kubernetes-Resource
resume booleanstring
trueResume existing pod on restart
Default true; reconnects to an existing pod for the same taskrun when found.
serviceAccountName string
Choose service account name
Uses the namespace default when omitted; must carry required RBAC.
syncWorkingDirectory booleanstring
falseWhether to synchronize working directory from remote runner back to local one after run.
version Non-dynamicstring
Plugin Version
Defines the version of the plugin to use.
The version must follow the Semantic Versioning (SemVer) specification:
- A single-digit MAJOR version (e.g.,
1). - A MAJOR.MINOR version (e.g.,
1.1). - A MAJOR.MINOR.PATCH version, optionally with any qualifier
(e.g.,
1.1.2,1.1.0-SNAPSHOT).
waitForLogs string
PT30SExtra wait for late logs
Default 30s; allows log streaming to finish after containers exit.
waitUntilCompletion string
PT1HWait for pod completion
Pod wall-clock timeout when task timeout is unset; default 1h.
waitUntilRunning string
PT10MWait for pod to start
Max time for scheduling, image pull, and container start; default 10m.
Metrics
files.retrieved counter
Incremented when output files are retrieved from the pod (only when outputFiles or outputDir are configured).
files.uploaded counter
Incremented when input files are uploaded to the pod (only when inputFiles are configured).
pod.created counter
Incremented when the pod is created.
pod.deleted counter
Incremented when the pod is deleted.
pod.scheduled counter
Incremented when the pod is scheduled onto a node.
task.running counter
Incremented when the main container starts running.