Kubernetes Deployment

Enterprise

Zephyr's Kubernetes deployment option allows you to run the Zephyr edge worker on your own Kubernetes infrastructure. This deployment model provides maximum control over your infrastructure while leveraging Zephyr's deployment and versioning capabilities.

Enterprise Only

Kubernetes deployment is available exclusively for Enterprise customers. If you're interested in deploying Zephyr on your own K8S infrastructure, please contact our sales team to discuss your requirements.

Overview

The Kubernetes edge worker is a containerized service that handles asset uploads and serves your deployed applications. It integrates with:

  • S3-compatible storage (AWS S3, MinIO, Ceph, etc.) for asset storage
  • Redis-compatible KV store for environment configuration and snapshots
  • OpenTelemetry-compatible collectors for OTLP HTTP traces, metrics, and logs

Configuration

The recommended way to configure the worker is using a JSON config file mounted as a Kubernetes Secret. This approach keeps all your configuration in one place and makes it easier to manage secrets securely.

Alternatively, you can use environment variables directly, though this is less recommended for production deployments.

Create a JSON file containing all your configuration. Worker-specific keys use the ZE_WORKER_ prefix; OpenTelemetry keys use the standard OTEL_ prefix:

// Example configuration
{
  "ZE_WORKER_PORT": "8080",
  "ZE_WORKER_JWT_SECRET": "your-secret-key",
  "ZE_WORKER_LOG_LEVEL": "info",
  "ZE_WORKER_DELIMITER": "-",
  "OTEL_SERVICE_NAME": "ze-k8s-workers",
  "OTEL_RESOURCE_ATTRIBUTES": "deployment.environment.name=production",
  "OTEL_METRIC_EXPORT_INTERVAL": "60000",
  "OTEL_EXPORTER_OTLP_ENDPOINT": "http://otel-collector.observability.svc.cluster.local:4318",
  "OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer%20your-token",
  "ZE_WORKER_S3_ENDPOINT": "https://s3.amazonaws.com",
  "ZE_WORKER_S3_REGION": "us-east-1",
  "ZE_WORKER_S3_ACCESS_KEY_ID": "AKIAIOSFODNN7EXAMPLE",
  "ZE_WORKER_S3_SECRET_ACCESS_KEY": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
  "ZE_WORKER_S3_BUCKET": "zephyr-assets",
  "ZE_WORKER_S3_FORCE_PATH_STYLE": "false",
  "ZE_WORKER_S3_CONNECTION_TIMEOUT_MS": "5000",
  "ZE_WORKER_S3_REQUEST_TIMEOUT_MS": "30000",
  "ZE_WORKER_S3_UPLOAD_REQUEST_TIMEOUT_MS": "60000",
  "ZE_WORKER_S3_MAX_SOCKETS": "200",
  "ZE_WORKER_S3_SOCKET_ACQUISITION_WARNING_TIMEOUT_MS": "35000",
  "ZE_WORKER_REDIS_HOST": "redis.default.svc.cluster.local",
  "ZE_WORKER_REDIS_PORT": "6379",
  "ZE_WORKER_REDIS_PASSWORD": "your-redis-password",
  "ZE_WORKER_REDIS_TLS": "true",
  "ZE_WORKER_REDIS_DB": "0",
  "ZE_WORKER_REDIS_PREFIX_ENVS": "{ze-k8s-worker}:envs:",
  "ZE_WORKER_REDIS_PREFIX_SNAPSHOTS": "{ze-k8s-worker}:snapshots:",
  "ZE_WORKER_REPLICA_NAME": "us-east-1",
  "ZE_WORKER_REPLICAS_URLS": [
    "https://ze.eu.example.com",
    "https://ze.ap.example.com",
  ],
}

Health Check Endpoints

The worker exposes the following health check endpoints for Kubernetes probes:

EndpointTypeDescription
GET /healthzLiveness probeAlways returns 200 if the process is running
GET /readyzReadiness probeChecks S3 and Redis connectivity; returns 200 if healthy, 503 if not

Observability

The Kubernetes worker emits OpenTelemetry traces, metrics, and logs over OTLP HTTP. Enable telemetry with any OTEL_EXPORTER_OTLP_* endpoint or by explicitly setting a signal exporter such as OTEL_TRACES_EXPORTER=otlp.

