El scheduler decide en qué nodo va cada pod. Este módulo son las herramientas para influir en esa decisión: forzar un nodo, atraer, repeler, reservar recursos y distribuir cargas. Acá el multi-node de tu cluster por fin importa.
# Poner un label a un nodo
k label node w1 disktype=ssd
# Ver labels de los nodos
k get nodes --show-labels
k get nodes -l disktype=ssd
spec:
nodeSelector:
disktype: ssd
containers:
- name: app
image: nginx
El pod SOLO irá a nodos con el label disktype=ssd. Si ninguno lo tiene, queda Pending.
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values: ["ssd", "nvme"]
requiredDuringSchedulingIgnoredDuringExecution se lee: "requerido AL schedular, ignorado si cambia DESPUÉS". O sea: decide al colocar el pod, pero si el label del nodo cambia luego, el pod ya colocado no se mueve.| nodeSelector | node Affinity |
|---|---|
| Simple: label = valor | Expresiones (In, NotIn, Exists...) |
| Solo AND exacto | OR, rangos, negación |
| Solo "requerido" | requerido O preferido |
nodeSelector (más corto, menos error). Si necesitás lógica (varios valores, preferencias, negación), usá nodeAffinity.# Formato: key=value:efecto
k taint node w1 gpu=true:NoSchedule
# Quitar el taint (mismo comando + guion al final)
k taint node w1 gpu=true:NoSchedule-
Ahora ningún pod se schedulea en w1... salvo los que toleren ese taint.
spec:
tolerations:
- key: "gpu"
operator: "Equal"
value: "true"
effect: "NoSchedule"
containers:
- name: app
image: nginx
node-role.kubernetes.io/control-plane:NoSchedule que evita que corran pods normales ahí. En el cluster single-node de práctica lo quitaste con el - para poder correr pods.| Efecto | Qué hace |
|---|---|
| NoSchedule | No schedulea pods nuevos sin toleration |
| PreferNoSchedule | Evita, pero no prohíbe |
| NoExecute | Además EXPULSA pods existentes sin toleration |
Affinity es el pod diciendo "quiero ir a tal nodo" (atracción, desde el pod).
Taint es el nodo diciendo "no quiero pods, salvo excepciones" (repulsión, desde el nodo).
Se complementan: taint reserva un nodo, toleration da el permiso de entrar, y affinity puede además dirigir el pod ahí.
spec:
containers:
- name: app
image: nginx
resources:
requests: # lo que RESERVA
cpu: "250m"
memory: "128Mi"
limits: # el TECHO que puede usar
cpu: "500m"
memory: "256Mi"
# LimitRange: defaults por pod en un namespace
# ResourceQuota: tope total del namespace
k get limitrange
k get resourcequota
m (millicores: 1000m = 1 core), memoria en Mi/Gi (binario) o M/G (decimal). El HPA del Módulo 4 usa el requests.cpu como base del %.| Request | Limit |
|---|---|
| Lo que reserva | El techo máximo |
| El scheduler lo usa para decidir dónde cabe | El kubelet lo hace cumplir en runtime |
| Garantía mínima | Corte máximo |
El scheduler suma los requests de los pods ya en un nodo y ve si el pod nuevo "entra" en lo que queda. Si ningún nodo tiene requests libres suficientes, el pod queda Pending (aunque haya CPU real ociosa: se mira el request reservado, no el uso real).
k describe node (sección Allocated resources).# "No pongas dos pods de esta app en el mismo nodo"
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: web
topologyKey: kubernetes.io/hostname
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: web
Reparte los pods de app=web lo más parejo posible entre nodos (diferencia máxima de 1).
Node affinity (5.1): "quiero ir a nodos con tal LABEL".
Pod affinity/anti-affinity: "quiero (o NO quiero) estar cerca de OTROS PODS con tal label".
Define qué es "estar cerca". kubernetes.io/hostname = mismo nodo. Otros labels de topología pueden ser zona, región (en la nube). Es la unidad de agrupación.
topologyKey: hostname es el patrón clásico de HA: garantiza que si un nodo cae, no te llevás todas las réplicas juntas.# Labels de nodos
k label node NODE key=value
k get nodes --show-labels
# Taints
k taint node NODE key=val:NoSchedule
k taint node NODE key=val:NoSchedule- # quitar
# Ver recursos de un nodo (para debug de Pending)
k describe node NODE # sección Allocated resources
# Conceptos que van en el YAML del pod:
# nodeSelector / affinity.nodeAffinity (atraer a nodos)
# tolerations (permiso ante taints)
# resources.requests / limits (reservar / limitar)
# affinity.podAntiAffinity (separar pods)
# topologySpreadConstraints (distribuir)