Starten Sie mit dem verteilten Beschleuniger für Cloud-Speicher auf AKS (Vorschau).

Dieser Quickstart aktiviert den verteilten Beschleuniger für Cloud-Speicher (DACS) über seine verwaltete Erweiterung auf einem bestehenden Azure Kubernetes Service (AKS)-Cluster, gewährt Lesezugriff auf einen Azure Blob-Container und überprüft, dass wiederholte Lesevorgänge den Cache verwenden. Das Workload-Beispiel verwendet das öffentliche dacs-client==0.1.0 Paket.

Important

Der verteilte Beschleuniger für Cloud-Speicher befindet sich in der Vorschau. Vorschaufunktionen werden ohne Service-Level-Vereinbarung bereitgestellt und sind für Produktionsworkloads nicht empfohlen. Weitere Informationen finden Sie unter Zusätzliche Nutzungsbedingungen für Microsoft Azure-Vorschauversionen.

Prerequisites

Bevor Sie beginnen, benötigen Sie Folgendes:

  • Ein Azure-Abonnement.
  • Ein bestehender AKS-Cluster, der die DACS-Vorschauunterstützungsanforderungen erfüllt.
  • Ein Linux-Cache-Knotenpool mit lokalen NVMe-Datendisks, beispielsweise die Standard_L*s_v3 VM-Familie.
  • Ein Azure Storage-Konto und ein Blob-Container, der repräsentative Modelldaten enthält.
  • Eine Bash-Shell mit Azure CLI, kubectl, und Docker oder einem anderen Container-Image-Build-Tool. Führe die Befehle in diesem Quickstart in derselben Shell-Sitzung aus, damit die Variablen verfügbar bleiben.
  • Berechtigung zur Installation von AKS-Erweiterungen, Verwaltung von Kubernetes-Ressourcen, Aktualisierung von Nodepool-Labels und zur Zuweisung der Speicher-Datenzugriffsrolle, die in diesem Quickstart verwendet wird.
  • Ein Workload-Image mit Python 3.8 oder höher und glibc 2.35 oder später. Dieser Quickstart verwendet python:3.12-slim-bookworm ein PyPI-Paket dacs-client==0.1.0 auf x64-Knoten.

Der verteilte Beschleuniger für Cloud-Speicher nutzt den Cache-Node-Pool nicht als persistenten Speicher. Azure Blob Storage bleibt die Quelle der Wahrheit.

Anforderungen für die Unterstützung der DACS-Vorschau

Requirement Unterstützung für die DACS-Vorschau
Azure-Regionen Alle öffentlichen Azure-Cloudregionen.
AKS Kubernetes-Versionen 1.35 oder später.

Festlegen von Variablen

Ersetzen Sie die Platzhalterwerte und führen Sie dann die folgenden Befehle aus:

SUBSCRIPTION_ID=<subscription-id>
RESOURCE_GROUP=<resource-group>
CLUSTER_NAME=<aks-cluster-name>
CACHE_NODE_POOL=<nvme-node-pool>
STORAGE_ACCOUNT=<storage-account-name>
STORAGE_CONTAINER=<blob-container-name>
CACHE_NAMESPACE=dacs-cache-system
CACHE_NAME=cache-sample

az account set --subscription $SUBSCRIPTION_ID
az aks get-credentials \
  --resource-group $RESOURCE_GROUP \
  --name $CLUSTER_NAME

Stellen Sie sicher, dass die AKS-Vorschauerweiterung installiert ist

DACS-Vorschau erfordert aks-preview Version 22.0.0b9 oder höher. Installieren oder aktualisieren Sie die Erweiterung sowie die Erweiterungen, die zur Verwaltung und Inspektion von DACS verwendet werden:

az extension add --name aks-preview --upgrade --yes
az extension show --name aks-preview --query version --output tsv
az extension add --name connectedk8s --upgrade --yes
az extension add --name k8s-extension --upgrade --yes

Du musst den AKS-Cluster nicht mit Azure Arc verbinden. Wenn du bereits einen DACS-Controller manuell installiert hast, folge "Prepare for Upgrades", bevor du auf die verwaltete Erweiterung wechselst. Betreib nicht zwei DACS-Controller auf demselben Cluster.

Überprüfen Sie den Cache-Node-Pool

Bestätigen Sie, dass der ausgewählte Knotenpool Linux und eine VM-Größe mit lokalen NVMe-Datenfestplatten verwendet:

