Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Este inicio rápido permite un acelerador distribuido para almacenamiento en la nube (DACS) a través de su extensión gestionada en un clúster de Azure Kubernetes Service (AKS) existente, concede acceso de lectura a un contenedor de Azure Blob y verifica que las lecturas repetidas usen la caché. El ejemplo de la carga de trabajo utiliza el paquete público dacs-client==0.1.0 .
Important
El acelerador distribuido para almacenamiento en la nube está en vista previa. Las características en versión preliminar se proporcionan sin un contrato de nivel de servicio y no se recomiendan para cargas de trabajo de producción. Para obtener más información, vea Términos de uso complementarios para las versiones preliminares de Microsoft Azure.
Prerequisites
Antes de comenzar, necesita lo siguiente:
- Una suscripción a Azure.
- Un clúster AKS existente que cumpla con los requisitos de soporte para la vista previa de DACS.
- Un pool de nodos de caché de Linux con discos de datos NVMe locales, como la
Standard_L*s_v3familia VM. - Una cuenta de Azure Storage y un contenedor Blob que contienen datos representativos del modelo.
- Un shell Bash con CLI de Azure,
kubectly Docker u otra herramienta de compilación de imágenes de contenedor. Ejecuta los comandos de este inicio rápido en la misma sesión de shell para que las variables sigan disponibles. - Permiso para instalar extensiones AKS, administrar recursos de Kubernetes, actualizar etiquetas del pool de nodos y asignar el rol de acceso a datos de almacenamiento utilizado en este inicio rápido.
- Una imagen de carga de trabajo con Python 3.8 o posterior y glibc 2.35 o posterior. Este inicio rápido utiliza
python:3.12-slim-bookwormy el paquete PyPIdacs-client==0.1.0en nodos x64.
El acelerador distribuido para almacenamiento en la nube no utiliza el grupo de nodos de caché como almacenamiento persistente. Azure Blob Storage sigue siendo la fuente de la verdad.
Requisitos de soporte para la vista previa de DACS
| Requirement | Soporte para la vista previa de DACS |
|---|---|
| Regiones de Azure | Todas las regiones de nube pública de Azure. |
| Versiones de AKS Kubernetes | 1.35 o posterior. |
Establecer variables
Sustituye los valores provisionales y luego ejecuta los siguientes comandos:
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
Asegúrese de que está instalada la extensión de vista previa de AKS
La vista previa del DACS requiere aks-preview una versión 22.0.0b9 o una versión posterior. Instala o actualiza la extensión y las extensiones utilizadas para gestionar e inspeccionar los 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
No necesitas conectar el clúster AKS a Azure Arc. Si ya instalaste un controlador DACS manualmente, sigue Preparación para las actualizaciones antes de cambiar a la extensión gestionada. No uses dos controladores DACS en el mismo clúster.
Verifica el pool de nodos de caché
Confirma que el grupo de nodos seleccionado usa Linux y un tamaño de máquina virtual con discos de datos NVMe locales:
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
Para acelerador distribuido para almacenamiento en la nube, usa un pool de nodos de caché dedicado o confirma que otro software no reclama ni formatea los mismos discos NVMe locales.
Etiqueta el pool de nodos de caché a nivel de pool de nodos para que la etiqueta sobreviva al reemplazo de nodo. Si el pool ya tiene etiquetas personalizadas, inclúyelas en la actualización para preservarlas:
az aks nodepool update \
--resource-group $RESOURCE_GROUP \
--cluster-name $CLUSTER_NAME \
--name $CACHE_NODE_POOL \
--labels dacs.azure.com/processing-unit=cpu
Caution
Activar DACS instala un DaemonSet previo que descubre, formatea y monta discos NVMe locales en nodos de caché etiquetados. Etiquete solo los nodos con discos dedicados a la caché.
Habilitar el acelerador distribuido para almacenamiento en la nube
Activa el DACS pasando únicamente distributedAccelerator. Se requiere la mayúscula A :
az aks update \
--resource-group $RESOURCE_GROUP \
--name $CLUSTER_NAME \
--enable-azure-container-storage distributedAccelerator
El comando instala la distributedaccelerator extensión gestionada, el controlador DACS y el prerrequisito NVMe DaemonSet en kube-system, y la caches.storage.azure.com definición personalizada de recursos (CRD). No es necesario instalar una tabla de requisitos previos por separado ni gestionar uno mismo la versión de Helm de la extensión. Crea un recurso de caché por separado, como se muestra más adelante.
Verifica la extensión
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
Confirma que el tipo de extensión es microsoft.distributedaccelerator y que el estado de provisión es Succeeded. La versión instalada del servidor se reporta por currentVersion; no la infieras a partir de la versión del paquete cliente ni de una etiqueta de imagen pública.
Graba esa versión para solucionar problemas, luego verifica el controlador y el 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
Continúa solo después de que la extensión esté en el Succeeded estado y el controlador esté listo. Si fallan las comprobaciones de instalación o preparación, consulta Solucionar problemas del acelerador distribuido para el almacenamiento en la nube.
Aprovisionar la caché
Verificar la preparación local del NVMe
La extensión gestionada prepara los discos NVMe locales a través de su DaemonSet de requisito previo. No despliegues una carga de trabajo duplicada para la configuración del disco ni instales otro chart de prerrequisitos.
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
Confirma que el DaemonSet tiene un pod en estado Ready en cada nodo de caché etiquetado. El punto de montaje es /var/lib/ssd/cacheserver y debe coincidir con la spec.storage.hostPath.nodeCacheFolderPath del recurso de caché. Si falta el DaemonSet o no está listo, deténgase y compruebe la versión de la extensión y los eventos de los pods de requisitos previos, en lugar de instalar un chart independiente.
Crea un espacio de nombres dedicado para la caché y la carga de prueba:
kubectl create namespace "$CACHE_NAMESPACE"
Crear el recurso Caché
Crea el recurso Cache. El ejemplo configura tres servidores de caché, con un servidor por cada nodo NVMe etiquetado, y requiere al menos tres nodos elegibles. Ajuste el número de servidores, el tamaño de la caché, la CPU y la memoria según las características de su grupo de nodos.
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
Verificar que la caché esté lista
Espere a que esté disponible el recurso de caché especificado por su nombre, en lugar de seleccionar la primera caché del clúster:
kubectl wait \
--namespace $CACHE_NAMESPACE \
--for=condition=Ready \
cache/$CACHE_NAME \
--timeout=10m
kubectl get cache,pods \
--namespace $CACHE_NAMESPACE \
--output wide
Verifica que los conteos actuales y deseados coincidan y que cada pod de servidor de caché esté ejecutándose en un nodo NVMe.
Obtén el nombre de host de descubrimiento usado por los clientes de carga de trabajo:
CACHE_DISCOVERY_URL=$(kubectl get cache $CACHE_NAME \
--namespace $CACHE_NAMESPACE \
-o jsonpath='{.status.discoveryURL}')
echo $CACHE_DISCOVERY_URL
Conceder acceso de lectura a los datos del modelo
Este inicio rápido utiliza la identidad gestionada por AKS Kubelet. Obtén su ID de objeto y el ID de recurso de la cuenta de almacenamiento:
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)
Asignar el rol de lectura con menor privilegio en el ámbito del contenedor:
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"
La asignación de roles puede tardar varios minutos en propagarse. Para usar la identidad de Kubelet, establezca las tres variables de identidad gestionada mostradas en la especificación del pod: AZURE_CLIENT_ID, MSI_ENDPOINT y un MSI_SECRET no vacío. Configurar solo AZURE_CLIENT_ID no es suficiente para esta configuración del cliente.
Agregar el cliente a una imagen de carga de trabajo
Crea un archivo llamado Dockerfile en tu directorio de compilación con el siguiente contenido. El nombre de la distribución es dacs-client, y el espacio de nombres de importación de Python es py_dacs_client:
FROM python:3.12-slim-bookworm
RUN python3 -m pip install --no-cache-dir "dacs-client==0.1.0"
Compila y envía la imagen a un registro del que tu clúster AKS pueda extraer. Para Azure Container Registry (ACR), inicie sesión antes de insertar la imagen y asegúrese de que la identidad de kubelet tenga permisos para extraer imágenes. Para un registro que utiliza permisos de registro RBAC, concede AcrPull en el alcance del registro. Para un registro habilitado por ABAC, utilice el rol de lector de repositorio correspondiente. Para obtener detalles, consulte Autenticación con Azure Container Registry desde Azure Kubernetes Service.
WORKLOAD_IMAGE=<registry-name>.azurecr.io/dacs-test:0.1.0
docker build \
--tag $WORKLOAD_IMAGE .
docker push $WORKLOAD_IMAGE
Implementar una prueba de solo lectura
Elige un blob de modelo existente y establece su ruta:
MODEL_BLOB=<path-to-model-blob>
Crea un pod de prueba. El pod lee hasta 4 MiB del blob cinco veces, con un intervalo de un segundo entre lecturas, y verifica que todas las lecturas devuelvan la misma suma de comprobación SHA-256. La caché se rellena de forma asincrónica, así que una segunda lectura inmediata puede pasar por alto la caché. Los intervalos dan tiempo a las subidas en segundo plano para completarse; utiliza las métricas del cliente y los contadores del servidor para confirmar los aciertos de caché en lugar de asumir que una lectura concreta es un acierto de caché. Para comparar contadores de servidor, captura una línea base antes de crear el pod siguiendo Verificar la ruta de solicitud de 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 la ruta de solicitud DACS
Una lectura exitosa o una segunda lectura más rápida por sí sola no demuestran que la solicitud haya llegado al DACS porque el cliente puede recurrir a Azure Blob Storage. Establece tanto CACHE_DISCOVERY_URL como CACHE_SERVER_PORT. Si falta alguno de ellos, el cliente registra Cache not configured. Working in Remote Blob mode only.
Inspecciona los logs del pod para las métricas de apagado del cliente cache_client_download_cache_hits y cache_client_download_cache_misses. Un recuento de acertos en caché distinto de cero indica que se ha atendido una solicitud desde la caché. Los contadores de cliente pueden incluir solicitudes internas y no necesariamente equivalen al número de lecturas de aplicaciones.
También compara los contadores de peticiones del servidor de caché antes y después de ejecutar la prueba. Revisa cada pod de caché-servidor porque la solicitud podría ser atendida por cualquier servidor, no necesariamente por el primer pod. Para inspeccionar un servidor:
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
En otro terminal, recupera las métricas e inspecciona el contador de solicitudes:
curl --fail --silent --show-error http://localhost:9096/metrics > dacs-metrics.txt
grep '^cache_server_request_counter' dacs-metrics.txt
Confirme un aumento en las solicitudes de descarga con request_type="Download" y status="Success", no solo la presencia de una serie de contadores, que puede tener un valor de cero. Los valores de la etiqueta distinguen entre mayúsculas y minúsculas. Detener el reenvío de puertos y repetir para otros pods de servidor de caché según sea necesario. Correlaciona las métricas de aciertos de caché del cliente con contadores de servidor y telemetría de Azure Blob para distinguir los aciertos de caché, el tráfico de origen y el comportamiento de respaldo.
Para la referencia completa de métricas y la configuración de recopilación, consulta Supervisar el acelerador distribuido para el almacenamiento en la nube.
Limpiar la prueba
kubectl delete pod dacs-test --namespace "$CACHE_NAMESPACE"
Si ya no necesitas la caché, elimina el recurso de caché mientras el controlador está en marcha:
kubectl delete cache "$CACHE_NAME" --namespace "$CACHE_NAMESPACE" --wait=true
kubectl get cache -A
Elimina el espacio de nombres solo si estaba dedicado a este inicio rápido y no contiene recursos que necesites conservar:
kubectl delete namespace "$CACHE_NAMESPACE"
Después de eliminar todos los recursos de caché y cargas de trabajo dependientes, desactiva la extensión gestionada:
az aks update \
--resource-group $RESOURCE_GROUP \
--name $CLUSTER_NAME \
--disable-azure-container-storage distributedAccelerator
Al deshabilitar DACS, se eliminan la extensión administrada, el controlador y el DaemonSet de requisitos previos, pero se conserva la definición de recursos personalizados (CRD) de caché. No elimine los requisitos previos administrados por separado, no desinstale directamente la versión de Helm de la extensión ni elimine manualmente la CRD. Elimina cualquier asignación de rol o etiqueta de nodo añadida únicamente para este inicio rápido solo después de confirmar que ninguna otra carga de trabajo la necesita.
Para más información, consulta Eliminar acelerador distribuido para almacenamiento en la nube.
Pasos siguientes
- Usa el acelerador distribuido para el almacenamiento en la nube con BlobFuse2.
- Usa un acelerador distribuido para almacenamiento en la nube con el cliente de Python.
- Gestionar el acelerador distribuido para almacenamiento en la nube.
- Supervisar el acelerador distribuido para el almacenamiento en la nube.
- Soluciona problemas con el acelerador distribuido para almacenamiento en la nube.