K8s em Exemplos: Anti-Afinidade de Pod

Pod anti-affinity espalha Pods entre nodes ou zones. Previne pontos únicos de falha. Use para: alta disponibilidade, espalhar réplicas, isolar workloads.

pod-anti-affinity.yaml

Pod anti-affinity é definida em spec.affinity.podAntiAffinity. Ela agenda Pods longe de Pods correspondentes. Mesma sintaxe que pod affinity mas efeito oposto.

spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app: my-app
          topologyKey: kubernetes.io/hostname
deployment-anti-affinity.yaml

Self anti-affinity espalha réplicas do mesmo Deployment. Use as próprias labels do Deployment. Com 3 réplicas, você precisa de pelo menos 3 nodes para anti-affinity required.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchLabels:
                  app: web-app
              topologyKey: kubernetes.io/hostname
pod-anti-affinity-preferred.yaml

Required anti-affinity pode tornar Pods não-agendáveis se não houver nodes suficientes. Use preferred para flexibilidade. Com 3 réplicas mas 2 nodes, required deixa 1 Pod Pending, preferred coloca 2 em um node.

spec:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchLabels:
                app: my-app
            topologyKey: kubernetes.io/hostname
pod-anti-affinity-zones.yaml

Espalhe entre nodes e zones usando múltiplas regras. Maior weight = preferência mais forte. Spreading por zone garante que falha de AZ não derrube todas as réplicas.

affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchLabels:
              app: my-app
          topologyKey: kubernetes.io/hostname
      - weight: 50
        podAffinityTerm:
          labelSelector:
            matchLabels:
              app: my-app
          topologyKey: topology.kubernetes.io/zone
pod-anti-affinity-isolation.yaml

Use matchExpressions para evitar tipos específicos de workload. Isole vizinhos barulhentos, separe workloads incompatíveis, ou mantenha dados sensíveis em nodes dedicados.

podAntiAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchExpressions:
          - key: workload-type
            operator: In
            values:
              - batch
              - ml-training
      topologyKey: kubernetes.io/hostname
    - labelSelector:
        matchLabels:
          team: competitor-team
      topologyKey: kubernetes.io/hostname
pod-anti-affinity-namespace.yaml

Anti-affinity cross-namespace usando namespaceSelector. Isole Pods de times ou ambientes diferentes. Previne problemas de vizinhos barulhentos entre fronteiras de namespace.

podAntiAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app: database
      namespaceSelector:
        matchLabels:
          environment: production
      topologyKey: kubernetes.io/hostname
---
    - labelSelector:
        matchLabels:
          app: resource-hog
      namespaces:
        - ml-workloads
        - batch-processing
      topologyKey: kubernetes.io/hostname
pod-anti-affinity-narrow.yaml

Anti-affinity tem impacto de performance em clusters grandes. Scheduler deve verificar todos os Pods correspondendo ao selector. Use nodeSelector ou node affinity quando possível. Selector estreito melhora performance.

podAntiAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app: my-app
          version: v2
      topologyKey: kubernetes.io/hostname
terminal

Debug problemas de anti-affinity verificando capacidade do node, distribuição de Pods e eventos do scheduler. Problema comum: não há nodes suficientes para anti-affinity required.

$ kubectl get pods -l app=my-app -o wide
NAME         READY   STATUS    NODE
my-app-1     1/1     Running   node-1
my-app-2     1/1     Running   node-2
my-app-3     0/1     Pending   <none>

$ kubectl describe pod my-app-3
Events:
  Type     Reason            Message
  Warning  FailedScheduling  0/2 nodes available:
    2 node(s) didn't match pod anti-affinity rules

$ kubectl get nodes
NAME     STATUS   ROLES    AGE
node-1   Ready    <none>   10d
node-2   Ready    <none>   10d

$ kubectl get pod my-app-1 -o jsonpath='{.spec.affinity}' | jq

Índice | GitHub | Use as setas do teclado para navegar |