| name | kubernetes-workloads |
| description | Manage Zeabur Kubernetes workloads directly with kubectl: create or update Deployments, inject Zeabur IDs and environment variables, change commands, limits, replicas, health checks, or scheduled restarts. Use whenever a request changes a service's running containers or lifecycle without the Zeabur backend. |
Read ../../references/kubernetes.md before changing a workload. It supplies the kubectl-only boundary, identity contract, naming defaults, and mutation loop.
Inputs and inventory
Require the target cluster context, environment ID, service ID, and requested outcome. Also require the container name for a multi-container pod. For a new workload, require image, port, and the project/user IDs to inject. For a command replacement, distinguish an argv from a shell command.
Inventory the candidate first:
kubectl -n "$NS" get deploy,sts -l "zeabur_service_id=$ZEABUR_SERVICE_ID"
kubectl -n "$NS" get pods -l "zeabur_service_id=$ZEABUR_SERVICE_ID" \
-o custom-columns=NAME:.metadata.name,READY:.status.containerStatuses[*].ready,IMAGE:.spec.containers[*].image
Select exactly one controller. Preserve its existing selector and Service relationship. A new standalone workload uses a stable selector containing only app.kubernetes.io/name: service-<service-id>; put the Zeabur identity labels on both the Deployment and pod template.
Complete this step only when the controller, container, and current rollout revision are known.
Deployments, image, command, and variables
For an existing Deployment, make narrow imperative changes:
kubectl -n "$NS" set image deployment/$WORKLOAD "$CONTAINER=$IMAGE"
kubectl -n "$NS" set env deployment/$WORKLOAD \
ZEABUR=1 \
ZEABUR_PROJECT_ID="$ZEABUR_PROJECT_ID" \
ZEABUR_SERVICE_ID="$ZEABUR_SERVICE_ID" \
ZEABUR_ENVIRONMENT_ID="$ZEABUR_ENVIRONMENT_ID" \
ZEABUR_USER_ID="$ZEABUR_USER_ID" \
ZEABUR_REGION="$ZEABUR_REGION"
Add user environment values with kubectl set env; source secret values from a Secret through a small server-side-apply fragment rather than placing a secret literal on the command line. Reconcile a removed environment variable explicitly with kubectl set env deployment/$WORKLOAD KEY-.
Replace a command with a minimal fragment that names the existing container. Use command and args as argv. Wrap an intentional shell program as command: ["/bin/sh", "-c"] and one args element; do not split it on whitespace.
apiVersion: apps/v1
kind: Deployment
metadata:
name: <workload>
namespace: environment-<environment-id>
spec:
template:
spec:
containers:
- name: <container>
command: ["/bin/sh", "-c"]
args: ["exec ./start-server --port $PORT"]
Apply the fragment through the shared field manager. A command or args update produces a new ReplicaSet; wait for that rollout before reporting success.
Resources and replicas
Use Kubernetes quantities, not decimal approximations: CPU 250m, memory 512Mi, ephemeral storage 1Gi. Requests reserve scheduling capacity; limits cap execution. Keep each requested resource in the same update so the scheduler sees a coherent pod shape.
kubectl -n "$NS" set resources deployment/$WORKLOAD --containers="$CONTAINER" \
--requests=cpu=250m,memory=256Mi,ephemeral-storage=512Mi \
--limits=cpu=500m,memory=512Mi,ephemeral-storage=1Gi
kubectl -n "$NS" scale deployment/$WORKLOAD --replicas=3
Before increasing replicas, inspect every mounted PVC. A ReadWriteOnce claim can make multi-replica scheduling fail unless the storage driver supports the chosen topology. State this conflict instead of claiming a successful scale from the desired replica count alone.
Health checks
Match the backend's baseline health semantics: use a startup probe to tolerate initialization and a readiness probe to gate traffic. It uses the same HTTP or TCP handler for both:
startupProbe:
httpGet: {path: /healthz, port: 8080}
failureThreshold: 36
periodSeconds: 5
successThreshold: 1
readinessProbe:
httpGet: {path: /healthz, port: 8080}
failureThreshold: 3
periodSeconds: 10
successThreshold: 1
For TCP, replace httpGet with tcpSocket: {port: 8080}. Add a liveness probe only when the requested behavior is to restart a process that becomes unhealthy after startup; startup and readiness alone prevent premature routing without adding a restart loop. Verify the probe path and port from the container, then verify Ready endpoints after rollout.
Scheduled restart
A scheduled restart is a Kubernetes CronJob that patches the target Deployment; it must not call a Zeabur HTTP endpoint. First create a namespaced ServiceAccount, Role, and RoleBinding granting get, list, and patch only on deployments in $NS. Use a cluster-approved image containing a kubectl version compatible with the API server.
The CronJob has these safe lifecycle settings:
spec:
schedule: "0 3 * * *"
timeZone: "Etc/UTC"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 1
jobTemplate:
spec:
backoffLimit: 0
ttlSecondsAfterFinished: 300
activeDeadlineSeconds: 1800
template:
spec:
serviceAccountName: restart-<service-id>
restartPolicy: Never
containers:
- name: restart
image: <approved-kubectl-image>
command: ["kubectl"]
args: ["-n", "environment-<environment-id>", "rollout", "restart", "deployment/<workload>"]
Apply its RBAC and CronJob together. Verify the schedule, service account, and kubectl auth can-i patch deployments --as=system:serviceaccount:$NS:<service-account> -n "$NS". Removing the CronJob disables automatic restarts; it does not restart the service.
Completion
After every workload mutation:
kubectl -n "$NS" rollout status deployment/$WORKLOAD --timeout=5m
kubectl -n "$NS" get deployment/$WORKLOAD
kubectl -n "$NS" get pods -l "zeabur_service_id=$ZEABUR_SERVICE_ID"
kubectl -n "$NS" get endpointslice -l "kubernetes.io/service-name=$SERVICE_NAME"
Report the controller, new revision, desired/available replicas, image digest or image reference, changed probe/resource/command fields, and any unsatisfied prerequisite. The operation is complete only when the requested state is present and every expected replica is Available and Ready.