K8s em Exemplos: Afinidade de Pod

Pod affinity agenda Pods em nodes onde Pods específicos já estão rodando. Use para: co-localizar serviços relacionados, reduzir latência de rede, localidade de dados.

pod-affinity.yaml

Pod affinity é definida em spec.affinity.podAffinity. labelSelector corresponde Pods alvo. topologyKey define o escopo (mesmo node, zone, etc.).

spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app: cache
          topologyKey: kubernetes.io/hostname
pod-affinity-types.yaml

Primeiro exemplo: required é uma restrição rígida - Pod não agenda se não satisfeita. Segundo exemplo: preferred é flexível - scheduler tenta mas não garante. Weight determina força da preferência (maior = mais forte).

spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app: cache
          topologyKey: kubernetes.io/hostname
---
spec:
  affinity:
    podAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchLabels:
                app: cache
            topologyKey: kubernetes.io/hostname
topology-keys.yaml

topologyKey define o escopo. kubernetes.io/hostname = mesmo node, topology.kubernetes.io/zone = mesma AZ, topology.kubernetes.io/region = mesma região. Keys customizadas para agendamento rack-aware.

topologyKey: kubernetes.io/hostname

topologyKey: topology.kubernetes.io/zone

topologyKey: topology.kubernetes.io/region

topologyKey: rack.example.com/rack-id
pod-affinity-expressions.yaml

Use matchExpressions para correspondência complexa de labels. Suporta operadores: In, NotIn, Exists, DoesNotExist. Múltiplas expressions usam lógica AND.

podAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchExpressions:
          - key: app
            operator: In
            values:
              - cache
              - queue
          - key: environment
            operator: In
            values:
              - production
      topologyKey: kubernetes.io/hostname
pod-affinity-namespace.yaml

namespaceSelector corresponde Pods entre namespaces. Por padrão, affinity só considera Pods no mesmo namespace. Use para dependências cross-namespace.

podAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app: cache
      namespaceSelector:
        matchLabels:
          team: platform
      topologyKey: kubernetes.io/hostname
---
    - labelSelector:
        matchLabels:
          app: cache
      namespaces:
        - shared-services
      topologyKey: kubernetes.io/hostname
pod-combined-affinity.yaml

Combine affinity com anti-affinity para posicionamento complexo. Co-localize com dependências mas espalhe entre nodes. Padrão comum para aplicações stateful com seus caches.

spec:
  affinity:
    podAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchLabels:
                app: redis
            topologyKey: kubernetes.io/hostname
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchLabels:
                app: my-app
            topologyKey: kubernetes.io/hostname
terminal

Debug problemas de pod affinity verificando eventos do scheduler. Pods Pending mostram por que nenhum node foi selecionado. Verifique se Pods alvo existem e têm labels correspondentes.

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

$ kubectl get pods -l app=cache --show-labels
NAME      READY   STATUS    LABELS
cache-1   1/1     Running   app=cache,env=prod

$ kubectl get pods -l app=cache -o wide
NAME      READY   NODE
cache-1   1/1     node-1

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

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