Kubernetes Kubernetes

Kubernetes Kubernetes

Certified
Enterprise Edition

Run tasks inside Kubernetes pods

This plugin is only available in the Enterprise Edition (EE).

To generate output files you can:

  • Use the outputFiles property 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 the OUTPUT_DIR environment 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, list
  • pods/log: get, watch
  • pods/exec: get, watch
  • secrets: create, delete (only required when credentials is 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, list
  • jobs/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"]
yaml
type: io.kestra.plugin.ee.kubernetes.runner.Kubernetes

Execute a Shell command.

yaml
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.

yaml
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.

yaml
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
DefaultALWAYS
Possible Values
IF_NOT_PRESENTALWAYSNEVER

Image pull policy for the task container

Configure Kubernetes cluster connection

Cluster endpoint, auth, and TLS settings used by the runner.

Definitions
apiVersionstring
Defaultv1

API version

API group version used by the client. Default v1.

caCertDatastring

CA certificate data

Base64-encoded PEM CA bundle. Whitespace is stripped automatically.

caCertFilestring

CA certificate file

Path to a PEM CA bundle.

clientCertDatastring

Client certificate data

Base64-encoded client cert. Whitespace is stripped automatically.

clientCertFilestring

Client certificate file

clientKeyAlgostring
DefaultRSA

Client key algorithm

Algorithm for the client key. Default RSA.

clientKeyDatastring

Client key data

Base64-encoded client key. Whitespace is stripped automatically.

clientKeyFilestring

Client key file

clientKeyPassphrasestring

Client key passphrase

disableHostnameVerificationbooleanstring

Disable hostname verification

Disables TLS hostname checks. Avoid in production clusters.

enableHttp2booleanstring

Enable HTTP/2

Off by default (HTTP/1.1, the prior behavior). Enable to use HTTP/2, which keeps long-lived watch/log streams alive better through proxies like GKE konnectivity.

keyStoreFilestring

Keystore file

keyStorePassphrasestring

Keystore passphrase

masterUrlstring
Defaulthttps://kubernetes.default.svc

Kubernetes API URL

API server endpoint. Default https://kubernetes.default.svc.

maxConcurrentRequestsintegerstring

Max concurrent HTTP requests

Caps total concurrent HTTP requests issued by this client. Lower this when running many concurrent tasks against a rate-limited API server (e.g. GKE). Fabric8 default: 64.

maxConcurrentRequestsPerHostintegerstring

Max concurrent HTTP requests per host

Caps concurrent HTTP requests to a single host (the API server). Fabric8 default: 5.

namespacestring

Default namespace

Namespace used when resources omit a namespace.

oauthTokenstring

OAuth token

oauthTokenProvider

Dynamically refreshes the OAuth token used to authenticate with the Kubernetes API. Use this when authenticating via a cloud provider (e.g. GCP, AWS, Azure) whose tokens are short-lived (typically 1 hour). Without this, long-running tasks will fail with an unauthorized error once the initial token expires. The provider executes a Kestra task to fetch a fresh token each time the Kubernetes client needs to re-authenticate.

Dynamically refreshes an OAuth token by executing a Kestra task each time the Kubernetes client needs to authenticate. This is essential for cloud providers (e.g. GCP, AWS, Azure) whose tokens are short-lived (typically 1 hour). Without automatic refresh, long-running tasks will fail with an unauthorized error once the initial token expires.

cachestring
DefaultPT5M
Formatduration

Token cache duration

How long a fetched token is reused before the provider executes the task again. Caching avoids hammering the token endpoint on every Kubernetes API call. Defaults to 5 minutes (PT5M). Set to PT0S to disable caching.

outputstring

Token output expression

An expression to extract the token value from the task output, e.g. {{ accessToken.tokenValue }}.

task

Token provider task

A Kestra task that fetches a fresh OAuth token. This task is executed each time the Kubernetes client needs to authenticate, enabling automatic token refresh for long-running operations.

passwordstring

Password

trustCertsbooleanstring

Trust all certificates

When true, skips TLS cert validation. Use only for testing.

trustStoreFilestring

Truststore file

trustStorePassphrasestring

Truststore passphrase

usernamestring

Username

watchReconnectIntervalstring

Watch reconnect interval

Backoff between watch reconnect attempts. Increase to prevent reconnect storms under API server pressure. Fabric8 default: 1s.

websocketPingIntervalstring

WebSocket ping interval

Keepalive ping on exec/log connections so idle streams aren't dropped by a proxy (e.g. GKE konnectivity). Only honored by the OkHttp backend. 0 disables.

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 container
  • securityContext — enforce a consistent security posture across all containers
  • resources — set default limits/requests that containers can override individually
  • env — 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

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.

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.

Definitions

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.

authstring

The registry authentication

A base64-encoded username: password string. When set, it is used as-is; otherwise it is computed from username and password.

passwordstring

The registry password

registrystring

The registry URL

If not defined, the registry host is extracted from the image name.

usernamestring

The registry username

Defaulttrue

Delete pod after completion

Defaults to true; set false to keep the pod for debugging.

Augment file sidecar spec

Merged into init/sidecar containers used for file transfer; supports template expressions.

Default{ "image": "busybox" }

File transfer sidecar settings

Configure image, resources, and defaults for init/sidecar containers handling uploads/downloads.

Definitions
defaultSpecobject

Default spec for file transfer containers

Overrides containerDefaultSpec for the init and sidecar containers that move files. Accepts Pod container fields such as securityContext, volumeMounts, resources, and env; useful for hardening or adding mounts used only by file transfer helpers.

Example: fileSidecar: defaultSpec: securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true volumeMounts: - name: tmp mountPath: /tmp

imagestring
Defaultbusybox

Image for file sidecar

Container image used by the init container (uploads input files) and the sidecar (downloads output files). Defaults to busybox.

The image must provide, on its PATH: a POSIX shell (sh), test/[, and sleep — required by the polling script that waits for the transfer to complete before the container exits. find and wc are also used, on a best-effort basis, to verify that uploaded files were fully transferred; if they're missing, verification is skipped rather than failing the task.

resourcesobject

Configure sidecar resource requests/limits

Optional Kubernetes resources block applied to the file transfer sidecar.

Defaultfalse

Inherit 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.

Default{ "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.

Definitions
backoffLimitintegerstring
Default6

Maximum 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.

enabledbooleanstring
Defaultfalse

Run 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.

podFailurePolicyobject

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.

Add custom pod labels

Merged with Kestra default flow/execution/taskrun labels.

Defaultdefault

Namespace for created pod

Defaults to 'default'; template expressions are allowed.

Node selector for scheduling

Assigns the pod to nodes matching the selector (see Assign Pod Nodes).

Reference (ref) of the pluginDefaults to apply to this task runner.

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.

Set main container resources

CPU and memory requests/limits for the main task container.

Definitions
limit
cpustring
memorystring
request
cpustring
memorystring
Defaulttrue

Resume existing pod on restart

Default true; reconnects to an existing pod for the same taskrun when found.

Choose service account name

Uses the namespace default when omitted; must carry required RBAC.

Defaultfalse

Whether to synchronize working directory from remote runner back to local one after run.

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).
DefaultPT30S

Extra wait for late logs

Default 30s; allows log streaming to finish after containers exit.

DefaultPT1H

Wait for pod completion

Pod wall-clock timeout when task timeout is unset; default 1h.

DefaultPT10M

Wait for pod to start

Max time for scheduling, image pull, and container start; default 10m.

Incremented when output files are retrieved from the pod (only when outputFiles or outputDir are configured).

Incremented when input files are uploaded to the pod (only when inputFiles are configured).

Incremented when the pod is created.

Incremented when the pod is deleted.

Incremented when the pod is scheduled onto a node.

Incremented when the main container starts running.