az aks nodepool show \
  --resource-group $RESOURCE_GROUP \
  --cluster-name $CLUSTER_NAME \
  --name $CACHE_NODE_POOL \
  --query '{osType:osType,vmSize:vmSize,count:count,powerState:powerState.code}' \
  --output table

Für einen verteilten Accelerator für Cloud-Speicher verwenden Sie einen dedizierten Cache-Node-Pool oder überprüfen Sie, dass andere Software nicht dieselben lokalen NVMe-Festplatten beansprucht oder formatiert.

Kennzeichne den Cache-Node-Pool auf Node-Pool-Ebene, damit das Label den Knotenaustausch übersteht. Wenn der Pool bereits benutzerdefinierte Labels hat, fügen Sie diese im Update hinzu, um sie zu erhalten:

az aks nodepool update \
  --resource-group $RESOURCE_GROUP \
  --cluster-name $CLUSTER_NAME \
  --name $CACHE_NODE_POOL \
  --labels dacs.azure.com/processing-unit=cpu

Caution

Das Aktivieren von DACS installiert ein voraussetzendes DaemonSet, das lokale NVMe-Festplatten auf beschrifteten Cache-Knoten entdeckt, formatiert und mountet. Beschrifte nur Knoten mit Datenträgern, die dem Cache gewidmet sind.

Aktivieren Sie verteilte Beschleunigung für Cloud-Speicher

Aktiviere DACS, indem du nur distributedAccelerator übergibst. Der Großbuchstabe A ist erforderlich:

az aks update \
  --resource-group $RESOURCE_GROUP \
  --name $CLUSTER_NAME \
  --enable-azure-container-storage distributedAccelerator

Der Befehl installiert die distributedaccelerator verwaltete Erweiterung, den DACS-Controller und die NVMe-Voraussetzung DaemonSet in kube-system, sowie die benutzerdefinierte caches.storage.azure.com Ressourcendefinition (CRD). Du installierst kein separates Voraussetzungs-Chart und verwaltest das Helm-Release der Erweiterung nicht selbst. Erstelle eine Cache-Ressource separat, wie später gezeigt.

Überprüfen Sie die Erweiterung

az k8s-extension show \
  --cluster-type managedClusters \
  --cluster-name $CLUSTER_NAME \
  --resource-group $RESOURCE_GROUP \
  --name distributedaccelerator \
  --query '{extensionType:extensionType,provisioningState:provisioningState,currentVersion:currentVersion,releaseTrain:releaseTrain}' \
  --output table

Bestätigen Sie, dass der Erweiterungstyp microsoft.distributedaccelerator ist und der Bereitstellungszustand Succeeded ist. Die installierte Serverversion wird von currentVersion gemeldet; leiten Sie sie nicht aus der Client-Paketversion oder einem Public Image Tag ab.

Nimm diese Version zur Fehlersuche auf und überprüfe dann Controller und CRD:

DACS_VERSION=$(az k8s-extension show \
  --cluster-type managedClusters \
  --cluster-name $CLUSTER_NAME \
  --resource-group $RESOURCE_GROUP \
  --name distributedaccelerator \
  --query currentVersion --output tsv)

echo "$DACS_VERSION"
kubectl rollout status deployment/dacs-manager --namespace kube-system --timeout=5m
kubectl get crd caches.storage.azure.com

Fahren Sie nur fort, wenn die Erweiterung im Zustand Succeeded ist und der Controller bereit ist. Wenn Installations- oder Bereitschaftsprüfungen fehlschlagen, siehe Problembehandlung für verteilten Beschleuniger für Cloudspeicher.

Cache bereitstellen

Überprüfen Sie die Vorbereitung des lokalen NVMe

Die verwaltete Erweiterung bereitet lokale NVMe-Festplatten über ihr vorausgesetztes DaemonSet vor. Stellen Sie keine doppelte Festplatten-Setup-Workload bereit und installieren Sie kein weiteres Voraussetzungs-Chart.

kubectl rollout status daemonset/dacs-prereq \
  --namespace kube-system --timeout=10m

kubectl get daemonset dacs-prereq --namespace kube-system
kubectl get pods --namespace kube-system --selector app.kubernetes.io/name=dacs-prereq --output wide

