Em cargas de trabalho de treinamento de IA distribuído e big data, os pods se comunicam frequentemente. O agendador padrão do Kubernetes distribui os pods uniformemente entre os nós, o que pode resultar em pods alocados em nós separados por múltiplos saltos de switch. Cada salto adicional aumenta a latência e reduz o throughput. O agendamento com reconhecimento de topologia de rede resolve esse problema ao atribuir todos os pods de um job a nós dentro do mesmo domínio de encaminhamento de Camada 1 ou Camada 2, minimizando os saltos de switch e acelerando a conclusão do job.
Como funciona
O agendamento com reconhecimento de topologia de rede utiliza um algoritmo guloso para atribuir jobs a nós Lingjun com a menor abrangência topológica possível.
Os clusters ACK Lingjun possuem uma topologia de rede de dois níveis:
Access Switch (ASW): interface direta para os nós Lingjun. Nós sob o mesmo ASW exigem pelo menos um salto para comunicação.
Point of Delivery (Pod): topologia de nível superior que agrupa vários ASWs. Nós sob ASWs diferentes no mesmo Pod exigem pelo menos dois saltos.
Quanto menos camadas de switch existirem entre os nós, menor será a latência. O agendador tenta primeiramente encaixar todos os pods no nível topológico mais baixo possível:
Job de 2 nós: atribuído a nós dentro do mesmo ASW (por exemplo, Par de Nós A-B ou E-F).
Job de 4 nós: atribuído a nós dentro do mesmo Pod (por exemplo, Par de Nós A-D ou E-H).
Os rótulos dos nós indicam a qual ASW e Pod cada nó pertence:
alibabacloud.com/asw-id: identifica o ASW.alibabacloud.com/point-of-delivery: identifica o Pod.
Nos clusters ACK Lingjun, o componente lingjun-networktopology-collector coleta automaticamente essas informações e aplica esses rótulos aos nós Lingjun. Para outros tipos de nós ou clusters, adicione os rótulos manualmente e garanta que as chaves dos rótulos correspondam aos valores de labelKey na configuração ClusterNetworkTopology.
Estratégias de agendamento
Duas estratégias controlam o rigor do agrupamento de pods dentro de um nível de topologia:
|
Estratégia |
Comportamento |
|
|
Agrupa os pods dentro da camada quando possível; permite agendamento entre camadas se os recursos forem insuficientes |
|
|
Exige que todos os pods estejam na mesma camada; o agendamento falha se nenhuma camada individual comportar o job |
Pré-requisitos
Antes de começar, verifique se você tem:
Um cluster ACK Lingjun
kubectl configurado para conectar-se ao cluster
Nós suficientes com rótulos de topologia aplicados
Configure e implante o agendamento com reconhecimento de topologia de rede
A configuração do agendamento com reconhecimento de topologia de rede requer três arquivos YAML: um para definir a estrutura de topologia no nível do cluster, outro para declarar as restrições de agendamento de um job específico e um terceiro para o próprio job.
Etapa 1: Defina a topologia do cluster
Crie o arquivo cluster-network-topology.yaml para declarar a estrutura de topologia de dois níveis do cluster:
apiVersion: scheduling.koordinator.sh/v1alpha1
kind: ClusterNetworkTopology
metadata:
# Keep unchanged.
name: default
spec:
networkTopologySpec:
# parentTopologyLayer declares the upper topology structure.
- parentTopologyLayer: ASWTopologyLayer
# The lowest level must be NodeTopologyLayer for Lingjun nodes.
topologyLayer: NodeTopologyLayer
# The following defines the cross-layer topology mapping. Normally, no modification is needed.
- labelKey:
- alibabacloud.com/point-of-delivery
topologyLayer: PoDTopologyLayer
- labelKey:
- alibabacloud.com/asw-id
parentTopologyLayer: PoDTopologyLayer
topologyLayer: ASWTopologyLayer
Etapa 2: Declare as restrições de topologia do job
Crie o arquivo sample-network-topology.yaml para especificar a estratégia de agendamento para cada nível de topologia:
apiVersion: scheduling.koordinator.sh/v1alpha1
kind: JobNetworkTopology
metadata:
labels:
network-topology-permit-wait-time: "999999"
# The job name.
name: sample-network-topology
# The namespace the job belongs to.
namespace: sample-network-topology
spec:
topologyStrategy:
# PreferGather: allows cross-ASW scheduling when resources are insufficient.
- layer: ASWTopologyLayer
strategy: PreferGather
- layer: NodeTopologyLayer
strategy: PreferGather
# MustGather: cross-Pod scheduling is not allowed.
- layer: PoDTopologyLayer
strategy: MustGather
# Must match spec.parallelism and pod-group.scheduling.sigs.k8s.io/min-available in the Job manifest.
workerNum: 2
Etapa 3: Crie o job
Crie o arquivo pi.yaml para definir o job e referenciar as restrições de topologia:
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
# Must match workerNum in JobNetworkTopology.
parallelism: 2
template:
metadata:
labels:
# Must match workerNum in JobNetworkTopology.
pod-group.scheduling.sigs.k8s.io/min-available: "2"
pod-group.scheduling.sigs.k8s.io/name: sample-gang
# Reference the JobNetworkTopology created in Step 2.
network-topology-job-name: sample-network-topology
network-topology-job-namespace: sample-network-topology
spec:
schedulerName: default-scheduler
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
resources:
limits:
# This example uses a single GPU. Adjust as needed.
nvidia.com/gpu: 1
restartPolicy: Never
backoffLimit: 4
Etapa 4: Implante a configuração
Aplique todos os três arquivos no cluster:
kubectl apply -f cluster-network-topology.yaml
kubectl apply -f sample-network-topology.yaml
kubectl apply -f pi.yaml
Verifique os resultados do agendamento
Verifique a topologia do cluster
Recupere os rótulos de topologia nos seus nós para confirmar a estrutura de topologia:
# Network topology:
# test-pod-1 test-pod-2
# / | \ |
# test-1 test-2 test-3 test-4
# / \ | | |
# 0.12 0.14 0.15 0.16 0.17
kubectl get no -l alibabacloud.com/asw-id,alibabacloud.com/point-of-delivery -ojson | jq '.items[] | {"Name":.metadata.name, "ASW":.metadata.labels."alibabacloud.com/asw-id", "POD":.metadata.labels."alibabacloud.com/point-of-delivery"}'
Saída esperada:
{
"Name": "cn-hongkong.10.1.0.12",
"ASW": "test-1",
"POD": "test-pod-1"
}
{
"Name": "cn-hongkong.10.1.0.14",
"ASW": "test-1",
"POD": "test-pod-1"
}
{
"Name": "cn-hongkong.10.1.0.15",
"ASW": "test-2",
"POD": "test-pod-1"
}
{
"Name": "cn-hongkong.10.1.0.16",
"ASW": "test-3",
"POD": "test-pod-1"
}
{
"Name": "cn-hongkong.10.1.0.17",
"ASW": "test-4",
"POD": "test-pod-2"
}
Cenário 1: Job de 2 pods
Com workerNum: 2, ambos os pods são agendados em nós dentro do mesmo ASW (test-1):
kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pi-8p89l 1/1 Running 0 4s 172.30.240.197 cn-hongkong.10.1.0.14 <none> <none>
pi-p8swv 0/1 ContainerCreating 0 4s <none> cn-hongkong.10.1.0.12 <none> <none>
Ambos os pods são alocados em test-1 (ASW), compartilhando o caminho de rede com o menor número de saltos.
Cenário 2: Job de 4 pods
Atualize parallelism e pod-group.scheduling.sigs.k8s.io/min-available em pi.yaml, além de workerNum em sample-network-topology.yaml para 4. Reaplique ambos os arquivos.
O agendador atribui todos os 4 pods dentro de test-pod-1, pois MustGather em PoDTopologyLayer impede o agendamento entre Pods. O nó sob test-pod-2 permanece não agendado:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pi-2kwq9 1/1 Running 0 4s 172.30.241.123 cn-hongkong.10.1.0.12 <none> <none>
pi-87hm5 0/1 ContainerCreating 0 4s <none> cn-hongkong.10.1.0.16 <none> <none>
pi-bsvx8 1/1 Running 0 4s 172.30.240.198 cn-hongkong.10.1.0.14 <none> <none>
pi-dvwhl 0/1 ContainerCreating 0 4s <none> cn-hongkong.10.1.0.15 <none> <none>
Cenário 3: Job de 5 pods (falha de agendamento)
Atualize os mesmos parâmetros para 5. O job falha porque test-pod-1 tem apenas 4 slots disponíveis e MustGather em PoDTopologyLayer proíbe o uso do único nó em test-pod-2.
Todos os pods permanecem no estado Pending:
NAME READY STATUS RESTARTS AGE
pi-75qf5 0/1 Pending 0 2s
pi-8k4nd 0/1 Pending 0 2s
pi-b2pmc 0/1 Pending 0 2s
pi-n7c2b 0/1 Pending 0 2s
pi-wf4zn 0/1 Pending 0 2s
Inspecione a mensagem de falha de agendamento:
kubectl get pod -ojson | jq '.items[].status'
A mensagem de falha de agendamento contém:
0/6 nodes are available: 1 Insufficient nvidia.com/gpu, 1 [NetworkTopology begin] cluster total nodes:6, 5 node provide 5 freeSlot, 1 node unavailable cause Insufficient nvidia.com/gpu, job desireNum:5, all fail topology paths by MustGather reason: [path:RootNode->test-pod-1, freeSlotNum:4], [path:RootNode->DefaultTopologyName, freeSlotNum:0], [path:RootNode->test-pod-2, freeSlotNum:1] [NetworkTopology end], 4 NetworkTopology bestPlan empty. network topology job sample-network-topology/sample-network-topology gets rejected due to pod is unschedulable...
Campos principais na mensagem:
|
Campo |
Valor |
Significado |
|
|
|
O agendador precisa de 5 slots dentro de um único domínio de nível Pod |
|
|
|
|
|
|
|
|
|
|
— |
Não existe nenhum plano de topologia válido; o agendamento está bloqueado |
Para resolver isso, reduza workerNum para caber em um único Pod ou altere a estratégia de PoDTopologyLayer de MustGather para PreferGather para permitir o agendamento entre Pods.