Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo quickstart consente l'acceleratore distribuito per lo storage cloud (DACS) tramite la sua estensione gestita su un cluster Servizio Azure Kubernetes (AKS) esistente, concede accesso alla lettura a un container Azure Blob e verifica che le letture ripetute utilizzino la cache. L'esempio del workload utilizza il pacchetto pubblico dacs-client==0.1.0.
Important
L'acceleratore distribuito per lo storage cloud è in anteprima. Le funzionalità di anteprima vengono fornite senza un contratto di servizio e non sono consigliate per i carichi di lavoro di produzione. Per ulteriori informazioni, vedere Condizioni supplementari per l'uso delle versioni di anteprima di Microsoft Azure.
Prerequisites
Prima di iniziare, è necessario disporre di quanto segue:
- Una sottoscrizione di Azure.
- Un cluster AKS esistente che soddisfa i requisiti di supporto per la preview DACS.
- Un pool di nodi cache Linux con dischi dati NVMe locali, come la
Standard_L*s_v3famiglia VM. - Un account Archiviazione di Azure e un container Blob contenenti dati rappresentativi del modello.
- Una shell Bash con interfaccia della riga di comando di Azure,
kubectle Docker o un altro strumento di build container-image. Esegui i comandi in questo avvio rapido nella stessa sessione di shell in modo che le variabili rimangano disponibili. - Permesso di installare estensioni AKS, amministrare le risorse Kubernetes, aggiornare le etichette del pool di nodi e assegnare il ruolo di accesso ai dati di archiviazione utilizzato in questo avvio rapido.
- Un'immagine del carico di lavoro con Python 3.8 o successivo e glibc 2.35 o successiva. Questo quickstart utilizza
python:3.12-slim-bookworme il pacchetto PyPIdacs-client==0.1.0su nodi x64.
Distributed accelerator per cloud storage non utilizza il pool di nodi della cache come storage persistente. Archiviazione BLOB di Azure rimane la fonte attendibile.
Requisiti di supporto per l'anteprima DACS
| Requirement | Supporto per l'anteprima DACS |
|---|---|
| Regioni di Azure | Tutte le aree del cloud pubblico di Azure. |
| Versioni di Kubernetes AKS | 1.35 o successive. |
Impostare variabili
Sostituisci i valori segnaposto e poi esegui i seguenti comandi:
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
Verificare che l'estensione di anteprima AKS sia installata
L'anteprima DACS richiede aks-preview versione 22.0.0b9 o successiva. Installa o aggiorna l'estensione e le estensioni utilizzate per gestire e ispezionare i DACS:
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
Non è necessario collegare il cluster del servizio Azure Kubernetes ad Azure Arc. Se è già stato installato manualmente un controller DACS, seguire Prepararsi per gli aggiornamenti prima di passare all'estensione gestita. Non usare due controller DACS sullo stesso cluster.
Verifica il pool di nodi della cache
Conferma che il pool di nodi selezionato utilizza Linux e una dimensione di VM con dischi dati NVMe locali:
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
Per un acceleratore distribuito per l'archiviazione cloud, usare un pool dedicato di nodi della cache o confermare che altri software non attestino né formattino gli stessi dischi NVMe locali.
Etichetta il pool di nodi cache a livello di pool di nodi così che l'etichetta sopravviva alla sostituzione del nodo. Se il pool ha già etichette personalizzate, includile nell'aggiornamento per preservarle:
az aks nodepool update \
--resource-group $RESOURCE_GROUP \
--cluster-name $CLUSTER_NAME \
--name $CACHE_NODE_POOL \
--labels dacs.azure.com/processing-unit=cpu
Caution
Abilitando DACS si installa un DaemonSet prerequisito che scopre, formatta e monta dischi NVMe locali su nodi di cache etichettati. Etichetta solo i nodi con dischi dedicati alla cache.
Abilita l'acceleratore distribuito per lo storage cloud
Abilita il DACS passando solo distributedAccelerator. La maiuscola A è richiesta:
az aks update \
--resource-group $RESOURCE_GROUP \
--name $CLUSTER_NAME \
--enable-azure-container-storage distributedAccelerator
Il comando installa l'estensione distributedaccelerator gestita, il controller DACS e il prerequisito NVMe DaemonSet in kube-system, e la caches.storage.azure.com definizione personalizzata della risorsa (CRD). Non installi un chart separato dei prerequisiti né gestisci tu stesso la release Helm dell'estensione. Crea una risorsa Cache separatamente come mostrato più avanti.
Verificare l'estensione
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
Conferma che il tipo di estensione sia microsoft.distributedaccelerator e che lo stato di provisioning sia Succeeded. La versione server installata è segnalata da currentVersion; non dedurla dalla versione del pacchetto client o da un tag immagine pubblica.
Registra quella versione per la risoluzione dei problemi, poi verifica il controller e il 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
Continua solo dopo che l'estensione è nello stato Succeeded e il controller è pronto. Se i controlli di installazione o preparazione non riescono, vedere Risolvere i problemi dell'acceleratore distribuito per l'archiviazione cloud.
Effettuare il provisioning della cache
Verifica la preparazione locale del NVMe
L'estensione gestita prepara i dischi NVMe locali tramite il suo prerequisito DaemonSet. Non distribuire un workload duplicato di configurazione del disco né installare un altro chart dei prerequisiti.
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
Conferma che il DaemonSet abbia un pod Ready su ogni nodo della cache etichettato. Il punto di montaggio è /var/lib/ssd/cacheserver e deve corrispondere al spec.storage.hostPath.nodeCacheFolderPath della risorsa della cache. Se il DaemonSet manca o non è pronto, fermati e controlla la versione dell'estensione e gli eventi dei pod prerequisito invece di installare un chart separato.
Crea un namespace dedicato per la Cache e il workload di test:
kubectl create namespace "$CACHE_NAMESPACE"
Crea la risorsa Cache
Crea la risorsa Cache. L'esempio configura tre server cache, con un server per ogni nodo NVMe etichettato, e richiede almeno tre nodi idonei. Regola il numero di server, la dimensione della cache, la CPU e la memoria per adattarli al pool di nodi.
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
Verificare l'idoneità della cache
Aspettare la risorsa Cache nominata invece di selezionare la prima cache nel cluster:
kubectl wait \
--namespace $CACHE_NAMESPACE \
--for=condition=Ready \
cache/$CACHE_NAME \
--timeout=10m
kubectl get cache,pods \
--namespace $CACHE_NAMESPACE \
--output wide
Verifica che i conteggi attuali e desiderati del server cache corrispondano e che ogni pod server cache sia in esecuzione su un nodo NVMe.
Recuperare il nome host di individuazione usato dai client del carico di lavoro:
CACHE_DISCOVERY_URL=$(kubectl get cache $CACHE_NAME \
--namespace $CACHE_NAMESPACE \
-o jsonpath='{.status.discoveryURL}')
echo $CACHE_DISCOVERY_URL
Concedi accesso in lettura ai dati del modello
Questo quickstart utilizza l'identità gestita AKS kubelet. Ottieni il suo ID oggetto e l'ID della risorsa dell'account di archiviazione:
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)
Assegna il ruolo di lettura con il minor privilegio nell'ambito del container:
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"
Le assegnazioni dei ruoli possono richiedere diversi minuti per essere propagate. Per usare l'identità di Kubelet, impostare tutte e tre le variabili di identità gestita mostrate nella specifica del pod: AZURE_CLIENT_ID, MSI_ENDPOINT, e un non vuoto MSI_SECRET. Impostare solo AZURE_CLIENT_ID non è sufficiente per questa configurazione client.
Aggiungere il client a un'immagine del carico di lavoro
Crea un file chiamato Dockerfile nella tua directory build con il seguente contenuto. Il nome della distribuzione è dacs-client, e lo spazio di importazione Python è py_dacs_client:
FROM python:3.12-slim-bookworm
RUN python3 -m pip install --no-cache-dir "dacs-client==0.1.0"
Compila e spingi l'immagine in un registro da cui il tuo cluster AKS possa prelevare. Per Registro Azure Container (ACR), accedi prima di fare push e assicurati che l'identità kubelet abbia l'autorizzazione per il pull delle immagini. Per un registro che utilizza Autorizzazioni del registro RBAC, concedere AcrPull a livello di registro. Per un registro abilitato ABAC, usa invece il ruolo appropriato di lettore di repository. Per dettagli, vedi Authenticate with Registro Azure Container from servizio Azure Kubernetes.
WORKLOAD_IMAGE=<registry-name>.azurecr.io/dacs-test:0.1.0
docker build \
--tag $WORKLOAD_IMAGE .
docker push $WORKLOAD_IMAGE
Implementa un test di sola lettura
Scegli un blob di modello esistente e imposta il suo percorso:
MODEL_BLOB=<path-to-model-blob>
Crea un pod di test. Il pod legge fino a 4 MiB dal blob cinque volte, con un intervallo di un secondo tra una lettura e l'altra, e verifica che tutte le letture restituiscano lo stesso checksum SHA-256. La popolazione della cache è asincrona, quindi una seconda lettura immediata può non trovare la cache. Gli intervalli danno tempo ai caricamenti in background per completarsi; utilizzare le metriche client e i contatori server per confermare gli hit della cache invece di presumere che una lettura particolare sia un hit. Per confrontare i contatori del server, cattura una linea di base prima di creare il pod seguendo Verificare il percorso della richiesta DACS.
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"
Verifica il percorso di richiesta DACS
Una lettura riuscita o una seconda lettura più veloce da sola non sono la prova che la richiesta sia arrivata al DACS perché il client può ripiegare su Archiviazione BLOB di Azure. Imposta sia CACHE_DISCOVERY_URL che CACHE_SERVER_PORT. Se manca uno dei due, il client registra Cache not configured. Working in Remote Blob mode only.
Ispeziona i log dei pod per le metriche di spegnimento del client cache_client_download_cache_hits e cache_client_download_cache_misses. Un conteggio di cache hit non nullo indica che una richiesta è stata servita dalla cache. I contatori client possono includere richieste interne e non necessariamente corrispondono al numero di letture applicative.
Confronta anche i contatori di richiesta del server cache prima e dopo l'esecuzione del test. Controlla ogni pod cache-server perché la richiesta potrebbe essere servita da qualsiasi server, non necessariamente dal primo pod. Per ispezionare un server:
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 un altro terminale, recupera le metriche e ispeziona il contatore delle richieste:
curl --fail --silent --show-error http://localhost:9096/metrics > dacs-metrics.txt
grep '^cache_server_request_counter' dacs-metrics.txt
Conferma un aumento delle richieste di download con request_type="Download" e status="Success", non solo la presenza di una serie di contatori, che può esistere a zero. I valori delle etichette sono sensibili a maiuscole e minuscole. Interrompi il port-forwarding e ripeti per altri pod di cache server se necessario. Correla le metriche di cache-hit del client con i server counter e la telemetria Azure Blob per distinguere i hit della cache, il traffico di origine e il comportamento di fallback.
Per il riferimento completo delle metriche e della configurazione di scrape, vedi Monitorare l'acceleratore distribuito per l'archiviazione cloud.
Pulisci il test
kubectl delete pod dacs-test --namespace "$CACHE_NAMESPACE"
Se non hai più bisogno della cache, elimina la risorsa Cache mentre il controller è in funzione:
kubectl delete cache "$CACHE_NAME" --namespace "$CACHE_NAMESPACE" --wait=true
kubectl get cache -A
Elimina lo spazio dei nomi solo se era dedicato a questo quickstart e non contiene risorse da conservare:
kubectl delete namespace "$CACHE_NAMESPACE"
Dopo aver rimosso tutte le risorse della cache e i carichi di lavoro dipendenti, disabilita l'estensione gestita:
az aks update \
--resource-group $RESOURCE_GROUP \
--name $CLUSTER_NAME \
--disable-azure-container-storage distributedAccelerator
Disabilitare DACS rimuove la sua estensione gestita, il controller e il DaemonSet prerequisito ma mantiene il CRD della cache. Non eliminare separatamente i prerequisiti gestiti, disinstalla direttamente la release Helm dell'estensione o elimina manualmente il CRD. Rimuovere qualsiasi assegnazione di ruolo o etichetta del pool di nodi aggiunta esclusivamente per questo avvio rapido solo dopo aver confermato che nessun altro carico di lavoro ne abbia bisogno.
Per maggiori informazioni, vedi Rimuovere acceleratore distribuito per lo storage cloud.
Passaggi successivi
- Usa l'acceleratore distribuito per lo storage cloud con BlobFuse2.
- Usa un acceleratore distribuito per lo storage cloud con il client Python.
- Gestisci un acceleratore distribuito per lo storage cloud.
- Monitorare un acceleratore distribuito per l'archiviazione cloud.
- Risoluzione dei problemi con acceleratore distribuito per lo storage cloud.