Skip to content

Kubernetes Integration

EMB provides native Kubernetes integration, allowing you to run tasks directly on pods in your cluster and manage deployments.

The kubernetes executor runs tasks on pods in your Kubernetes cluster, complementing the local and container (Docker Compose) executors.

tasks:
migrate:
script: npm run migrate
executors:
- kubernetes

Use the kubernetes executor when you need to:

  • Run tasks on a deployed instance of your application
  • Execute database migrations on production/staging environments
  • Debug issues in a running cluster
  • Run one-off commands without local setup
tasks:
db-migrate:
description: Run database migrations on the cluster
executors:
- kubernetes
script: npm run migrate
console:
description: Open Rails console on production
interactive: true
executors:
- kubernetes
script: rails console

Use the --executor flag to run tasks on Kubernetes:

Terminal window
# Run migration on the cluster
emb run db-migrate --executor kubernetes

Configure Kubernetes defaults in your .emb.yml:

defaults:
kubernetes:
namespace: staging # Default namespace
selectorLabel: app.kubernetes.io/component # Label for pod selection (default)

Override settings per component:

api/Embfile.yml
kubernetes:
selector: app=api,tier=backend # Custom label selector
container: main # For multi-container pods
OptionDescriptionDefault
namespaceDefault Kubernetes namespacedefault
selectorLabelLabel name used to find component podsapp.kubernetes.io/component
OptionDescription
selectorCustom label selector (e.g., app=api,env=prod)
containerContainer name for multi-container pods

EMB resolves the namespace in this order of precedence:

  1. Environment variable: K8S_NAMESPACE
  2. Configuration: defaults.kubernetes.namespace
  3. Default: default
Terminal window
# Set environment variable
export K8S_NAMESPACE=production
emb run migrate --executor kubernetes
# Or configure in .emb.yml
# defaults:
# kubernetes:
# namespace: production

By default, EMB finds pods using the label app.kubernetes.io/component={component-name}:

Terminal window
# For component "api", EMB looks for pods with:
# app.kubernetes.io/component=api

If your pods use different labels, configure a custom selector:

# Component with custom selector
kubernetes:
selector: app=my-api,environment=production

To change the default label name project-wide:

.emb.yml
defaults:
kubernetes:
selectorLabel: app # Now uses: app={component-name}

For pods with multiple containers (sidecars, init containers, etc.), specify which container to use:

worker/Embfile.yml
kubernetes:
container: main # Execute in the 'main' container, not the sidecar

If not specified and the pod has multiple containers, EMB will error with a helpful message listing available containers.

EMB provides commands for interacting with your Kubernetes deployments:

Open a shell in a running pod:

Terminal window
emb kubernetes shell <COMPONENT> [OPTIONS]

Options:

  • -n, --namespace <name> - Target namespace
  • -s, --shell <shell> - Shell to use (default: /bin/sh)

Examples:

Terminal window
emb kubernetes shell api
emb kubernetes shell api --namespace production
emb kubernetes shell api --shell /bin/bash

View logs from pods:

Terminal window
emb kubernetes logs <COMPONENT> [OPTIONS]

Options:

  • -n, --namespace <name> - Target namespace
  • -f, --follow - Follow log output
  • --tail <lines> - Number of lines to show

Examples:

Terminal window
emb kubernetes logs api
emb kubernetes logs api --follow
emb kubernetes logs api --namespace production --tail 100

List pods for a deployment:

Terminal window
emb kubernetes ps <COMPONENT> [OPTIONS]

Options:

  • -n, --namespace <name> - Target namespace

Restart pods for a deployment:

Terminal window
emb kubernetes restart <COMPONENT> [OPTIONS]

Options:

  • -n, --namespace <name> - Target namespace

For tasks requiring user input, mark them as interactive:

tasks:
console:
description: Open application console
interactive: true
executors:
- kubernetes
script: rails console

This ensures:

  • TTY is allocated for the pod exec
  • stdin is connected for interactive input
  • SIGINT (Ctrl+C) is properly handled
.emb.yml
project:
name: myapp
defaults:
kubernetes:
namespace: ${env:K8S_NAMESPACE:-staging}
selectorLabel: app.kubernetes.io/component
components:
api:
kubernetes:
container: app # Multi-container pod
tasks:
migrate:
description: Run database migrations
executors:
- kubernetes
script: npm run db:migrate
console:
description: Open Rails console
interactive: true
executors:
- kubernetes
script: rails console
worker:
kubernetes:
selector: app=worker,tier=background
tasks:
process:
description: Process pending jobs
executors:
- kubernetes
script: npm run jobs:process
Error: No ready pods found for component "api" in namespace "production"

Solutions:

  • Check pod status: kubectl get pods -n production -l app.kubernetes.io/component=api
  • Verify the label selector matches your pod labels
  • Ensure pods are in Ready state
Error: Pod "api-xyz" has multiple containers, explicit container config required

Solution: Add container to your component’s kubernetes config:

kubernetes:
container: main
Error: Container "main" not found in pod "api-xyz"

Solution: Check available containers and update your config:

Terminal window
kubectl get pod api-xyz -o jsonpath='{.spec.containers[*].name}'