Create Your First Sandbox

This guide creates a Python Sandbox, waits for it to become Ready, executes a command, suspends and resumes it, and then deletes it.

Before You Begin

  • Install and verify Agent Sandbox v0.5.4-1.
  • Connect kubectl to the target workload cluster, not the global cluster.
  • Ensure the workload cluster can pull docker-mirrors.alauda.cn/library/python:3.12-alpine.
  • Install Python 3 locally to generate a future RFC3339 expiration timestamp.

Verify the active cluster before applying or deleting any resource:

kubectl config current-context

Continue only when the output is the intended workload cluster.

Create a Namespace and Expiration Time

Set the namespace and create an expiration time 30 minutes in the future:

export BUSINESS_NAMESPACE=agent-demo
export SANDBOX_EXPIRE_AT="$(python3 -c 'from datetime import datetime, timedelta, timezone; print((datetime.now(timezone.utc) + timedelta(minutes=30)).strftime("%Y-%m-%dT%H:%M:%SZ"))')"

kubectl create namespace "$BUSINESS_NAMESPACE" \
  --dry-run=client -o yaml | kubectl apply -f -

shutdownTime is an absolute RFC3339 timestamp. It is not an idle timeout and is not automatically extended by commands or network activity.

Create the Sandbox

Apply a v1beta1 Sandbox with a restricted-compatible security context:

cat <<EOF | kubectl apply -n "$BUSINESS_NAMESPACE" -f -
apiVersion: agents.x-k8s.io/v1beta1
kind: Sandbox
metadata:
  name: python-sandbox
spec:
  operatingMode: Running
  shutdownPolicy: Delete
  shutdownTime: "${SANDBOX_EXPIRE_AT}"
  podTemplate:
    metadata:
      labels:
        app.kubernetes.io/name: agent-sandbox-workload
    spec:
      automountServiceAccountToken: false
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        runAsGroup: 1000
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: python
          image: docker-mirrors.alauda.cn/library/python:3.12-alpine
          command: ["sh", "-c", "sleep 1800"]
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
EOF

The controller manages a Pod named python-sandbox in the same namespace.

Wait for Ready

Wait for the Sandbox Ready condition and inspect the resources:

kubectl wait --for=condition=Ready sandbox/python-sandbox \
  -n "$BUSINESS_NAMESPACE" \
  --timeout=180s

kubectl get sandbox python-sandbox -n "$BUSINESS_NAMESPACE"
kubectl get pod python-sandbox -n "$BUSINESS_NAMESPACE"

If the wait times out, inspect the Sandbox, Pod, events, and controller logs before continuing.

Run a Command

Execute Python in the Sandbox container:

kubectl exec -n "$BUSINESS_NAMESPACE" python-sandbox -c python -- \
  python -c 'import socket; print("host=" + socket.gethostname()); print("sandbox-ready-check=ok")'

Expected output includes:

host=python-sandbox
sandbox-ready-check=ok

Suspend and Resume

Suspend the Sandbox:

kubectl patch sandbox python-sandbox \
  -n "$BUSINESS_NAMESPACE" \
  --type=merge \
  -p '{"spec":{"operatingMode":"Suspended"}}'

kubectl wait --for=condition=Suspended=True sandbox/python-sandbox \
  -n "$BUSINESS_NAMESPACE" \
  --timeout=180s

Resume it and wait for Ready again:

kubectl patch sandbox python-sandbox \
  -n "$BUSINESS_NAMESPACE" \
  --type=merge \
  -p '{"spec":{"operatingMode":"Running"}}'

kubectl wait --for=condition=Ready=True sandbox/python-sandbox \
  -n "$BUSINESS_NAMESPACE" \
  --timeout=180s

In v0.5.4, the Suspended condition remains present while the Sandbox is running. Clients must inspect its boolean status instead of using condition presence as the state check.

Delete the Sandbox

Verify the active context and $BUSINESS_NAMESPACE before deleting the resource.

Delete the Sandbox when the exercise is complete:

kubectl config current-context
kubectl delete sandbox python-sandbox -n "$BUSINESS_NAMESPACE"

Because this example uses shutdownPolicy: Delete, the controller also deletes the Sandbox when shutdownTime is reached. Do not delete the CRD as part of ordinary workload cleanup.