For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://docs.nvidia.com/dynamo/llms.txt. For full content including API reference and SDK examples, see https://docs.nvidia.com/dynamo/llms-full.txt.
RDMA / InfiniBand в AKS
RDMA / InfiniBand в AKS
В этом руководстве показано, как настроить RDMA поверх InfiniBand в AKS для высокопроизводительного disaggregated inference с Dynamo. RDMA обеспечивает прямой доступ к памяти между GPU на разных узлах, обходя накладные расходы CPU и kernel — это критично для низколатентной передачи KV cache между workers prefill и decode.
Без RDMA disaggregated inference откатывается к TCP с серьезным падением производительности (~98 с TTFT против ~200-500 мс с RDMA). Подробности о вариантах транспорта и ожидаемой производительности см. в Disaggregated Communication Guide.
Шаги Network Operator и NicClusterPolicy в этом руководстве основаны на репозитории Azure AKS RDMA InfiniBand. Этот проект open-source и не поддерживается Microsoft Azure — сообщайте о проблемах в GitHub repository.
Предварительные требования
AKS cluster с узлами, поддерживающими RDMA:
- как минимум 2 GPU-узла для включения cross-node RDMA communication
- VM серии ND с InfiniBand NIC Mellanox ConnectX (например,
Standard_ND96asr_v4,Standard_ND96isr_H100_v5) - Ubuntu OS в node pool (требуется для совместимости с NVIDIA driver)
- установка GPU driver пропущена в node pool (
--skip-gpu-driver-install) — см. GPU Node Pool Setup
Зарегистрируйте AKS InfiniBand feature, чтобы гарантировать, что узлы окажутся в одной физической InfiniBand-сети:
az feature register --namespace Microsoft.ContainerService --name AKSInfinibandSupport
az feature show --namespace Microsoft.ContainerService --name AKSInfinibandSupport --query "properties.state"
# Wait until "Registered"
az provider register --namespace Microsoft.ContainerService
Обзор
Настройка RDMA включает пять компонентов, устанавливаемых в следующем порядке:
- Network Operator — разворачивает Mellanox OFED driver и Node Feature Discovery
- NicClusterPolicy — настраивает OFED driver на узлах с поддержкой InfiniBand
- IB Node Configuration — загружает InfiniBand kernel modules и задает memlock limits
- RDMA Shared Device Plugin — предоставляет InfiniBand NIC подам как Kubernetes resource
- GPU Operator — устанавливается со специфичными для RDMA настройками (NFD отключен, GPUDirect RDMA включен, host MOFED)
Шаг 1: Установите NVIDIA Network Operator
NVIDIA Network Operator автоматизирует развертывание сетевых компонентов, включая Mellanox OFED drivers для поддержки InfiniBand.
Создайте namespace и пометьте его для привилегированных workloads:
kubectl create ns network-operator
kubectl label --overwrite ns network-operator pod-security.kubernetes.io/enforce=privileged
Добавьте NVIDIA Helm repo (если он еще не добавлен):
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
Создайте network-operator-values.yaml:
nfd:
deployNodeFeatureRules: false
Установите Network Operator:
helm install network-operator nvidia/network-operator \
--namespace network-operator \
-f network-operator-values.yaml \
--version v26.1.0
Проверьте, что pod Network Operator запущен:
kubectl get pods -n network-operator
Шаг 2: Примените NicClusterPolicy
NicClusterPolicy настраивает OFED driver (Mellanox OFED / DOCA driver) как DaemonSet на всех узлах с поддержкой InfiniBand.
Примените базовый NicClusterPolicy с помощью kustomize:
kubectl apply -k https://github.com/Azure/aks-rdma-infiniband/configs/nicclusterpolicy/base
Это нацелено на узлы с Mellanox NIC (feature.node.kubernetes.io/pci-15b3.present) и устанавливает DOCA/OFED driver как DaemonSet.
Дождитесь завершения установки MOFED driver DaemonSet на всех узлах (это может занять несколько минут):
kubectl get pods -n network-operator -l app=mofed-ubuntu22.04-ds -w
# Wait until all pods show Running
Шаг 3: Разверните IB Node Configuration DaemonSet
Этот DaemonSet загружает InfiniBand kernel modules и устанавливает unlimited memlock limits на GPU-узлах. Это требуется для работы RDMA — без этого могут не существовать файлы устройств InfiniBand, а закрепление памяти для RDMA-передач будет завершаться ошибкой.
Этот шаг не описан в Azure RDMA repo, но необходим для рабочей конфигурации. DaemonSet загружает kernel modules ib_umad и rdma_ucm, устанавливает unlimited memlock limits для containerd и kubelet и перезапускает оба сервиса, чтобы применить изменения.
Создайте ib-node-config.yaml:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ib-node-config
namespace: kube-system
spec:
selector:
matchLabels:
app: ib-node-config
template:
metadata:
labels:
app: ib-node-config
spec:
hostPID: true
nodeSelector:
kubernetes.azure.com/agentpool: <GPU_NODE_POOL_NAME>
tolerations:
- operator: Exists
initContainers:
- name: ib-setup
image: busybox:1.36
securityContext:
privileged: true
command:
- sh
- -c
- |
echo "=== IB Node Configuration ==="
nsenter -t 1 -m -u -i -n -- modprobe ib_umad
nsenter -t 1 -m -u -i -n -- modprobe rdma_ucm 2>/dev/null || true
nsenter -t 1 -m -u -i -n -- modprobe ib_ucm 2>/dev/null || true
nsenter -t 1 -m -u -i -n -- lsmod | grep ib_umad && echo "OK: ib_umad" || echo "FAIL: ib_umad"
nsenter -t 1 -m -u -i -n -- ls /dev/infiniband/rdma_cm && echo "OK: rdma_cm device" || echo "WARN: no rdma_cm device"
nsenter -t 1 -m -u -i -n -- sh -c 'printf "ib_umad\nrdma_ucm\n" > /etc/modules-load.d/ib-umad.conf'
nsenter -t 1 -m -u -i -n -- sh -c 'printf "* - memlock unlimited\nroot - memlock unlimited\n" > /etc/security/limits.d/99-ib-memlock.conf'
nsenter -t 1 -m -u -i -n -- sh -c 'mkdir -p /etc/systemd/system/containerd.service.d && printf "[Service]\nLimitMEMLOCK=infinity\n" > /etc/systemd/system/containerd.service.d/memlock.conf'
nsenter -t 1 -m -u -i -n -- sh -c 'mkdir -p /etc/systemd/system/kubelet.service.d && printf "[Service]\nLimitMEMLOCK=infinity\n" > /etc/systemd/system/kubelet.service.d/memlock.conf'
nsenter -t 1 -m -u -i -n -- systemctl daemon-reload
nsenter -t 1 -m -u -i -n -- systemctl restart containerd
nsenter -t 1 -m -u -i -n -- systemctl restart kubelet
sleep 10
nsenter -t 1 -m -u -i -n -- systemctl is-active containerd && echo "OK: containerd active" || echo "FAIL: containerd"
nsenter -t 1 -m -u -i -n -- systemctl is-active kubelet && echo "OK: kubelet active" || echo "FAIL: kubelet"
echo "=== Setup Complete ==="
containers:
- name: keepalive
image: busybox:1.36
command: ["sh", "-c", "echo IB node config active; sleep infinity"]
<GPU_NODE_POOL_NAME> на имя вашего GPU node pool (например, ndh100pool).kubectl apply -f ib-node-config.yaml
Дождитесь завершения инициализации всех pods:
kubectl get pods -n kube-system -l app=ib-node-config -w
Что это делает:
ib_umad— InfiniBand user-space management datagram module, required for RDMA device accessrdma_ucm— RDMA user-space connection manager- Memlock limits — RDMA требует закрепления страниц памяти; без unlimited memlock большие передачи завершаются ошибкой
- Service restarts — containerd и kubelet нужно перезапустить, чтобы они подхватили новые memlock limits
Шаг 4: Разверните RDMA Shared Device Plugin
RDMA Shared Device Plugin предоставляет InfiniBand NIC как Kubernetes extended resource, чтобы поды могли запрашивать RDMA access.
Создайте ConfigMap с конфигурацией device plugin:
apiVersion: v1
kind: ConfigMap
metadata:
name: rdma-devices
namespace: kube-system
data:
config.json: |
{
"periodicUpdateInterval": 300,
"configList": [{
"resourceName": "hca_shared_devices_a",
"rdmaHcaMax": 1000,
"selectors": {
"vendors": ["15b3"],
"drivers": ["mlx5_core"]
}
}
]
}
Создайте DaemonSet:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: rdma-shared-dp-ds
namespace: kube-system
spec:
selector:
matchLabels:
name: rdma-shared-dp-ds
template:
metadata:
labels:
name: rdma-shared-dp-ds
spec:
hostNetwork: true
nodeSelector:
kubernetes.azure.com/agentpool: <GPU_NODE_POOL_NAME>
tolerations:
- operator: Exists
containers:
- name: k8s-rdma-shared-dp-ds
image: ghcr.io/mellanox/k8s-rdma-shared-dev-plugin:v1.5.3
securityContext:
privileged: true
volumeMounts:
- name: device-plugin
mountPath: /var/lib/kubelet/device-plugins
- name: plugins-registry
mountPath: /var/lib/kubelet/plugins_registry
- name: config
mountPath: /k8s-rdma-shared-dev-plugin
- name: devs
mountPath: /dev/
volumes:
- name: device-plugin
hostPath:
path: /var/lib/kubelet/device-plugins
- name: plugins-registry
hostPath:
path: /var/lib/kubelet/plugins_registry
- name: config
configMap:
name: rdma-devices
- name: devs
hostPath:
path: /dev/
<GPU_NODE_POOL_NAME> with your GPU node pool name (e.g., ndh100pool).<GPU_NODE_POOL_NAME> на имя вашего GPU node pool (например, ndh100pool).kubectl apply -f rdma-configmap.yaml
kubectl apply -f rdma-shared-dp-ds.yaml
Дождитесь запуска pods device plugin:
kubectl get pods -n kube-system -l name=rdma-shared-dp-ds -w
Шаг 5: Установите GPU Operator (с включенным RDMA)
Установите GPU Operator со значениями, специфичными для RDMA:
helm install gpu-operator nvidia/gpu-operator \
--namespace gpu-operator --create-namespace \
--set nfd.enabled=false \
--set driver.rdma.enabled=true \
--set driver.rdma.useHostMofed=true
Ключевые отличия от стандартной установки GPU Operator:
nfd.enabled=false— Network Operator уже разворачивает Node Feature Discovery; запуск двух экземпляров NFD приводит к конфликтамdriver.rdma.enabled=true— включает поддержку GPUDirect RDMA; заставляет driver daemonset собирать и загружатьnvidia_peermemdriver.rdma.useHostMofed=true— указывает GPU Operator использовать MOFED driver, установленный Network Operator (Шаг 1), а не собственный; это требуется, когда OFED управляется Network Operator
Дождитесь, пока pods GPU Operator перейдут в состояние Running:
kubectl get pods -n gpu-operator -w
Проверка
1. Проверьте, что pods MOFED driver запущены на всех InfiniBand-узлах:
kubectl get pods -n network-operator -l app=mofed-ubuntu22.04-ds
2. Проверьте, что pods IB node config завершили инициализацию:
kubectl get pods -n kube-system -l app=ib-node-config
3. Проверьте, что RDMA Shared Device Plugin запущен:
kubectl get pods -n kube-system -l name=rdma-shared-dp-ds
4. Проверьте, что RDMA resources доступны на GPU-узлах:
kubectl get nodes -o json | jq '.items[] | select(.status.allocatable["rdma/hca_shared_devices_a"] != null) | {name: .metadata.name, rdma: .status.allocatable["rdma/hca_shared_devices_a"], gpu: .status.allocatable["nvidia.com/gpu"]}'
Каждый узел с поддержкой InfiniBand должен сообщать ресурсы rdma/hca_shared_devices_a (обычно 1k на основе rdmaHcaMax: 1000).
5. Проверьте, что pods GPU Operator healthy:
kubectl get pods -n gpu-operator
Запросы ресурсов pod
Pods Dynamo, которым нужен RDMA access, должны запрашивать ресурс rdma/hca_shared_devices_a. При использовании Dynamo operator с DGDR это автоматически обрабатывается для disaggregated развертываний на кластерах с поддержкой RDMA.
Для ручных DGD specs добавьте запрос ресурса в контейнер:
resources:
limits:
nvidia.com/gpu: 8
rdma/hca_shared_devices_a: 1
IPC_LOCK capability is not required when this setup is followed. IPC_LOCK is historically needed for RDMA because ibv_reg_mr calls mlock() to pin memory pages — but mlock() only needs the capability if the memlock rlimit would otherwise block it. The ib-node-config DaemonSet (Step 3) sets LimitMEMLOCK=infinity on the kubelet and containerd systemd units, so all pods on GPU nodes inherit an unlimited memlock limit and RDMA memory pinning works without any capability in the pod spec.
If you see ENOMEM errors from ibv_reg_mr and ib-node-config is running, verify that containerd and kubelet were restarted after the limits were applied (check the init container logs). If ib-node-config is not deployed, add IPC_LOCK to your pod's securityContext.capabilities.add.
Устранение неполадок
Pods MOFED зависли в Init или CrashLoopBackOff:
- Verify nodes are Ubuntu OS:
kubectl get nodes -o custom-columns="NAME:.metadata.name,OS:.status.nodeInfo.osImage" - Check MOFED pod logs:
kubectl logs -n network-operator <mofed-pod> -c mofed-container
rdma/hca_shared_devices_a не отображается на узлах:
- Check the RDMA device plugin pods are running:
kubectl get pods -n kube-system -l name=rdma-shared-dp-ds - Check device plugin logs:
kubectl logs -n kube-system <rdma-shared-dp-pod> - Verify the
rdma-devicesConfigMap exists:kubectl get configmap rdma-devices -n kube-system
IB kernel modules не загружаются:
- Check the ib-node-config init container logs:
kubectl logs -n kube-system <ib-node-config-pod> -c ib-setup - Verify the MOFED driver is installed first (Step 2 must complete before Step 3)
Ошибки memlock во время RDMA-передач (ENOMEM от ibv_reg_mr):
- Verify the ib-node-config DaemonSet has run on all GPU nodes and init containers completed
- Check that containerd and kubelet were restarted:
kubectl logs -n kube-system <ib-node-config-pod> -c ib-setup - Confirm the limits took effect on the kubelet process:
# On a GPU node (via kubectl debug or ssh)cat /proc/$(pgrep -x kubelet)/limits | grep -i memlock# Should show: Max locked memory unlimited unlimited
- If limits are not unlimited, the ib-node-config DaemonSet needs to be re-applied and services restarted
GPUDirect RDMA не работает — отсутствует module nvidia_peermem:
Узлы серии ND (включая ND H100 v5) не поставляются с nvidia_peermem в host OS. Этот модуль требуется, чтобы InfiniBand adapters могли напрямую читать/записывать память GPU — без него RDMA-передачи откатываются к staging через host memory.
Проверьте, загружен ли модуль:
# Check on a GPU node via a privileged pod or node shell
lsmod | grep nvidia_peermem
# If empty, the module is not loaded
modinfo nvidia_peermem
# If "Module not found", it is also not present in the host's /lib/modules
Если драйверами управляет GPU Operator (driver.rdma.enabled=true), nvidia_peermem собирается и загружается nvidia-driver-daemonset — он находится в /lib/modules driver pod-а, а не в нативных kernel modules host-а. Проверьте, что driver daemonset загружает его:
kubectl exec -n gpu-operator $(kubectl get pod -n gpu-operator -l app=nvidia-driver-daemonset -o jsonpath='{.items[0].metadata.name}') -- lsmod | grep nvidia_peermem
Если вывод пустой, убедитесь, что в Helm values GPU Operator заданы driver.rdma.enabled=true и driver.rdma.useHostMofed=true (см. Шаг 5 выше), затем перезапустите driver daemonset:
kubectl rollout restart daemonset/nvidia-driver-daemonset -n gpu-operator
DaemonSet nvidia-peermem-reloader из Azure RDMA repo предназначен для кластеров, использующих AKS-managed GPU drivers (без GPU Operator). Он просто запускает modprobe nvidia-peermem — и это завершится ошибкой на узлах ND H100 v5, потому что host OS не включает этот модуль. При использовании GPU Operator (рекомендуется) operator обрабатывает nvidia_peermem автоматически через driver.rdma.enabled=true.
См. также
- Azure AKS RDMA InfiniBand — GitHub
- Set up InfiniBand on Azure HPC VMs — Microsoft Learn
- Enable InfiniBand VM extension — Microsoft Learn
- NVIDIA Network Operator Documentation
- Disaggregated Communication Guide — transport options, UCX configuration, performance expectations