If you set only OTEL_EXPORTER_OTLP_ENDPOINT, the worker treats it as the collector base URL and sends each signal to:

  • Traces: <endpoint>/v1/traces
  • Metrics: <endpoint>/v1/metrics
  • Logs: <endpoint>/v1/logs

Use the signal-specific endpoint variables when your collector exposes separate routes:

{
  "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "http://otel-collector:4318/v1/traces",
  "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT": "http://otel-collector:4318/v1/metrics",
  "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT": "http://otel-collector:4318/v1/logs",
}

Signal-specific endpoint variables export only their configured signal unless a shared base endpoint is also set.

For collectors that require authentication, set OTLP headers using comma-separated key=value pairs. Percent-encode spaces and other special characters:

{
  "OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer%20your-token",
  "OTEL_EXPORTER_OTLP_TRACES_HEADERS": "x-api-key=trace-key",
}

Store header values that contain tokens, API keys, or tenant credentials in a Kubernetes Secret.

Set OTEL_SDK_DISABLED=true to force telemetry off, even when endpoints are configured.

SignalCoverage
TracesHTTP requests, readiness checks, Redis operations, and S3 operations
MetricsHTTP request counts/duration, storage operation counts/duration, checks
LogsStructured worker logs with trace and span IDs when a span is active

Worker stdout is structured JSON:

{
  "timestamp": "2026-06-29T04:31:14.288Z",
  "level": "info",
  "service": "ze-k8s-workers",
  "replica": "primary",
  "message": "Worker listening",
  "server.port": 8080,
  "otel.enabled": true
}

Configuration Reference

Below is the complete reference for all available configuration options. These can be set in your JSON config file or as environment variables.

Bootstrap Option

KeyDescriptionDefaultExample
ZE_WORKER_CONFIG_JSONPath to a JSON config file. When set, values in the file take precedence over process environment variables.(unset)/etc/zephyr/worker-config.json

Required Options

KeyDescriptionExample
ZE_WORKER_JWT_SECRETSecret key for JWT token validationyour-secret-key-here
ZE_WORKER_S3_ENDPOINTS3-compatible storage endpoint URLhttps://s3.amazonaws.com or http://minio:9000
ZE_WORKER_S3_ACCESS_KEY_IDS3 access key IDAKIAIOSFODNN7EXAMPLE
ZE_WORKER_S3_SECRET_ACCESS_KEYS3 secret access keywJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
ZE_WORKER_S3_BUCKETS3 bucket name for storing assetszephyr-assets
ZE_WORKER_REDIS_HOSTRedis-compatible KV store hostnameredis.default.svc.cluster.local

Server Options

KeyDescriptionDefaultExample
ZE_WORKER_PORTHTTP server port80803000
ZE_WORKER_LOG_LEVELLogging levelinfodebug, trace, warn, error, fatal
ZE_WORKER_DELIMITERDelimiter for hostname parsing-. or _

OpenTelemetry Options

KeyDescriptionDefaultExample
OTEL_SDK_DISABLEDDisables OpenTelemetry export(unset)true
OTEL_SERVICE_NAMEService name resource attributeze-k8s-workersze-k8s-workers-prod
OTEL_RESOURCE_ATTRIBUTESAdditional resource attributesdeployment.environment.name from NODE_ENV, otherwise productiondeployment.environment.name=production
OTEL_METRIC_EXPORT_INTERVALOTLP metric export interval in milliseconds6000030000
OTEL_TRACES_EXPORTERTrace exporter selection(unset)otlp or none
OTEL_METRICS_EXPORTERMetrics exporter selection(unset)otlp or none
OTEL_LOGS_EXPORTERLogs exporter selection(unset)otlp or none
OTEL_EXPORTER_OTLP_ENDPOINTBase OTLP HTTP endpoint for all signals(unset)http://otel-collector:4318
OTEL_EXPORTER_OTLP_TRACES_ENDPOINTSignal-specific OTLP HTTP traces endpoint(unset)http://otel-collector:4318/v1/traces
OTEL_EXPORTER_OTLP_METRICS_ENDPOINTSignal-specific OTLP HTTP metrics endpoint(unset)http://otel-collector:4318/v1/metrics
OTEL_EXPORTER_OTLP_LOGS_ENDPOINTSignal-specific OTLP HTTP logs endpoint(unset)http://otel-collector:4318/v1/logs
OTEL_EXPORTER_OTLP_HEADERSBase OTLP HTTP headers for all signals(unset)Authorization=Bearer%20TOKEN
OTEL_EXPORTER_OTLP_TRACES_HEADERSSignal-specific OTLP HTTP traces headers(unset)x-api-key=trace-key
OTEL_EXPORTER_OTLP_METRICS_HEADERSSignal-specific OTLP HTTP metrics headers(unset)x-api-key=metrics-key
OTEL_EXPORTER_OTLP_LOGS_HEADERSSignal-specific OTLP HTTP logs headers(unset)x-api-key=logs-key