Bestätigen Sie, dass das DaemonSet auf jedem beschrifteten Cache-Knoten einen Ready-Pod hat. Der Mount-Punkt ist /var/lib/ssd/cacheserver und muss mit dem spec.storage.hostPath.nodeCacheFolderPath der Cache-Ressource übereinstimmen. Wenn das DaemonSet fehlt oder nicht bereit ist, stoppe und überprüfe die Erweiterungsversion und die erforderlichen Pod-Events, anstatt ein separates Diagramm zu installieren.

Erstelle einen dedizierten Namensraum für den Cache- und Testworkload:

kubectl create namespace "$CACHE_NAMESPACE"

Erstellen Sie die Cache-Ressource

Erstellen Sie die Cache-Ressource. Das Beispiel konfiguriert drei Cache-Server, mit einem Server pro beschriftetem NVMe-Knoten, und erfordert mindestens drei geeignete Knoten. Passe Serveranzahl, Cache-Größe, CPU und Speicher an deinen Node-Pool an.

cat <<EOF | kubectl apply -f -
apiVersion: storage.azure.com/v1
kind: Cache
metadata:
  name: $CACHE_NAME
  namespace: $CACHE_NAMESPACE
spec:
  scaling:
    static:
      numServers: 3
  serverSizeInGB: 1000
  serverThreads: 80
  cpuLimit: 4
  memoryLimitMB: 32000
  port: 9065
  metricsPort: 9096
  nodeSelectorKey: dacs.azure.com/processing-unit
  nodeSelectorValue: cpu
  storage:
    hostPath:
      nodeCacheFolderPath: /var/lib/ssd/cacheserver
EOF

Cache-Bereitschaft prüfen

Warte auf die benannte Cache-Ressource, anstatt den ersten Cache im Cluster auszuwählen:

kubectl wait \
  --namespace $CACHE_NAMESPACE \
  --for=condition=Ready \
  cache/$CACHE_NAME \
  --timeout=10m

kubectl get cache,pods \
  --namespace $CACHE_NAMESPACE \
  --output wide

Überprüfen Sie, ob die aktuellen und gewünschten Cache-Server-Zählungen übereinstimmen und dass jeder Cache-Server-Pod auf einem NVMe-Knoten läuft.

Erhalten Sie den von Workload-Clients verwendeten Discovery-Hostnamen:

CACHE_DISCOVERY_URL=$(kubectl get cache $CACHE_NAME \
  --namespace $CACHE_NAMESPACE \
  -o jsonpath='{.status.discoveryURL}')

echo $CACHE_DISCOVERY_URL

Gewähren Sie Lesezugriff auf Modelldaten

Dieser Quickstart verwendet die vom AKS-Kubelet verwaltete Identität. Rufen Sie Ihre Objekt-ID und die Ressourcen-ID des Speicherkontos ab:

KUBELET_OBJECT_ID=$(az aks show \
  --resource-group $RESOURCE_GROUP \
  --name $CLUSTER_NAME \
  --query identityProfile.kubeletidentity.objectId \
  --output tsv)

KUBELET_CLIENT_ID=$(az aks show \
  --resource-group $RESOURCE_GROUP \
  --name $CLUSTER_NAME \
  --query identityProfile.kubeletidentity.clientId \
  --output tsv)

STORAGE_ID=$(az storage account show \
  --resource-group $RESOURCE_GROUP \
  --name $STORAGE_ACCOUNT \
  --query id \
  --output tsv)

Weise die Least-Privilege-Read-Rolle im Container-Scope zu:

az role assignment create \
  --assignee-object-id $KUBELET_OBJECT_ID \
  --assignee-principal-type ServicePrincipal \
  --role "Storage Blob Data Reader" \
  --scope "$STORAGE_ID/blobServices/default/containers/$STORAGE_CONTAINER"

Rollenzuweisungen können mehrere Minuten dauern, bis sie verbreitet werden. Um die Kubelet-Identität zu verwenden, legen Sie alle drei in der Pod-Spezifikation gezeigten Variablen für die verwaltete Identität fest: AZURE_CLIENT_ID, MSI_ENDPOINT und ein nichtleeres MSI_SECRET. Nur AZURE_CLIENT_ID zu setzen reicht für diese Client-Konfiguration nicht aus.

Füge den Client zu einem Workload-Image hinzu

Erstelle eine Datei mit dem Namen Dockerfile in deinem Build-Verzeichnis mit folgendem Inhalt. Der Verteilungsname ist dacs-client, und der Python-Importnamensraum lautetpy_dacs_client:

FROM python:3.12-slim-bookworm
RUN python3 -m pip install --no-cache-dir "dacs-client==0.1.0"

Baue das Image und pushe es in eine Registry, aus der dein AKS-Cluster abrufen kann. Für Azure Container Registry (ACR) sollten Sie sich vor dem Pushen anmelden und sicherstellen, dass die Kubelet-Identität Image-Pull-Zugriff hat. Für ein Register mit RBAC-Registrierungsberechtigungen erteilen AcrPull Sie es im Registrierungsbereich. Für eine ABAC-fähige Registry verwenden Sie stattdessen die entsprechende repository-reader-Rolle. Für Details siehe Authenticate with Azure Container Registry from Azure Kubernetes Service.

WORKLOAD_IMAGE=<registry-name>.azurecr.io/dacs-test:0.1.0

docker build \
  --tag $WORKLOAD_IMAGE .
docker push $WORKLOAD_IMAGE

Stelle einen Read-Only-Test bereit

Wählen Sie einen bestehenden Modellblob und legen Sie seinen Pfad fest:

MODEL_BLOB=<path-to-model-blob>

Erstellen Sie einen Test-Pod. Der Pod liest fünfmal bis zu 4 MiB aus dem Blob aus, mit einem Intervall von einer Sekunde zwischen den Lesungen, und überprüft, dass alle Lesungen die gleiche SHA-256-Prüfsumme zurückgeben. Die Cache-Befüllung ist asynchron, daher kann ein unmittelbarer zweiter Lesezugriff am Cache vorbeigehen. Die Intervalle geben den Hintergrund-Uploads Zeit zum Abschluss; verwenden Sie die Client-Metriken und Serverzähler, um Cache-Hits zu bestätigen, anstatt anzunehmen, dass ein bestimmter Read ein Hit ist. Um Serverzähler zu vergleichen, erfassen Sie vor der Erstellung des Pods eine Baseline, indem Sie den DACS-Anfragepfad überprüfen.

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: dacs-test
  namespace: $CACHE_NAMESPACE
spec:
  restartPolicy: Never
  containers:
    - name: test
      image: $WORKLOAD_IMAGE
      env:
        - name: CACHE_DISCOVERY_URL
          value: "$CACHE_DISCOVERY_URL"
        - name: CACHE_SERVER_PORT
          value: "9065"
        - name: DACS_CPU_CORES
          value: "2"
        - name: DACS_MEMORY_MB
          value: "512"
        - name: AZURE_CLIENT_ID
          value: "$KUBELET_CLIENT_ID"
        - name: MSI_ENDPOINT
          value: "http://169.254.169.254/metadata/identity/oauth2/token"
        - name: MSI_SECRET
          value: "required-nonempty-value"
        - name: MODEL_PATH
          value: "az://$STORAGE_ACCOUNT.blob.core.windows.net/$STORAGE_CONTAINER/$MODEL_BLOB"
      command: ["python3", "-c"]
      resources:
        requests:
          cpu: "1"
          memory: 512Mi
        limits:
          cpu: "2"
          memory: 1Gi
      args:
        - |
          import asyncio
          import ctypes
          import hashlib
          import os
          import time

          from py_dacs_client.dacs_client import DACSCacheClient
          from py_dacs_client.dacs_utils import BoundedBufferManager

          async def main():
              path = os.environ["MODEL_PATH"]
              client = DACSCacheClient()
              buffers = BoundedBufferManager(max_memory_limit=64 * 1024 * 1024)
              try:
                  size = min(await client.get_file_size(path), 4 * 1024 * 1024)
                  if size == 0:
                      raise ValueError("Choose a nonempty model blob")
                  first_digest = None
                  for attempt in range(1, 6):
                      start = time.perf_counter()
                      buffer = await buffers.acquire_buffer(size)
                      try:
                          count = await client.read_blob(path, buffer, size, 0)
                          if count != size:
                              raise RuntimeError(f"Expected {size} bytes, received {count}")
                          digest = hashlib.sha256(ctypes.string_at(buffer, count)).hexdigest()
                          if first_digest is not None and digest != first_digest:
                              raise RuntimeError("Repeated reads returned different data")
                          first_digest = digest
                      finally:
                          await buffers.release_buffer(buffer)
                      elapsed = time.perf_counter() - start
                      print(f"read {attempt}: {count} bytes in {elapsed:.3f}s; sha256={digest}")
                      if attempt < 5:
                          await asyncio.sleep(1)
              finally:
                  await client.shutdown()

          asyncio.run(main())
