Bemærk
Adgang til denne side kræver godkendelse. Du kan prøve at logge på eller ændre mapper.
Adgang til denne side kræver godkendelse. Du kan prøve at ændre mapper.
Use BlobFuse2 with distributed accelerator for cloud storage (DACS) to read Azure Blob data through Linux file-system paths. Applications keep their existing file-reading code, while BlobFuse2 serves cached data through DACS and retrieves missing data from Blob Storage.
The Azure Blob Container Storage Interface (CSI) driver mounts the container through a persistent volume (PV) and persistent volume claim (PVC). Azure Blob Storage remains the durable source of truth.
This article covers configuration, read-path verification, and Standard storage benchmark results.
Prerequisites
- An AKS cluster that meets the Azure region and Kubernetes version requirements in the DACS quickstart.
- Linux cache nodes with local NVMe disks dedicated to DACS.
- Ubuntu Linux workload nodes for application pods that mount BlobFuse2.
- An Azure Blob container containing your application data.
- An existing user-assigned managed identity for Blob authentication.
- Azure CLI and
kubectl. - Permission to enable DACS and the managed Azure Blob CSI driver, create Kubernetes resources, manage the identity's federated credentials, and assign the required Blob data-access role.
- BlobFuse2 2.5.6 or later installed on every eligible Linux workload node. For distributed-cache support and limitations, see the BlobFuse2 2.5.6 release notes.
- AKS-managed Azure Blob CSI driver
v1.27.11or later, with the AKS OIDC issuer and Microsoft Entra Workload ID enabled for token-only authentication.
Important
Use a read-only mount for each container. Verify DACS activity through cache-server metrics and BlobFuse2 logs.
DACS treats the Kubernetes cluster as a single trust domain and doesn't provide tenant isolation. Don't use it in a multitenant cluster. Workload identity authorizes Blob Storage access; it doesn't isolate cached data. For more information, see the DACS security model. DACS treats the Kubernetes cluster as a single trust domain and doesn't provide tenant isolation. Don't use it in a multitenant cluster. Workload identity authorizes Blob Storage access; it doesn't isolate cached data. For more information, see the DACS security model.
Set variables
Run the commands in the same Bash session. Replace the placeholders with your cluster, storage container, and existing user-assigned managed identity:
SUBSCRIPTION_ID="<subscription-id>"
RESOURCE_GROUP="<aks-resource-group>"
CLUSTER_NAME="<aks-cluster-name>"
WORKLOAD_NODE_POOL="<blobfuse-ready-node-pool>"
STORAGE_RESOURCE_GROUP="<storage-resource-group>"
STORAGE_ACCOUNT="<storage-account-name>"
STORAGE_CONTAINER="<existing-container-name>"
IDENTITY_RESOURCE_GROUP="<managed-identity-resource-group>"
IDENTITY_NAME="<managed-identity-name>"
CACHE_NAMESPACE=dacs-cache-system
CACHE_NAME=cache-sample
WORKLOAD_NAMESPACE=blobfuse-dacs
SERVICE_ACCOUNT=blobfuse-reader
az account set --subscription "$SUBSCRIPTION_ID"
az aks get-credentials --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME"
BLOBFUSE_CLIENT_ID=$(az identity show \
--resource-group "$IDENTITY_RESOURCE_GROUP" \
--name "$IDENTITY_NAME" \
--query clientId --output tsv)
Install distributed accelerator for cloud storage
To install DACS, prepare dedicated cache disks, create a Cache resource, and verify readiness, see Get started with distributed accelerator for cloud storage on AKS.
Retrieve the discovery hostname for your ready Cache:
CACHE_DISCOVERY_HOST=$(kubectl get cache "$CACHE_NAME" \
--namespace "$CACHE_NAMESPACE" \
-o jsonpath='{.status.discoveryURL}')
test -n "$CACHE_DISCOVERY_HOST"
Use the hostname published by your Cache resource and its configured port. The quickstart uses port 9065.
Enable the Azure Blob CSI driver and verify BlobFuse2
Use the AKS-managed driver. Follow Enable the Azure Blob CSI driver on AKS.
Use AKS to manage CSI driver upgrades. Ensure every eligible workload node runs BlobFuse2 2.5.6 or later, and coordinate package updates with volume unmounts.
Verify the installed mount process
Check CSI readiness through the node DaemonSet.
kubectl get csidriver blob.csi.azure.com
kubectl rollout status daemonset/csi-blob-node \
--namespace kube-system --timeout=10m
kubectl get pods --namespace kube-system \
--selector app=csi-blob-node --output wide
kubectl get daemonset csi-blob-node --namespace kube-system \
--output jsonpath='{range .spec.template.spec.containers[*]}{.name}{": "}{.image}{"\n"}{end}'
Confirm that the blob container image is version v1.27.11 or later.
The CSI driver image version doesn't identify the BlobFuse2 version installed on the host. For each eligible Ubuntu node, select its csi-blob-node pod from the preceding output and verify the host binary used by the CSI proxy:
BLOB_CSI_POD="<csi-blob-node-pod-name>"
kubectl exec --namespace kube-system "$BLOB_CSI_POD" --container blob -- \
nsenter --mount=/proc/1/ns/mnt -- /usr/bin/blobfuse2 --version
kubectl exec --namespace kube-system "$BLOB_CSI_POD" --container blob -- \
nsenter --mount=/proc/1/ns/mnt -- /usr/bin/blobfuse2 mount --help
Confirm version 2.5.6 or later and the --distributed-cache-* options used in the volume configuration in the following section.
Update BlobFuse2 when the node image has an older version
If the host binary is missing or earlier than 2.5.6, configure the managed CSI driver's install-blobfuse-proxy init container to install the required BlobFuse2 package. Skip this step when all eligible nodes already have version 2.5.6 or later.
This update uses the package installer on Ubuntu nodes, which need access to the configured Ubuntu and Microsoft package repositories. It doesn't replace the managed CSI driver image or install a separate driver.
Important
The patch rolls out the csi-blob-node DaemonSet across the cluster, not only the workload node pool. Check the host versions on all affected Ubuntu nodes and coordinate the update with volume unmounts before proceeding. If a node already runs a version newer than 2.5.6, set BLOBFUSE2_VERSION below to that version or a later available package. Package downgrades are disabled.
Save the current DaemonSet and create the patch:
kubectl get daemonset csi-blob-node --namespace kube-system \
--output yaml > csi-blob-node-before.yaml
BLOBFUSE2_VERSION=2.5.6
cat <<EOF > csi-blob-proxy-patch.yaml
spec:
template:
spec:
initContainers:
- name: install-blobfuse-proxy
env:
- name: INSTALL_BLOBFUSE
value: "false"
- name: INSTALL_BLOBFUSE2
value: "true"
- name: BLOBFUSE2_VERSION
value: "$BLOBFUSE2_VERSION"
- name: INSTALL_BLOBFUSE_PROXY
value: "true"
- name: ALLOW_PACKAGE_INSTALL_DOWNGRADE
value: "false"
EOF
kubectl patch daemonset csi-blob-node --namespace kube-system \
--type strategic --patch-file csi-blob-proxy-patch.yaml
kubectl rollout status daemonset/csi-blob-node \
--namespace kube-system --timeout=15m
The merge patch updates the named init container and environment entries while preserving its image and other settings. For the package-selection controls, see the Blob CSI proxy installer.
After the rollout, list the CSI pods again and repeat the host binary verification on every eligible workload node. Verify 2.5.6 or later and the distributed-cache options before mounting the volume. Existing BlobFuse2 mount processes don't switch versions when the package changes; recreate their mounts to use the updated binary.
If the rollout fails, inspect the installer logs for the affected pod:
kubectl logs --namespace kube-system "<csi-blob-node-pod-name>" \
--container install-blobfuse-proxy
AKS updates can reconcile the managed DaemonSet. Recheck the host binary and installer settings after CSI driver or node-image upgrades. Once the node image supplies the required BlobFuse2 version, remove the temporary package-version override as part of that upgrade.
Configure Blob authentication
Use federated AKS workload identity with token-only Blob authentication. The volume configuration enables this mode with mountWithWorkloadIdentityToken: "true".
Follow Enable OIDC and Microsoft Entra Workload ID, then create the workload ServiceAccount:
kubectl create namespace "$WORKLOAD_NAMESPACE"
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: $SERVICE_ACCOUNT
namespace: $WORKLOAD_NAMESPACE
annotations:
azure.workload.identity/client-id: "$BLOBFUSE_CLIENT_ID"
EOF
Link the ServiceAccount to your managed identity and grant container-scoped access:
OIDC_ISSUER=$(az aks show \
--resource-group "$RESOURCE_GROUP" \
--name "$CLUSTER_NAME" \
--query oidcIssuerProfile.issuerUrl --output tsv)
az identity federated-credential create \
--name blobfuse-dacs-reader \
--identity-name "$IDENTITY_NAME" \
--resource-group "$IDENTITY_RESOURCE_GROUP" \
--issuer "$OIDC_ISSUER" \
--subject "system:serviceaccount:$WORKLOAD_NAMESPACE:$SERVICE_ACCOUNT" \
--audiences api://AzureADTokenExchange
IDENTITY_PRINCIPAL_ID=$(az identity show \
--resource-group "$IDENTITY_RESOURCE_GROUP" \
--name "$IDENTITY_NAME" \
--query principalId --output tsv)
STORAGE_ID=$(az storage account show \
--resource-group "$STORAGE_RESOURCE_GROUP" \
--name "$STORAGE_ACCOUNT" \
--query id --output tsv)
az role assignment create \
--assignee-object-id "$IDENTITY_PRINCIPAL_ID" \
--assignee-principal-type ServicePrincipal \
--role "Storage Blob Data Contributor" \
--scope "$STORAGE_ID/blobServices/default/containers/$STORAGE_CONTAINER"
The role assignment follows the CSI token-only mount guidance. Allow it to propagate before testing. The workload accesses Blob Storage through the federated identity and a read-only mount.
Configure a read-only BlobFuse2 volume
Retrieve the cluster DNS service IP for the Cache's cluster-local hostname:
CLUSTER_DNS_IP=$(az aks show \
--resource-group "$RESOURCE_GROUP" \
--name "$CLUSTER_NAME" \
--query networkProfile.dnsServiceIp --output tsv)
test -n "$CLUSTER_DNS_IP"
Allow workload nodes to reach cluster DNS, the DACS endpoints, and Azure Blob Storage for cache misses and fallback.
Create a static PV and PVC for your existing container. The Retain policy preserves the data when the claim is removed:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolume
metadata:
name: blobfuse-dacs-pv
spec:
capacity:
storage: 1Ti
accessModes:
- ReadOnlyMany
persistentVolumeReclaimPolicy: Retain
storageClassName: ""
mountOptions:
- --read-only=true
- --allow-other=true
- --disable-kernel-cache=true
- --block-cache=false
- --streaming=false
- --preload=false
- --distributed-cache-discovery-endpoint=$CACHE_DISCOVERY_HOST:9065
- --distributed-cache-dns-server=$CLUSTER_DNS_IP
- --distributed-cache-block-size=16
- --distributed-cache-node-memory=1024
- --distributed-cache-prefetch=16
- --distributed-cache-parallelism=16
csi:
driver: blob.csi.azure.com
readOnly: true
volumeHandle: "$STORAGE_RESOURCE_GROUP#$STORAGE_ACCOUNT#$STORAGE_CONTAINER#blobfuse-dacs"
volumeAttributes:
protocol: fuse2
resourceGroup: "$STORAGE_RESOURCE_GROUP"
storageAccount: "$STORAGE_ACCOUNT"
containerName: "$STORAGE_CONTAINER"
clientID: "$BLOBFUSE_CLIENT_ID"
mountWithWorkloadIdentityToken: "true"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: blobfuse-dacs-pvc
namespace: $WORKLOAD_NAMESPACE
spec:
accessModes:
- ReadOnlyMany
storageClassName: ""
volumeName: blobfuse-dacs-pv
resources:
requests:
storage: 1Ti
EOF
Use a unique PV name and volumeHandle for each volume. The 1Ti declaration provides the capacity value for PV/PVC binding.
Configure caching through the --distributed-cache-* options. The distributed-cache component manages its local block-cache layer.
The example allocates 1,024 MiB to the local cache and prefetches 16 blocks. Budget memory separately for application pods, host-side BlobFuse2 mounts, and colocated DACS servers.
Mount the volume in a workload
Set DATA_FILE to a file path relative to the container root. This Python workload reads the first 4 MiB twice and compares checksums:
DATA_FILE="<existing-file-path>"
WORKLOAD_IMAGE="python:3.12-slim-bookworm"
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: blobfuse-dacs-reader
namespace: $WORKLOAD_NAMESPACE
labels:
azure.workload.identity/use: "true"
spec:
serviceAccountName: $SERVICE_ACCOUNT
restartPolicy: Never
nodeSelector:
kubernetes.io/os: linux
agentpool: "$WORKLOAD_NODE_POOL"
containers:
- name: reader
image: $WORKLOAD_IMAGE
command:
- python3
- -c
- |
import hashlib
import os
import time
from pathlib import Path
path = Path("/mnt/blob") / os.environ["DATA_FILE"]
previous = None
for attempt in range(2):
with path.open("rb") as stream:
data = stream.read(4 * 1024 * 1024)
if not data:
raise RuntimeError("The selected file returned no data")
digest = hashlib.sha256(data).hexdigest()
if previous is not None and digest != previous:
raise RuntimeError("Repeated reads returned different bytes")
print(f"read={attempt + 1} bytes={len(data)} sha256={digest}", flush=True)
previous = digest
time.sleep(5)
env:
- name: DATA_FILE
value: "$DATA_FILE"
resources:
requests:
cpu: "1"
memory: 128Mi
limits:
cpu: "1"
memory: 256Mi
volumeMounts:
- name: blob
mountPath: /mnt/blob
readOnly: true
volumes:
- name: blob
persistentVolumeClaim:
claimName: blobfuse-dacs-pvc
readOnly: true
EOF
kubectl get pvc blobfuse-dacs-pvc --namespace "$WORKLOAD_NAMESPACE"
kubectl logs --namespace "$WORKLOAD_NAMESPACE" \
blobfuse-dacs-reader --follow --pod-running-timeout=5m
The application reads /mnt/blob/<path>. The node selector schedules it on the pool with the verified BlobFuse2 installation.
Verify the DACS read path
Configure scraping for each cache-server pod by following Monitor distributed accelerator for cloud storage.
- Confirm that the PVC is bound to the PV and that the mount uses the expected discovery, DNS, and read-only options.
- Check the CSI and BlobFuse2 logs for the installed version and connections to the expected cache servers.
- Record a baseline for
cache_server_request_counter{request_type="Download",status="Success"}, summed only across the server pods owned by your Cache. - Allow background population to complete, then repeat reads across workload nodes. Correlate successful server Download activity with BlobFuse2 logs and Blob telemetry to confirm distributed reuse.
Use checksums to verify data integrity and request counters to verify the cache path. For detailed commands, see Verify the DACS request path.
Verify reuse across two nodes
The introductory workload reads twice from one node, which can reuse its local cache. To verify distributed reuse, use two ready nodes from the verified workload pool and a test file that you didn't read through this Cache. Choose a file small enough to fit in the cache and get its expected SHA-256 from the original source or a trusted manifest. The introductory workload reads twice from one node, which can reuse its local cache. To verify distributed reuse, use two ready nodes from the verified workload pool and a test file that you didn't read through this Cache. Choose a file small enough to fit in the cache and get its expected SHA-256 from the original source or a trusted manifest.
Use a Cache dedicated to this test so unrelated workloads don't affect its request counters. List eligible nodes, and then set the hostname labels, the file path relative to the container root, and its expected checksum: List eligible nodes, and then set the hostname labels, the file path relative to the container root, and its expected checksum:
kubectl get nodes --selector "agentpool=$WORKLOAD_NODE_POOL" \
--output wide --label-columns kubernetes.io/hostname
COLD_NODE="<first-node-hostname-label>"
WARM_NODE="<different-node-hostname-label>"
VALIDATION_FILE="<existing-uncached-file-path>"
EXPECTED_SHA256="<expected-full-file-sha256>"
Create two readers that keep their mounts active while you run the checks and wait for background population:
create_validation_reader() {
local name="$1" node="$2"
if [ -z "$COLD_NODE" ] || [ -z "$WARM_NODE" ] || [ "$COLD_NODE" = "$WARM_NODE" ]; then
echo "ERROR: choose two different workload nodes." >&2
return 1
fi
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: $name
namespace: $WORKLOAD_NAMESPACE
labels:
azure.workload.identity/use: "true"
spec:
serviceAccountName: $SERVICE_ACCOUNT
restartPolicy: Never
nodeSelector:
kubernetes.io/os: linux
agentpool: "$WORKLOAD_NODE_POOL"
kubernetes.io/hostname: "$node"
containers:
- name: reader
image: $WORKLOAD_IMAGE
command: ["sleep", "86400"]
resources:
requests:
cpu: "1"
memory: 128Mi
limits:
cpu: "1"
memory: 256Mi
volumeMounts:
- name: blob
mountPath: /mnt/blob
readOnly: true
volumes:
- name: blob
persistentVolumeClaim:
claimName: blobfuse-dacs-pvc
readOnly: true
EOF
}
create_validation_reader blobfuse-dacs-cold "$COLD_NODE" &&
create_validation_reader blobfuse-dacs-warm "$WARM_NODE" &&
kubectl wait pod/blobfuse-dacs-cold pod/blobfuse-dacs-warm \
--namespace "$WORKLOAD_NAMESPACE" --for=condition=Ready --timeout=5m &&
kubectl get pods blobfuse-dacs-cold blobfuse-dacs-warm \
--namespace "$WORKLOAD_NAMESPACE" --output wide
Confirm that both readers are ready on different nodes. Don't read the file from the warm node yet. Confirm that both readers are ready on different nodes. Don't read the file from the warm node yet.
Read and verify the entire file from the cold node:
kubectl exec --namespace "$WORKLOAD_NAMESPACE" blobfuse-dacs-cold -- \
sh -c 'set -eu; cd /mnt/blob; printf "%s %s\n" "$1" "$2" | sha256sum --check' \
sh "$EXPECTED_SHA256" "$VALIDATION_FILE"
Stop if the checksum check fails. Keep the cold reader running and use the cache-server metrics to confirm that background population is complete. Immediately before the warm read, record the successful Download counter baseline across the servers owned by your Cache. Stop if the checksum check fails. Keep the cold reader running and use the cache-server metrics to confirm that background population is complete. Immediately before the warm read, record the successful Download counter baseline across the servers owned by your Cache.
Read and verify the same file from the second node:
kubectl exec --namespace "$WORKLOAD_NAMESPACE" blobfuse-dacs-warm -- \
sh -c 'set -eu; cd /mnt/blob; printf "%s %s\n" "$1" "$2" | sha256sum --check' \
sh "$EXPECTED_SHA256" "$VALIDATION_FILE"
Both checksum checks must report OK, and the Cache's successful Download counter must increase during the second read. Matching checksums alone don't prove distributed reuse. If the counter doesn't increase, follow the fallback diagnostics in Troubleshoot the integration rather than declaring success.
Optimize read performance
Tune application I/O separately from BlobFuse2 cache settings:
| Setting | Description |
|---|---|
| Application I/O size and thread count | The byte ranges and concurrency requested by the application. |
--distributed-cache-block-size |
Local and distributed cache block size in MiB. |
--distributed-cache-node-memory |
Local block-cache memory setting in MiB for the mount. |
--distributed-cache-prefetch |
Number of blocks to prefetch. |
--distributed-cache-parallelism |
Concurrent block downloads, including prefetch work. |
| Cache resource sizing | DACS server count, local-NVMe capacity, CPU, memory, and server threads. |
Measure sequential and random access separately. Tune block size, prefetch, and concurrency together while monitoring throughput, memory, origin traffic, and throttling.
For colocated deployments, reserve CPU, memory, network bandwidth, and local disk capacity for both application workers and cache servers.
Apply changed mount options through a coordinated unmount and remount for all pods sharing the volume. Verify the new options in CSI logs.
Standard storage benchmark results
The benchmarks compare BlobFuse2 alone with dedicated and colocated DACS on a Standard_LRS, Hot-tier StorageV2 account in Central US. Each profile covers five thread counts across the three configurations.
Deployment scenarios
- Dedicated DACS: Application workers and DACS cache servers run on separate node pools.
- Colocated DACS: Application workers and DACS cache servers share the same nodes.
BlobFuse2 alone provides the baseline for both scenarios.
Test configuration
| Setting | Measured configuration |
|---|---|
| VMs | Cache servers: Standard_E192ids_v6 * 10; workers: Standard_E192ids_v6 * 10 |
| DACS server resource limits | 32 CPUs and 128 GiB of memory per server. |
| Native chart server resource requests | 250m CPU and 100Mi memory per server. |
| Benchmark | Elbencho 3.0-38; I/O depth 1. |
| Dataset | 800 existing 10-GiB files, totaling 8,000 GiB; five files per I/O thread. |
| BlobFuse2 | Read-only mounts; kernel cache disabled. |
| Client cache | 16-MiB blocks; prefetch 128 blocks; parallelism 128; native memory sizing. |
Each case used fresh worker and cache resources. Results are aggregate measurements, with thread counts reported per worker.
Sequential reads
Sequential tests used 16-MiB I/O and five read iterations per case. Cold throughput is the first iteration. Warm throughput and the BlobFuse-only baseline are the averages of iterations 2 through 5. Values are aggregate MiB/s.
| Threads per worker | BlobFuse-only | Dedicated cold | Dedicated warm | Colocated cold | Colocated warm |
|---|---|---|---|---|---|
| 1 | 18,074 | 15,689 | 19,976.75 | 15,564 | 20,443.5 |
| 2 | 18,745 | 18,923 | 36,779.75 | 19,380 | 36,827.75 |
| 4 | 21,497 | 22,028 | 41,211.75 | 23,793 | 44,692.25 |
| 8 | 25,544 | 25,970 | 42,445 | 24,532 | 47,158.25 |
| 16 | 25,953.25 | 21,296 | 43,082.25 | 22,899 | 47,760.75 |
At 16 threads per worker, colocated warm throughput was 84% higher than BlobFuse-only and 10.9% higher than dedicated warm throughput.
Estimated origin bandwidth savings
Retained telemetry indicates approximately 70% lower average Blob-origin bandwidth for dedicated and colocated DACS compared with BlobFuse-only across the matched sequential tests, including initial cold-cache population.
Random 4-KiB reads
Random tests use 4-KiB I/O with -i 1 --rand --infloop and a 300-second runtime. Each case reports one aggregate IOPS measurement, including cache population.
| Threads per worker | BlobFuse-only IOPS | Dedicated IOPS | Colocated IOPS |
|---|---|---|---|
| 1 | 59 | 503 | 530 |
| 2 | 117 | 952 | 882 |
| 4 | 236 | 1,586 | 1,446 |
| 8 | 448 | 2,004 | 2,046 |
| 16 | 540 | 1,804 | 1,809 |
Both DACS scenarios peak at eight threads per worker. Colocated DACS reaches 2,046 IOPS, or 4.57 times the BlobFuse-only result at the same thread count.
Troubleshoot the integration
| Area | Action |
|---|---|
| Version and mount options | Verify the host-side BlobFuse2 version and its --distributed-cache-* options. |
| Cache activity | Correlate cache-server Download counters with BlobFuse2 logs and Blob telemetry. |
| Discovery and DNS | Verify --distributed-cache-dns-server, node access to cluster DNS, and the Cache's discovery service. |
| Authentication | Verify the federated ServiceAccount, identity role, CSI version, and mountWithWorkloadIdentityToken: "true". |
| Node memory | Budget memory for mount caches, background population, application pods, and colocated DACS servers. |
| Configuration updates | Remount the volume and confirm the new options in CSI logs. |
For storage-mount troubleshooting, see Troubleshoot BlobFuse2 and the Blob CSI driver debugging guide.
Identify local-cache or origin fallback
A successful mount or read doesn't prove that DACS is serving data:
- If CSI logs report
BlobFuse2 distributed-cache support could not be verified, the driver removes the distributed-cache options and selects local block cache. Verify the host BlobFuse2 version and mount capabilities, then coordinate an unmount and remount. - If CSI logs report
BlobFuse2 distributed-cache support could not be verified, the driver removes the distributed-cache options and selects local block cache. Verify the host BlobFuse2 version and mount capabilities, then coordinate an unmount and remount. - If BlobFuse2 discovers no cache servers, the mount can still succeed and reads go directly to Blob Storage. Check the discovery service, DNS address, endpoints, and node-to-cache connectivity.
Find the CSI pod running on the affected reader node and inspect its blob container:
kubectl get pods --namespace "$WORKLOAD_NAMESPACE" --output wide
kubectl get pods --namespace kube-system \
--selector app=csi-blob-node --output wide
CSI_POD="<csi-blob-node-pod-on-affected-reader-node>"
kubectl logs "$CSI_POD" --namespace kube-system --container blob --since=15m
CSI container logs aren't host BlobFuse2 logs. On the affected workload node, use your approved node-access method to inspect BlobFuse2's journal:
journalctl --identifier=blobfuse2 --since "15 minutes ago" --no-pager
If BlobFuse2 is configured to write to a file instead, inspect its configured log path. After correcting the problem, coordinate an unmount and remount for all pods sharing the volume, then repeat the cache-path verification.
Clean up the test workload
Delete only resources created for this article. Stop the reader pods before deleting the claim and PV:
kubectl delete pod blobfuse-dacs-reader blobfuse-dacs-cold blobfuse-dacs-warm \
--namespace "$WORKLOAD_NAMESPACE" --ignore-not-found
kubectl delete pvc blobfuse-dacs-pvc \
--namespace "$WORKLOAD_NAMESPACE" --ignore-not-found
kubectl delete pv blobfuse-dacs-pv --ignore-not-found
The Retain policy preserves your container and blobs. Don't delete existing application data or the managed identity. Remove the federated credential, role assignment, or workload namespace only if you created it solely for this test and no other workload needs it.
Leave the managed Blob CSI driver and shared DACS resources enabled. If DACS was enabled only for this evaluation and no other workload needs it, follow Remove distributed accelerator for cloud storage.