Affinity: Gleich und Gleich gesellt sich gern

Node Affinity ist Ihre Möglichkeit zu sagen: "Hey Kubernetes, ich habe bestimmte Vorlieben, wo diese Pods leben sollen." Es ist wie ein Dating-Profil für Ihre Pods, aber anstatt "lange Spaziergänge am Strand" geben Sie die Eigenschaften der Nodes an. Es gibt zwei Arten von Node Affinity:

  • requiredDuringSchedulingIgnoredDuringExecution: Die Regel "Du musst so groß sein, um mitzufahren". Pods werden nur auf Nodes platziert, die diese Kriterien erfüllen.
  • preferredDuringSchedulingIgnoredDuringExecution: Die "wäre schön, wenn"-Option. Kubernetes versucht sein Bestes, aber es ist nicht schlimm, wenn es nicht klappt.

Hier ist ein kurzes Beispiel für Node Affinity in Aktion:


apiVersion: v1
kind: Pod
metadata:
  name: gpu-cruncher
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: gpu
            operator: In
            values:
            - "true"
  containers:
  - name: gpu-container
    image: gpu-app:latest

Dieser Pod sagt: "Ich weigere mich absolut, auf einem Node ohne GPU zu laufen. Keine Ausnahmen!"

Pod Affinity und Anti-Affinity: Das soziale Netzwerk der Pods

Während Node Affinity sich auf Pod-zu-Node-Beziehungen bezieht, geht es bei Pod Affinity und Anti-Affinity um Pod-zu-Pod-Dynamiken. Es ist wie die Sitzordnung bei einer Hochzeit, bei der einige Gäste sich lieben und andere... nicht so sehr.

Pod Affinity

Verwenden Sie dies, wenn Sie möchten, dass Pods beste Freunde sind und auf demselben Node oder in derselben Zone bleiben. Ideal für Apps, die viel kommunizieren müssen und Fernbeziehungen hassen.

Pod Anti-Affinity

Dies ist für Pods, die etwas persönlichen Raum benötigen. Verwenden Sie es, um Ihre Replikate über verschiedene Nodes oder Zonen zu verteilen, um hohe Verfügbarkeit zu gewährleisten. Es ist das Kubernetes-Äquivalent von "Ich liebe dich, aber ich brauche auch meinen Freiraum." Hier ist ein Beispiel, das beides zeigt:


apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: web
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - cache
            topologyKey: "kubernetes.io/hostname"
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - web
              topologyKey: "kubernetes.io/hostname"

Dieses Deployment sagt: "Ich möchte auf demselben Node wie mein Cache-Kumpel sein, aber bitte versuchen Sie, meine Replikate auf verschiedenen Nodes zu halten, wenn möglich."

Taints und Tolerations: Die Türsteher des Kubernetes-Clubs

Taints und Tolerations sind wie der VIP-Bereich Ihres Clusters. Taints werden auf Nodes angewendet und setzen im Grunde ein "Keine Pods erlaubt"-Schild auf. Tolerations sind die VIP-Pässe, die bestimmten Pods erlauben, diese Schilder zu ignorieren. Um einen Node zu tainten:


kubectl taint nodes node1 key=value:NoSchedule

Das ist, als würde man dem Node sagen: "Du bist besonders. Lass nicht jeden Pod auf dir laufen." Um einem Pod eine Toleration hinzuzufügen:


apiVersion: v1
kind: Pod
metadata:
  name: vip-pod
spec:
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"
  containers:
  - name: vip-container
    image: vip-app:latest

Dieser Pod zeigt seinen VIP-Pass und sagt: "Ich darf in den speziellen Bereich!"

Alles zusammenfügen: Die große Orchestrierung

Nun kombinieren wir diese Techniken für ein echtes Scheduling-Wunder. Stellen Sie sich vor, Sie betreiben ein hochriskantes Pokerspiel (ich meine, ein kritisches Datenbank-Cluster) über mehrere Zonen:


apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: poker-db
spec:
  replicas: 3
  selector:
    matchLabels:
      app: poker-db
  template:
    metadata:
      labels:
        app: poker-db
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: failure-domain.beta.kubernetes.io/zone
                operator: In
                values:
                - us-central1-a
                - us-central1-b
                - us-central1-c
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - poker-db
            topologyKey: "kubernetes.io/hostname"
      tolerations:
      - key: "dedicated"
        operator: "Equal"
        value: "database"
        effect: "NoSchedule"
      containers:
      - name: db
        image: poker-db:latest

Dieses StatefulSet macht mehrere Dinge:

1. Sicherstellen, dass jede Replik in einer von drei spezifischen Zonen ist (Node Affinity).

2. Sicherstellen, dass keine zwei Replikate auf demselben Node enden (Pod Anti-Affinity).

3. Erlauben der Platzierung nur auf Nodes, die für Datenbanken reserviert sind (Toleration). Es ist wie das Einrichten eines hochsicheren, verteilten Tresors für Ihre Pokerchips!

Debugging: Wenn Ihre Pods verschwinden

Manchmal landen Pods trotz Ihrer besten Bemühungen im Scheduling-Limbo. Hier sind einige schnelle Tipps, wenn etwas schiefgeht:

1. Überprüfen Sie den Pod-Status: kubectl get pod <pod-name> -o wide

2. Gehen Sie ins Detail: kubectl describe pod <pod-name>

3. Suchen Sie nach Ereignissen im Zusammenhang mit dem Scheduling: kubectl get events --sort-by=.metadata.creationTimestamp

4. Wenn alles andere fehlschlägt, überprüfen Sie die Scheduler-Logs: kubectl logs kube-scheduler-<node-name> -n kube-system

Denken Sie daran, mit großer Macht kommt große Verantwortung (und gelegentlich große Verwirrung).

Best Practices: Die Do's und Don'ts des fortgeschrittenen Schedulings

  • Do verwenden Sie Labels konsistent und sinnvoll. Sie sind das Rückgrat Ihrer Scheduling-Strategie.
  • Don't überkomplizieren Sie Ihre Regeln. Kubernetes sollte keinen Doktortitel benötigen, um Ihre Scheduling-Präferenzen zu verstehen.
  • Do testen Sie Ihre Konfigurationen zuerst in einer Nicht-Produktionsumgebung. Was in der Theorie funktioniert, funktioniert nicht immer in der Praxis.
  • Don't vergessen Sie nicht, Ihre Scheduling-Entscheidungen zu dokumentieren. Ihr zukünftiges Ich (oder Ihre Kollegen) wird es Ihnen danken.
  • Do überprüfen und aktualisieren Sie regelmäßig Ihre Scheduling-Konfigurationen, während sich Ihr Cluster und Ihre Workloads weiterentwickeln.

Fazit: Die Kunst der Pod-Platzierung meistern

Fortgeschrittenes Scheduling in Kubernetes ist wie das Dirigieren eines Orchesters. Jede Technik - Affinity, Anti-Affinity, Taints und Tolerations - ist ein Instrument. Geschickt eingesetzt, schaffen sie einen harmonischen und effizienten Cluster. Schlecht eingesetzt, und Sie haben Chaos (und wahrscheinlich einige sehr verwirrte Pods). Denken Sie daran, das Ziel ist es, Ihre Workload-Verteilung zu optimieren, die Zuverlässigkeit zu verbessern und Ihren Cluster zum Singen zu bringen. Also gehen Sie voran, experimentieren Sie, und mögen Ihre Pods immer genau dort landen, wo Sie sie haben wollen!

"In der Welt von Kubernetes ist ein gut geplanter Pod ein glücklicher Pod." - Altes DevOps-Sprichwort (das ich gerade erfunden habe)

Viel Spaß beim Scheduling, und möge der Pod mit Ihnen sein!