S3 Options

KeyDescriptionDefaultExample
ZE_WORKER_S3_REGIONS3 regionus-east-1eu-west-1
ZE_WORKER_S3_FORCE_PATH_STYLEUse path-style URLs (required for MinIO/Ceph)truefalse
ZE_WORKER_S3_CONNECTION_TIMEOUT_MSTimeout for establishing the S3 connection500010000
ZE_WORKER_S3_REQUEST_TIMEOUT_MSTimeout for non-upload S3 requests3000045000
ZE_WORKER_S3_UPLOAD_REQUEST_TIMEOUT_MSTimeout for upload S3 requests60000120000
ZE_WORKER_S3_MAX_SOCKETSMaximum keep-alive sockets used by the S3 client per worker instance200400
ZE_WORKER_S3_SOCKET_ACQUISITION_WARNING_TIMEOUT_MSDelay before warning that requests are queuing behind the S3 socket pool3500060000

Redis Options

KeyDescriptionDefaultExample
ZE_WORKER_REDIS_PORTRedis port63796380
ZE_WORKER_REDIS_PASSWORDRedis password (if required)(empty)your-redis-password
ZE_WORKER_REDIS_TLSEnable TLS for Redis connectionfalsetrue
ZE_WORKER_REDIS_DBRedis database number01, 2, etc.
ZE_WORKER_REDIS_PREFIX_ENVSKey prefix for environment variables{ze-k8s-worker}:envs:{myapp}:envs:
ZE_WORKER_REDIS_PREFIX_SNAPSHOTSKey prefix for snapshots{ze-k8s-worker}:snapshots:{myapp}:snapshots:
Redis Key Prefixes

The curly braces {} in the default prefixes enable Redis Cluster hash tags. This ensures all keys with the same hash tag are stored on the same cluster node, enabling multi-key operations, transactions, and better performance. For standalone Redis instances, the braces have no special meaning but don't cause issues.

Replication Options

KeyDescriptionDefaultExample
ZE_WORKER_REPLICA_NAMEName for this replica instance (enables replication)(empty)us-east-1, eu-west-1
ZE_WORKER_REPLICAS_URLSList of replica worker URLs to sync to (JSON array or comma-separated)[]["https://a.example.com", "https://b.example.com"] or https://a,https://b
Replication Mode

Replication is enabled when ZE_WORKER_REPLICA_NAME is set. The replica name identifies this worker instance in logs.

Using Environment Variables

While the JSON config file is recommended, you can also configure the worker using environment variables directly. This can be useful for simple setups or when integrating with external secret management systems.

Set ZE_WORKER_CONFIG_JSON to the path of your config file. If both are provided, values in the JSON file take precedence over environment variables.

env:
  - name: ZE_WORKER_JWT_SECRET
    valueFrom:
      secretKeyRef:
        name: ze-worker-secrets
        key: jwt-secret
  - name: ZE_WORKER_S3_ENDPOINT
    value: 'https://s3.us-west-2.amazonaws.com'
  - name: ZE_WORKER_S3_ACCESS_KEY_ID
    valueFrom:
      secretKeyRef:
        name: ze-worker-secrets
        key: s3-access-key
  # ... additional environment variables

Scaling and Replication

Zephyr workers support two scaling modes that can be used independently or combined:

ModeStorageReplicationUse Case
Same-region scalingShared S3/RedisNone neededHorizontal scaling, high availability
Multi-regionSeparate per regionHTTP sync between regionsLow latency, geo-distribution

Check worker logs on startup to verify replication:

# Workers with REPLICAS_URLS set (replicate to other regions)
{"level":"info","message":"Replica mode enabled","zephyr.replica":"us-east-1"}
{"level":"info","message":"Replica fan-out configured","zephyr.replica.count":1,"zephyr.replica.urls":["https://ze.eu.example.com"]}

# Workers without REPLICAS_URLS (receive-only, share storage with primary)
{"level":"info","message":"Replica mode enabled","zephyr.replica":"us-east-2"}
{"level":"info","message":"No replica URLs configured; receive-only mode enabled"}

Same-Region Scaling

Multiple workers sharing the same S3 bucket and Redis instance. All workers read/write to the same storage, so no data replication is needed.

All workers use identical config. Only ZE_WORKER_REPLICA_NAME differs:

// US East - Worker 1
{
  "ZE_WORKER_REPLICA_NAME": "us-east-1-worker-1",
  "ZE_WORKER_S3_BUCKET": "zephyr-us-east",
  "ZE_WORKER_REDIS_HOST": "redis-us-east.example.com",
}

Multi-Region Replication

Each region has its own S3 and Redis. One primary worker per region replicates data to other regions' primaries via HTTP sync.

Each region lists other regions' load balancer URLs:

// US East
{
  "ZE_WORKER_REPLICA_NAME": "us-east-1",
  "ZE_WORKER_REPLICAS_URLS": [
    "https://ze.eu.example.com",
    "https://ze.ap.example.com",
  ],
  "ZE_WORKER_S3_BUCKET": "zephyr-us-east",
  "ZE_WORKER_REDIS_HOST": "redis-us-east.example.com",
}

Combined: Multi-Region with Scaling

Multiple workers per region (shared storage) + cross-region replication. All workers in a region replicate to one worker per other region.

All workers have ZE_WORKER_REPLICAS_URLS pointing to other regions' load balancers:

WorkerZE_WORKER_REPLICA_NAMEZE_WORKER_REPLICAS_URLS
US Worker 1us-east-1["https://ze.eu.example.com"]
US Worker 2us-east-2["https://ze.eu.example.com"]
EU Worker 1eu-west-1["https://ze.us.example.com"]
EU Worker 2eu-west-2["https://ze.us.example.com"]
Important
  • Same JWT secret: All workers across all regions must share ZE_WORKER_JWT_SECRET
  • One target per region: Include only one URL per region in ZE_WORKER_REPLICAS_URLS (typically the load balancer)
  • Eventual consistency: Cross-region replication is asynchronous

Troubleshooting

Common Issues

Worker fails to start

  1. Verify all required configuration options are set
  2. Check that S3 endpoint is reachable from within the cluster
  3. Ensure Redis host is resolvable and accessible
  4. Check the worker logs using kubectl

Readiness probe failing

  1. Check S3 bucket exists and credentials have read/write access
  2. Verify Redis connection (host, port, password, TLS settings)
  3. Review worker logs for specific error messages

Telemetry is not reaching the collector

  1. Confirm the collector accepts OTLP HTTP, not only OTLP gRPC
  2. Verify the worker pod can resolve and connect to the collector service
  3. Use the collector base URL for OTEL_EXPORTER_OTLP_ENDPOINT, for example http://otel-collector:4318
  4. Include the full /v1/traces, /v1/metrics, or /v1/logs path when using signal-specific endpoints
  5. Configure OTLP headers when the collector requires a bearer token, API key, or tenant header
  6. Confirm OTEL_SDK_DISABLED is not set to true

Logs are too verbose

Set ZE_WORKER_LOG_LEVEL to warn or error. You can keep OpenTelemetry enabled while reducing stdout and exported log volume.

Assets not serving correctly

  1. Confirm ZE_WORKER_DELIMITER matches your DNS configuration
  2. Verify S3 bucket policy allows the worker to read objects
  3. Check that the Ingress or load balancer is routing traffic correctly

Getting Help

If you encounter issues with your Kubernetes deployment, reach out to your Zephyr account representative or contact us on Discord.