Install any skill in seconds. Free to start, no credit card required.
Get Started Free →KubeSphere Fluid management Skill. Use when user asks to install or enable Fluid, check Fluid status, view Fluid pods/logs/CRDs, create or update Dataset, AlluxioRuntime, JuiceFSRuntime, or ThinRuntime, perform DataLoad or cache warming, scale runtime, or troubleshoot Fluid issues in KubeSphere.
.claude/skills/kubesphere-kubesphere-fluid/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 658% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 208% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 228% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 660% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 170% | 0% |
Use this skill for the full Fluid lifecycle in KubeSphere:
InstallPlanDataset manifests with mount configurationAlluxioRuntime, JuiceFSRuntime, or ThinRuntime manifests for cachingOut of scope by default:
DataBackup or GooseFSIf the user explicitly asks for those, acknowledge that they are Fluid capabilities but treat them as a follow-up task.
InstallPlan YAML, Dataset YAML, AlluxioRuntime YAML, kubectl commands, or a short ordered procedure.InstallPlan.fluid only if the user context or cluster output does not expose a different resource name.upgradeStrategy: Manual unless the user explicitly asks for something else.bashkubectl api-resources --api-group data.fluid.io
data.fluid.io/v1alpha1data.fluid.io/v1alpha1data.fluid.io/v1alpha1data.fluid.io/v1alpha1ALWAYS use the exact values provided by the user. Never substitute or guess values.
When generating YAML manifests:
| Parameter | Rule | |-----------|------| | name | MUST use user's value exactly | | namespace | MUST use user's value exactly | | mountPoint | MUST use user's value exactly (e.g., s3://bucket, oss://bucket, pvc://, https://) | | replicas | MUST use user's value exactly | | quota | MUST use user's value exactly | | mediumType | Use user's value, default to MEM if not specified | | path | Use user's value, default to /dev/shm if not specified |
WRONG: Using pvc:// when user specified s3://mybucket/spark-data RIGHT: Using exactly what user provided: s3://mybucket/spark-data
Each operation has a specific scope. Do NOT create additional resources unless user explicitly asks.
| User Request | Output Scope | |--------------|--------------| | "Create Dataset" | Only Dataset YAML | | "Create AlluxioRuntime" | Only AlluxioRuntime YAML (NOT Dataset) | | "Create JuiceFSRuntime" | Only JuiceFSRuntime YAML (NOT Dataset) | | "Create ThinRuntime" | Only ThinRuntime YAML (NOT Dataset) | | "Create Dataset with Runtime" | Both Dataset + Runtime YAML | | "Create DataLoad" | Only DataLoad YAML |
Example:
When the user asks for precision, prove the version mapping first:
bash# Discover KubeSphere extension version kubectl get extensionversions.kubesphere.io -l kubesphere.io/extension-ref=fluid kubectl get extensionversion fluid-<version> -o yaml # Discover Fluid runtime image or controller version kubectl get pods -n fluid-system -o wide kubectl get deploy -n fluid-system alluxio-runtime-controller -o jsonpath='{.spec.template.spec.containers[*].image}' kubectl describe pod -n fluid-system <fluid-pod>
If these commands disagree with assumed mappings, prefer cluster output over defaults.
This section provides three approaches for querying Fluid status:
Use curl with environment variables for querying KubeSphere extension status and multi-cluster resources.
Environment Variables:
bashexport KS_HOST="http://<kubesphere-host>" # KubeSphere console URL (required) export KS_USERNAME="admin" # Username (default: admin) export KS_PASSWORD="<password>" # Password (required)
Helper Functions (add to ~/.bashrc or use directly):
bash# Get OAuth token ks_token() { curl -s -X POST "$KS_HOST/oauth/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=password&username=${KS_USERNAME:-admin}&password=$KS_PASSWORD&client_id=kubesphere&client_secret=kubesphere" | jq -r '.access_token' } # Make API call: ks_api GET/POST/PUT/DELETE <path> [body] ks_api() { local method=${1:-GET} local path=$2 local body=$3 local token=$(ks_token) curl -s -X "$method" \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ ${body:+-d "$body"} \ "$KS_HOST$path" }
Query Commands:
bash# List all clusters (host + member clusters) ks_api GET /kapis/cluster.kubesphere.io/v1alpha1/clusters | jq -r '.items[].metadata.name' # List installed extensions ks_api GET /kapis/kubesphere.io/v1alpha1/extensions | jq -r '.items[].metadata.name' | grep -i fluid # List available extension versions ks_api GET /kapis/kubesphere.io/v1alpha1/extensionversions | jq -r '.items[].metadata.name' | grep -i fluid # Get Fluid extension details ks_api GET /kapis/kubesphere.io/v1alpha1/extensions/fluid | jq # Get cluster connection status ks_api GET /kapis/cluster.kubesphere.io/v1alpha1/clusters/<cluster>/status | jq '.conditions'
Multi-Cluster Resource Query:
bash# Get datasets in host cluster ks_api GET /clusters/host/kapis/data.fluid.io/v1alpha1/namespaces/<namespace>/datasets # Get alluxioruntimes in host cluster ks_api GET /clusters/host/kapis/data.fluid.io/v1alpha1/namespaces/<namespace>/alluxioruntimes # Get all runtimes (Alluxio + JuiceFS + Thin) ks_api GET /clusters/host/kapis/data.fluid.io/v1alpha1/namespaces/<namespace>/allruntimes # Get specific dataset ks_api GET /clusters/host/kapis/data.fluid.io/v1alpha1/namespaces/<namespace>/datasets/<name> # Get CRDs in cluster ks_api GET /clusters/host/apis/apiextensions.k8s.io/v1/customresourcedefinitions | jq -r '.items[] | select(.metadata.name | contains("fluid")) | .metadata.name'
API Path Format:
# For KubeSphere extension management:
/kapis/kubesphere.io/v1alpha1/extensions
/kapis/cluster.kubesphere.io/v1alpha1/clusters
# For Fluid resources in namespace:
/clusters/{cluster}/kapis/data.fluid.io/v1alpha1/namespaces/{namespace}/{resources}
/clusters/{cluster}/kapis/data.fluid.io/v1alpha1/namespaces/{namespace}/{resources}/{name}Query Parameters:
page - Page number (default: 1)limit - Items per pageascending - Sort direction (default: false)sortBy - Sort field (e.g., createTime)Supported Resource Types:
datasetsalluxioruntimesjuicefsruntimesdataloadsthinruntimesallruntimesCreate Operations:
bash# Create Dataset DATASET_JSON='{ "apiVersion": "data.fluid.io/v1alpha1", "kind": "Dataset", "metadata": { "name": "<name>", "namespace": "<namespace>" }, "spec": { "mounts": [{ "mountPoint": "<mountPoint>", "name": "<mountName>" }] } }' ks_api POST /clusters/host/kapis/data.fluid.io/v1alpha1/namespaces/$NAMESPACE/datasets "$DATASET_JSON" # Or use kubectl: # kubectl apply -f examples/dataset.yaml
Read Operations:
bash# List all datasets in namespace ks_api GET /clusters/host/kapis/data.fluid.io/v1alpha1/namespaces/$NAMESPACE/datasets # Get specific dataset ks_api GET /clusters/host/kapis/data.fluid.io/v1alpha1/namespaces/$NAMESPACE/datasets/<name>
Update Operations (Scale Runtime):
bash# Scale AlluxioRuntime via PUT RUNTIME_UPDATE='{"spec":{"replicas":<new-replicas>}}' ks_api PUT /clusters/host/kapis/data.fluid.io/v1alpha1/namespaces/$NAMESPACE/alluxioruntimes/<name> "$RUNTIME_UPDATE" # Or use kubectl: # kubectl scale alluxioruntime <name> -n <namespace> --replicas=<n>
Delete Operations:
bash# Delete dataset ks_api DELETE /clusters/host/kapis/data.fluid.io/v1alpha1/namespaces/$NAMESPACE/datasets/<name> # Delete alluxioruntime ks_api DELETE /clusters/host/kapis/data.fluid.io/v1alpha1/namespaces/$NAMESPACE/thinruntimes/<name> ks_api DELETE /clusters/host/kapis/data.fluid.io/v1alpha1/namespaces/$NAMESPACE/alluxioruntimes/<name>
Use kubectl for direct Kubernetes resource operations.
bash# Extension and version discovery in KubeSphere kubectl get extensions.kubesphere.io | grep -i fluid kubectl get extensionversions.kubesphere.io | grep -i fluid # InstallPlan and extension status kubectl get installplans.kubesphere.io kubectl get installplan fluid -o yaml kubectl describe extension fluid kubectl describe extensionversion fluid-<version> # Fluid runtime resources kubectl api-resources --api-group data.fluid.io kubectl get crd | grep -E 'datasets.data.fluid.io|alluxioruntimes.data.fluid.io' kubectl get pods -A | grep -i fluid kubectl get datasets.data.fluid.io -A kubectl get alluxioruntimes.data.fluid.io -A
bash# List available datasets ksctl get dataset -n <namespace> # Create dataset with runtime ksctl create dataset -f dataset.yaml # Check status ksctl describe dataset <name> -n <namespace>
| Scenario | Recommended Approach | |----------|---------------------| | Query KubeSphere extension status | KubeSphere API (curl) | | List available clusters | KubeSphere API (curl) | | Query host cluster Kubernetes resources | kubectl | | Query member cluster Kubernetes resources | kubeconfig extraction | | Create/apply Dataset/Runtime | kubectl | | Get extension version info | KubeSphere API (curl) | | Quick status check | ksctl |
KubeSphere UI relation:
InstallPlan manifests and kubectlThis skill includes ready-to-use example manifests in the examples/ directory:
| File | Description | |------|-------------| | examples/dataset.yaml | Minimal Dataset manifest | | examples/alluxioruntime.yaml | Dataset + AlluxioRuntime with tiered storage | | examples/juicefs.yaml | Dataset + JuiceFSRuntime | | examples/thinruntime.yaml | Dataset + ThinRuntime | | examples/dataload.yaml | DataLoad for cache warming | | examples/installplan.yaml | InstallPlan for Fluid extension |
bashkubectl get extension fluid kubectl get extensionversions.kubesphere.io -l kubesphere.io/extension-ref=fluid kubectl describe extensionversion fluid-<exact-version>
Check:
Use this when the user has already confirmed the extension name and version.
bash# See examples/installplan.yaml for the template kubectl apply -f examples/installplan.yaml kubectl get installplan fluid -w kubectl describe installplan fluid kubectl get extension fluid -o yaml
bash# See examples/dataset.yaml # Key fields: # - spec.mounts[].mountPoint: Data source (s3://, oss://, pvc://, https://) - USE EXACT VALUE FROM USER # - spec.mounts[].name: Mount identifier # - spec.mounts[].readOnly: Read-only mount (default: false)
IMPORTANT: When user provides mountPoint, use it EXACTLY. Do not substitute.
Common operations:
bashkubectl apply -f examples/dataset.yaml kubectl get dataset <name> -n <namespace> kubectl describe dataset <name> -n <namespace> kubectl delete dataset <name> -n <namespace>
When user asks to create AlluxioRuntime ONLY, generate ONLY AlluxioRuntime YAML:
yamlapiVersion: data.fluid.io/v1alpha1 kind: AlluxioRuntime metadata: name: {{name}} namespace: {{namespace}} spec: replicas: {{replicas}} tieredstore: levels: - mediumtype: {{mediumType}} path: {{path}} quota: {{quota}} high: "{{high}}" low: "{{low}}"
When user explicitly asks for "Dataset with Runtime", generate both:
bash# See examples/alluxioruntime.yaml
spec.replicas: Number of Alluxio workers - USE USER'S VALUEspec.tieredstore.levels: Storage configurationmediumtype: MEM, SSD, or HDD - USE USER'S VALUE or default to MEMpath: Storage path - USE USER'S VALUE or default to /dev/shmquota: Storage size - USE USER'S VALUEhigh/low: Watermark ratiosCommon operations:
bashkubectl apply -f examples/alluxioruntime.yaml kubectl get alluxioruntime <name> -n <namespace> -o wide kubectl describe alluxioruntime <name> -n <namespace>
bash# Scale via kubectl kubectl scale alluxioruntime <name> -n <namespace> --replicas=<n> # Scale via kubectl patch kubectl patch alluxioruntime <name> -n <namespace> -p '{"spec":{"replicas":<n>}}' # Verify kubectl get alluxioruntime <name> -n <namespace> -o wide
When user asks to create JuiceFSRuntime ONLY, generate ONLY JuiceFSRuntime YAML:
yamlapiVersion: data.fluid.io/v1alpha1 kind: JuiceFSRuntime metadata: name: {{name}} namespace: {{namespace}} spec: volume: name: {{juicefsVolume}} secret: {{secretName}}
When user explicitly asks for "Dataset with JuiceFS", generate both:
bash# See examples/juicefs.yaml
spec.volume.name: JuiceFS volume name - USE USER'S VALUEspec.volume.secret: Credentials secret - USE USER'S VALUECommon operations:
bashkubectl apply -f examples/juicefs.yaml kubectl get juicefsruntime <name> -n <namespace> -o wide kubectl describe juicefsruntime <name> -n <namespace>
ALWAYS include all required fields:
yamlapiVersion: data.fluid.io/v1alpha1 kind: DataLoad metadata: name: {{name}} namespace: {{namespace}} spec: dataset: name: {{datasetName}} # REQUIRED - target dataset name namespace: {{datasetNamespace}} # REQUIRED - target dataset namespace loadMetadata: {{loadMetadata}} # REQUIRED - boolean (default: false) target: # REQUIRED - array of paths to load - path: {{targetPath}} # Path to load, e.g., /data
Field requirements:
spec.dataset.name: REQUIRED - must be provided by userspec.dataset.namespace: REQUIRED - must be provided by user spec.loadMetadata: REQUIRED - default to false if user doesn't specifyspec.target: REQUIRED - array of paths, minimum one entryspec.target[].path: REQUIRED - the path to load (e.g., /data, /user/home)Common operations:
bashkubectl apply -f examples/dataload.yaml kubectl get dataload <name> -n <namespace> kubectl describe dataload <name> -n <namespace>
Check whether datasets or runtimes still exist:
bashkubectl get datasets.data.fluid.io -A kubectl get alluxioruntimes.data.fluid.io -A kubectl get juicefsruntimes.data.fluid.io -A kubectl get thinruntimes.data.fluid.io -A
If these resources still exist, tell the user to migrate or remove them first.
bashkubectl delete installplan fluid kubectl get installplan fluid kubectl get pods -n fluid-system | grep -i fluid
If the user wants full cleanup, remind them to handle application resources first.
bashkubectl describe installplan fluid kubectl get installplan fluid -o jsonpath='{.status.conditions}' kubectl get extension fluid -o yaml kubectl get extensionversion fluid-<version> -o yaml
bashkubectl get pods -A | grep -i fluid kubectl describe pod -n fluid-system <pod-name> kubectl logs -n fluid-system deploy/alluxio-runtime-controller --tail=200 kubectl logs -n fluid-system deploy/juicefs-runtime-controller --tail=200 kubectl get events -n fluid-system --sort-by=.lastTimestamp
bashkubectl get crd datasets.data.fluid.io alluxioruntimes.data.fluid.io juicefsruntimes.data.fluid.io thinruntimes.data.fluid.io kubectl describe crd datasets.data.fluid.io kubectl api-resources --api-group data.fluid.io
Likely causes:
Safe next actions:
InstallPlan state and conditionsbashkubectl get alluxioruntime <name> -n <namespace> kubectl describe alluxioruntime <name> -n <namespace> kubectl get pods -n <namespace> -l release=<runtime>
Likely causes:
bashkubectl describe dataset <name> -n <namespace> kubectl get dataset <name> -n <namespace> -o yaml
Likely causes:
bashkubectl get dataload <name> -n <namespace> kubectl describe dataload <name> -n <namespace> kubectl get dataset <dataset-name> -n <namespace>
bashkubectl describe alluxioruntime <name> -n <namespace> | grep -A5 "Scaling" kubectl describe resourcequota -n <namespace> kubectl describe nodes | grep -A10 "Allocated resources"
Match the answer to the user intent:
InstallPlan manifestkubectl commands, grouped by purposeWhen user asks to create ThinRuntime ONLY, generate ONLY ThinRuntime YAML:
yamlapiVersion: data.fluid.io/v1alpha1 kind: ThinRuntime metadata: name: {{name}} namespace: {{namespace}} spec: mountPoint: {{mountPoint}} thin: profile: {{profileName}} credentials: {{secretName}}
When user explicitly asks for "Dataset with ThinRuntime", generate both:
bash# See examples/thinruntime.yaml
spec.mountPoint: Under storage path - USE USER'S VALUEspec.thin.profile: Thin runtime profile name - USE USER'S VALUEspec.thin.credentials: Secret containing credentials - USE USER'S VALUECommon operations:
bashkubectl apply -f examples/thinruntime.yaml kubectl get thinruntime <name> -n <namespace> -o wide kubectl describe thinruntime <name> -n <namespace>
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-20 | fail→fail | 18,074 | 7,228 | -60% | 1 | 1 | 0% | 2,995 | 6,882 | +130% | 0 | 0 | — |
case-01 | fail→pass | 3,725 | 3,247 | -13% | 1 | 1 | 0% | 835 | 6,333 | +658% | 0 | 0 | — |
case-02 | fail→pass | 10,625 | 4,076 | -62% | 1 | 1 | 0% | 2,065 | 6,366 | +208% | 0 | 0 | — |
case-03 | pass→pass | 3,699 | 3,495 | -6% | 1 | 1 | 0% | 718 | 6,336 | +782% | 0 | 0 | — |
case-04 | pass→pass | 26,186 | 3,574 | -86% | 1 | 1 | 0% | 2,468 | 6,315 | +156% | 0 | 0 | — |
case-05 | pass→fail | 11,107 | 7,312 | -34% | 1 | 1 | 0% | 2,303 | 6,988 | +203% | 0 | 0 | — |
case-06 | pass→pass | 6,122 | 4,451 | -27% | 1 | 1 | 0% | 1,208 | 6,558 | +443% | 0 | 0 | — |
case-07 | pass→pass | 9,188 | 2,922 | -68% | 1 | 1 | 0% | 1,649 | 6,154 | +273% | 0 | 0 | — |
case-08 | pass→pass | 5,156 | 3,767 | -27% | 1 | 1 | 0% | 924 | 6,207 | +572% | 0 | 0 | — |
case-09 | fail→pass | 15,442 | 9,110 | -41% | 1 | 1 | 0% | 1,977 | 6,485 | +228% | 0 | 0 | — |
case-21 | fail→fail | 28,773 | 9,806 | -66% | 1 | 1 | 0% | 5,257 | 7,645 | +45% | 0 | 0 | — |
case-10 | pass→pass | 6,398 | 12,769 | +100% | 1 | 1 | 0% | 1,038 | 6,184 | +496% | 0 | 0 | — |
case-11 | pass→pass | 4,542 | 2,434 | -46% | 1 | 1 | 0% | 809 | 5,981 | +639% | 0 | 0 | — |
case-12 | fail→pass | 5,751 | 3,303 | -43% | 1 | 1 | 0% | 812 | 6,174 | +660% | 0 | 0 | — |
case-13 | fail→pass | 15,368 | 4,810 | -69% | 1 | 1 | 0% | 2,396 | 6,471 | +170% | 0 | 0 | — |
case-14 | fail→pass | 10,461 | 6,393 | -39% | 1 | 1 | 0% | 1,812 | 6,613 | +265% | 0 | 0 | — |
case-15 | pass→pass | 8,623 | 4,350 | -50% | 1 | 1 | 0% | 1,713 | 6,465 | +277% | 0 | 0 | — |
case-16 | fail→pass | 5,040 | 3,591 | -29% | 1 | 1 | 0% | 918 | 6,140 | +569% | 0 | 0 | — |
case-17 | fail→pass | 12,897 | 4,729 | -63% | 1 | 1 | 0% | 2,296 | 6,381 | +178% | 0 | 0 | — |
case-18 | pass→pass | 8,588 | 3,131 | -64% | 1 | 1 | 0% | 1,583 | 6,251 | +295% | 0 | 0 | — |
case-19 | fail→fail | 12,687 | 6,546 | -48% | 1 | 1 | 0% | 2,156 | 6,782 | +215% | 0 | 0 | — |
case-22 | fail→pass | 9,562 | 4,537 | -53% | 1 | 1 | 0% | 1,808 | 6,459 | +257% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +36 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.