Mount in Kubernetes
Mount Tonbo Artifacts inside a Kubernetes pod on EKS, GKE, AKS, or kind.
For pods on EKS, GKE, AKS, or kind. A bare Linux host has its own page; generic Docker / Podman containers have one too.
Tonbo Artifacts mounts via FUSE. Inside Kubernetes that needs one of:
- a privileged pod, or
- the
SYS_ADMINcapability plus/dev/fuseexposed as a device.
Default Pod Security Standard restricted blocks both. baseline allows the
SYS_ADMIN path. privileged allows either. A CSI-driver path that would let
fully restricted clusters mount without privileged workloads is not shipped
in v0 (see the note at the bottom of this page).
The rest of this page walks an EKS cluster start-to-mount end-to-end. The pod spec and command sequence work unchanged on GKE, AKS, and kind; only the cluster-creation step differs.
1. EKS cluster
Smallest viable cluster, one managed node:
eksctl create cluster \
--name tonbo-eks-test \
--region us-west-1 \
--node-type t3.medium \
--nodes 1 \
--node-volume-size 20 \
--managed
This takes ~15 minutes for the control plane plus ~5 for the node group. The
default Amazon Linux 2023 node ships with the FUSE kernel module already
loaded and /dev/fuse present.
eksctl writes a kubeconfig entry. Verify:
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# ip-192-168-23-209.us-west-1.compute.internal Ready <none> 2m v1.34.7-eks-7fcd7ec
Confirm /dev/fuse is on the node and the kernel ships FUSE:
kubectl debug node/$(kubectl get nodes -o name | head -1) -it --image=busybox -- ls -la /host/dev/fuse
# crw-rw-rw- 1 root root 10, 229 May 16 04:43 /host/dev/fuse
2. Pod spec
artifacts-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: artifacts-test
spec:
restartPolicy: Never
containers:
- name: artifacts
image: ubuntu:24.04
command: ["sleep", "infinity"]
securityContext:
privileged: true
volumeMounts:
- name: fuse-device
mountPath: /dev/fuse
volumes:
- name: fuse-device
hostPath:
path: /dev/fuse
type: CharDevice
Two non-default bits:
securityContext.privileged: true, needed for themount()syscall the FUSE driver calls. Without this the install proceeds butartifacts mountfails withfusermount: permission denied.- The
hostPathdevice volume pulls/dev/fusefrom the node into the container at the same path. The container's own/devfilesystem is a tmpfs by default and doesn't expose/dev/fuseautomatically even underprivileged.
Apply and wait:
kubectl apply -f artifacts-pod.yaml
kubectl wait --for=condition=Ready pod/artifacts-test --timeout=120s
3. Install + login + mount inside the pod
kubectl exec -it artifacts-test -- bash
Then follow the standard Quickstart:
apt-get update -qq && apt-get install -y -qq curl ca-certificates
curl -fsSL https://artifacts.tonbo.dev/install.sh | bash
# ==> Platform: linux-x86_64
# ==> Latest release: 25a4c23c1f0c
# ==> fuse3 already installed
# ==> sha256 ok: 07e264d209c99c957ee8812ce1a3eb8cc5b28acbb9b67e52a9fad8cf80fd875e
# ==> Installed: /usr/local/bin/artifacts
artifacts --version
# artifacts version 0.0.1-dev
artifacts login --manual-code # see Headless hosts below
artifacts workspace create eks-demo --backend managed
# Workspace eks-demo is active.
mkdir -p /mnt/work
artifacts mount eks-demo /mnt/work
# Mounting /mnt/work ...
Verify:
mount | grep tonbo
# Tonbo:tzu-3833a78-eks-demo-0ed546c4dc38 on /mnt/work type fuse.juicefs
# (rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072)
ls /mnt/work
# .accesslog .config .stats .trash plus your data
echo "hello from EKS pod on AL2023 kernel 6.12" > /mnt/work/eks.txt
cat /mnt/work/eks.txt
mkdir -p /mnt/work/agent-memory/2026/05/case-a/notes
echo "deep" > /mnt/work/agent-memory/2026/05/case-a/notes/intake.txt
find /mnt/work -type f
# /mnt/work/.accesslog
# /mnt/work/.stats
# /mnt/work/.config
# /mnt/work/eks.txt
# /mnt/work/agent-memory/2026/05/case-a/notes/intake.txt
4. Headless login
EKS pods don't have a browser, so the loopback OAuth callback can't reach the CLI. Use one of:
-
API key (preferred for non-interactive flows): mint a
tbo_*key in your User Center account, ship it to the pod as a Kubernetes secret, and export it. The CLI auto-detects it, so noartifacts loginis needed:export TONBO_API_KEY=tbo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxSee API keys.
-
--manual-code: the CLI prints an auth URL; open it in any browser, sign in, paste the one-time code back into the pod terminal.
5. Tear down
From inside the pod, unmount and delete the workspace first:
artifacts unmount /mnt/work
artifacts workspace delete eks-demo
Then exit and clean up the cluster:
kubectl delete pod artifacts-test
eksctl delete cluster --name tonbo-eks-test --region us-west-1
The cluster delete tears down the eksctl-managed VPC, NAT gateway, nodegroup, and control plane. Allow ~10 minutes.
Troubleshooting
The pod isn't actually privileged. Re-check securityContext.privileged
and confirm your namespace doesn't have a restricted Pod Security
Standard label blocking it:
kubectl get namespace default -o jsonpath='{.metadata.labels}'/dev/fuse isn't reaching the container. Confirm the hostPath volume
is on the spec and the node has /dev/fuse (kubectl debug node/<name> -it --image=busybox -- ls -la /host/dev/fuse).
Usually a Pod Security Standard violation. Check:
kubectl describe pod artifacts-test | tail -20If your cluster runs restricted PSS on default namespace, create a
dedicated namespace with the privileged label:
kubectl create namespace tonbo-test
kubectl label namespace tonbo-test pod-security.kubernetes.io/enforce=privileged
kubectl apply -n tonbo-test -f artifacts-pod.yamlCSI driver (not in v0)
A CSI driver, Helm chart, and StorageClass that would let workload pods
consume workspaces through a PersistentVolumeClaim (with the kubelet
performing the FUSE mount, so the workload stays unprivileged) do not ship
in v0. There is no Helm chart to install today.
In v0, mounting in Kubernetes requires the privileged or SYS_ADMIN +
/dev/fuse path shown above. If you need unprivileged mounts on a hardened
restricted cluster, reach out and tell us about your requirements.