Em implantações distribuídas, a falha na criação de um pod em uma zona pode concentrar réplicas excessivas nas zonas restantes, o que viola os requisitos de distribuição e aumenta a latência entre zonas. Em um cluster ACK Serverless Pro, utilize o agendamento nativo do Kubernetes para distribuir pods baseados em Elastic Container Instance (ECI) uniformemente entre as zonas ou fixá-los em uma zona específica para acesso de baixa latência.
Contexto
O Kubernetes oferece três primitivas de agendamento para posicionamento de pods no nível de zona:
|
Primitiva |
Comportamento |
Quando usar |
|
|
Distribui pods uniformemente entre zonas com base em um desvio máximo |
Necessidade de distribuição equilibrada em várias zonas |
|
|
Atrai pods para zonas onde já existem pods correspondentes em execução |
Necessidade de colocalizar pods na mesma zona |
|
|
Fixa pods em zonas específicas com base em rótulos de nó |
Necessidade de direcionar uma zona nomeada (por exemplo, |
Esses recursos aplicam-se a pods baseados em ECI apenas quando nodeAffinity, podAffinity ou topologySpreadConstraints estiver configurado para os pods, ou quando estes corresponderem a uma política de recursos existente.
Para consultar a documentação do Kubernetes sobre essas APIs, acesse Restrições de distribuição de topologia de pod, Atribuição de pods a nós, Afinidade de nó, Afinidade de pod e maxSkew.
Pré-requisitos
Antes de começar, verifique se:
-
Existe um cluster ACK Serverless Pro que atende aos seguintes requisitos:
Versão 1,22 ou posterior do Kubernetes
Versão 2.10.0 ou posterior do componente ACK Virtual Node
Versão 5,9 ou posterior do componente kube-scheduler, com o recurso de agendamento de pods baseado em nó virtual ativado (consulte Ativar a política de agendamento de pods baseada em nó virtual para um cluster ACK)
Várias zonas (vSwitches) estão configuradas no eci-profile para permitir o agendamento de pods em múltiplas zonas (consulte Configurar um eci-profile)
O parâmetro
nodeAffinity,podAffinityoutopologySpreadConstraintsestá configurado para os pods que você deseja agendar, ou os pods correspondem a uma política de recursos existente
Para agendar pods em nós virtuais baseados em ARM, adicione tolerâncias às contaminações do nó virtual no campo tolerations da especificação do pod.
Observações de uso
Defina
topologyKeycomotopology.kubernetes.io/zone.-
As anotações a seguir desativam os recursos de distribuição de zona e afinidade:
Anotação
Efeito
k8s.aliyun.com/eci-schedule-strategy: "VSwitchOrdered"Ativa uma estratégia de agendamento multizona que segue uma ordem especificada de vSwitch
k8s.aliyun.com/eci-fail-strategy: "fail-fast"Define a política de tratamento de falhas do pod como
fail-fast
Distribuir pods baseados em ECI entre zonas e configurar afinidades
Os exemplos a seguir utilizam um cluster ACK Serverless Pro executando o Kubernetes 1,22.
Exemplo 1: Distribuir pods uniformemente entre zonas usando restrições de distribuição de topologia
O campo topologySpreadConstraints controla a diferença máxima na contagem de pods entre zonas (maxSkew). Com maxSkew: 1 em três zonas, nenhuma zona pode ter mais de um pod extra em comparação com qualquer outra.
Esse campo aceita os seguintes parâmetros:
topologySpreadConstraints:
- maxSkew: <integer>
minDomains: <integer> # Optional. Beta in Kubernetes 1.25 and later.
topologyKey: <string>
whenUnsatisfiable: <string>
labelSelector: <object>
matchLabelKeys: <list> # Optional. Beta in Kubernetes 1.27 and later.
nodeAffinityPolicy: [Honor|Ignore] # Optional. Beta in Kubernetes 1.26 and later.
nodeTaintsPolicy: [Honor|Ignore] # Optional. Beta in Kubernetes 1.26 and later.
Para obter detalhes sobre os parâmetros, consulte Campo topologySpreadConstraints.
O Deployment a seguir distribui 10 réplicas uniformemente entre as zonas disponíveis. A configuração whenUnsatisfiable: DoNotSchedule impede o agendamento de um pod caso sua alocação viole a restrição maxSkew: 1.
apiVersion: apps/v1
kind: Deployment
metadata:
name: with-pod-topology-spread
labels:
app: with-pod-topology-spread
spec:
replicas: 10
selector:
matchLabels:
app: with-pod-topology-spread
template:
metadata:
labels:
app: with-pod-topology-spread
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: with-pod-topology-spread
containers:
- name: with-pod-topology-spread
image: registry.k8s.io/pause:2.0
resources:
requests:
cpu: "1"
memory: "256Mi"
Implantar e verificar
-
Salve o YAML em
deployment.yamle aplique-o:kubectl apply -f deployment.yaml -
Consulte os nós nos quais os pods estão em execução:
kubectl get po -lapp=with-pod-topology-spread -ocustom-columns=NAME:.metadata.name,NODE:.spec.nodeName --no-headers | grep -v "<none>" -
Conte os pods por zona para confirmar a distribuição uniforme:
kubectl get po -lapp=with-pod-topology-spread -ocustom-columns=NODE:.spec.nodeName --no-headers | grep -v "<none>" | xargs -I {} kubectl get no {} -ojson | jq '.metadata.labels["topology.kubernetes.io/zone"]' | sort | uniq -c
Exemplo 2: Fixar pods em uma zona específica usando afinidades
Utilize podAffinity para colocalizar pods na mesma zona de outros pods correspondentes existentes ou use nodeAffinity para fixar pods em uma zona com base no rótulo do nó.
Opção A: Colocalizar pods em uma zona usando afinidade de pod
O Deployment abaixo usa podAffinity para agendar todas as réplicas na mesma zona dos pods existentes que possuem o rótulo app: with-affinity.
apiVersion: apps/v1
kind: Deployment
metadata:
name: with-affinity
labels:
app: with-affinity
spec:
replicas: 3
selector:
matchLabels:
app: with-affinity
template:
metadata:
labels:
app: with-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- with-affinity
topologyKey: topology.kubernetes.io/zone
containers:
- name: with-affinity
image: registry.k8s.io/pause:2.0
Opção B: Fixar pods em uma zona específica usando afinidade de nó
Para implantar pods exclusivamente em uma zona específica, substitua podAffinity por nodeAffinity. A configuração a seguir fixa os pods na Zona A de Pequim (cn-beijing-a).
apiVersion: apps/v1
kind: Deployment
metadata:
name: with-affinity
labels:
app: with-affinity
spec:
replicas: 3
selector:
matchLabels:
app: with-affinity
template:
metadata:
labels:
app: with-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- cn-beijing-a
containers:
- name: with-affinity
image: registry.k8s.io/pause:2.0
Implantar e verificar
-
Salve o YAML em
deployment.yamle aplique-o:kubectl apply -f deployment.yaml -
Consulte os nós nos quais os pods estão em execução:
kubectl get po -lapp=with-affinity -ocustom-columns=NAME:.metadata.name,NODE:.spec.nodeName --no-headers | grep -v "<none>" -
Confirme se todos os pods foram alocados na zona esperada:
kubectl get po -lapp=with-affinity -ocustom-columns=NODE:.spec.nodeName --no-headers | grep -v "<none>" | xargs -I {} kubectl get no {} -ojson | jq '.metadata.labels["topology.kubernetes.io/zone"]' | sort | uniq -c
Distribuição estrita de topologia de pods ECI
Por padrão, o kube-scheduler tenta distribuir os pods uniformemente entre as zonas, mas a criação de pods baseados em ECI pode falhar em algumas delas. Quando isso ocorre, a contagem de pods na zona com falha permanece em zero, o que pode violar a restrição maxSkew. O diagrama a seguir ilustra o resultado do agendamento com maxSkew: 1. Para mais informações sobre maxSkew, consulte maxSkew.
Se a criação de pods falhar na Zona B e na Zona C, dois pods executarão na Zona A e nenhum nas outras zonas, violando a restrição maxSkew: 1.
O ACK Serverless Pro oferece suporte à distribuição estrita de topologia de pods ECI para evitar esse cenário. Quando ativado, o kube-scheduler agenda primeiro um pod para cada zona e mantém os pods pendentes até que os pods agendados sejam criados com sucesso, conforme mostrado abaixo.
Mesmo após a criação do Pod A1, os pods pendentes permanecem retidos. Se o Pod B1 ou o Pod C1 falhar, agendar mais pods para a Zona A violaria o maxSkew. Somente após a criação do Pod B1 o kube-scheduler prossegue com o agendamento de um pod para a Zona C. Os pods sombreados em verde foram criados com sucesso.
Para desativar a distribuição estrita de topologia, defina whenUnsatisfiable como ScheduleAnyway. Para mais detalhes, consulte Definição de restrição de distribuição.Definição de Restrição de Distribuição