EOF

kubectl wait \
  --namespace "$CACHE_NAMESPACE" \
  --for=jsonpath='{.status.phase}'=Succeeded \
  pod/dacs-test \
  --timeout=5m

kubectl logs dacs-test --namespace "$CACHE_NAMESPACE"

Verifizieren Sie den DACS-Anfragepfad

Ein erfolgreicher Read oder ein schnellerer zweiter Read allein ist kein Beweis dafür, dass die Anfrage DACS erreicht hat, da der Client auf Azure Blob Storage zurückgreifen kann. Setze sowohl CACHE_DISCOVERY_URL als auch CACHE_SERVER_PORT. Wenn einer von beiden fehlt, protokolliert der Client Cache not configured. Working in Remote Blob mode only.

Überprüfen Sie die Pod-Logs auf die Client-Abschaltmetriken cache_client_download_cache_hits und cache_client_download_cache_misses. Eine nicht null Cache-Hit-Zahl zeigt an, dass eine Anfrage aus dem Cache bedient wurde. Client-Zähler können interne Anfragen enthalten und entsprechen nicht unbedingt der Anzahl der Lesevorgänge der Anwendung.

Vergleichen Sie außerdem die Cache-Server-Anfragezähler vor und nach der Ausführung des Tests. Überprüfe jeden Cache-Server-Pod, denn die Anfrage könnte von jedem Server bedient werden, nicht unbedingt vom ersten Pod. Um einen Server zu inspizieren:

CACHE_POD=$(kubectl get pods \
  --namespace $CACHE_NAMESPACE \
  --selector app=cacheserver \
  -o jsonpath='{.items[0].metadata.name}')

kubectl port-forward \
  --namespace $CACHE_NAMESPACE \
  pod/$CACHE_POD 9096:9096

In einem anderen Terminal holen Sie die Metriken ab und inspizieren Sie den Anforderungszähler:

curl --fail --silent --show-error http://localhost:9096/metrics > dacs-metrics.txt
grep '^cache_server_request_counter' dacs-metrics.txt

Verifizieren Sie mit request_type="Download" und status="Success" einen Anstieg bei den Download-Anfragen, nicht nur das Vorhandensein einer Zählerzeitreihe, die auch bei null vorhanden sein kann. Werte von Labels sind groß-/kleinschreibungssensitiv. Stoppe das Port-Forwarding und wiederhole das bei Bedarf für andere Cache-Server-Pods. Korrelieren Sie Client-Cache-Hit-Metriken mit Serverzählern und Azure Blob-Telemetrie, um Cache-Hits, Ursprungsverkehr und Rückfallverhalten zu unterscheiden.

Für die vollständige Metrikreferenz- und Scrape-Konfiguration siehe Monitor distributed accelerator for cloud storage.

Den Test bereinigen

kubectl delete pod dacs-test --namespace "$CACHE_NAMESPACE"

Wenn du den Cache nicht mehr brauchst, lösche die Cache-Ressource, während der Controller läuft:

kubectl delete cache "$CACHE_NAME" --namespace "$CACHE_NAMESPACE" --wait=true
kubectl get cache -A

Löschen Sie den Namensraum nur, wenn er diesem Quickstart gewidmet war und keine Ressourcen enthält, die Sie behalten müssen:

kubectl delete namespace "$CACHE_NAMESPACE"

Nachdem alle Cache-Ressourcen und abhängigen Arbeitslasten entfernt wurden, deaktivieren Sie die verwaltete Erweiterung:

az aks update \
  --resource-group $RESOURCE_GROUP \
  --name $CLUSTER_NAME \
  --disable-azure-container-storage distributedAccelerator

Das Deaktivieren von DACS entfernt die verwaltete Erweiterung, den Controller und das erforderliche DaemonSet, behält aber den Cache-CRD bei. Lösche nicht die verwalteten Voraussetzungen separat, deinstalliere nicht direkt das Helm-Release der Erweiterung oder lösche die CRD manuell. Entferne jegliche Rollenzuweisung oder Knotenpool-Bezeichnung, die ausschließlich für diesen Quickstart hinzugefügt wurde, erst nachdem bestätigt wurde, dass keine andere Arbeitslast sie benötigt.

Weitere Informationen finden Sie unter Remove distributed accelerator for cloud storage.

Nächste Schritte