创建第一个 Sandbox

本指南将创建一个 Python Sandbox,等待其变为 Ready,执行命令,暂停并恢复它,然后删除它。

开始前准备

  • 安装并验证 Agent Sandbox v0.5.4-1。
  • 将 kubectl 连接到目标业务集群,而不是 global 集群。
  • 确保业务集群能够拉取 docker-mirrors.alauda.cn/library/python:3.12-alpine。
  • 在本地安装 Python 3,以生成未来的 RFC3339 过期时间戳。

在应用或删除任何资源之前,请验证当前集群:

kubectl config current-context

仅当输出为预期的业务集群时,才继续。

创建 Namespace 和过期时间

设置 Namespace,并创建一个 30 分钟后的过期时间:

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 是一个绝对 RFC3339 时间戳。它不是空闲超时时间,也不会因命令执行或网络活动而自动延长。

创建 Sandbox

应用一个带有受限兼容安全上下文的 v1beta1 Sandbox:

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

控制器会在相同的 Namespace 中管理一个名为 python-sandbox 的 Pod。

等待 Ready

等待 Sandbox 的 Ready condition,并检查资源:

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"

如果等待超时,请在继续之前检查 Sandbox、Pod、事件以及控制器日志。

运行命令

在 Sandbox 容器中执行 Python:

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

预期输出包括:

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

暂停和恢复

暂停 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

恢复它,并再次等待 Ready:

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

在 v0.5.4 中,当 Sandbox 运行时,Suspended condition 仍然存在。客户端必须检查其布尔状态,而不是使用 condition 是否存在作为状态检查。

删除 Sandbox

在删除资源之前,请验证当前上下文和 $BUSINESS_NAMESPACE。

在练习完成后删除 Sandbox:

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

由于此示例使用 shutdownPolicy: Delete,因此当达到 shutdownTime 时,控制器也会删除 Sandbox。请不要将 CRD 作为常规业务清理的一部分进行删除。