Belajar Kubernetes - Episode 35 - Pengenalan dan Penjelasan Affinity dan Anti-Affinity

Belajar Kubernetes - Episode 35 - Pengenalan dan Penjelasan Affinity dan Anti-Affinity

Di episode ini kita akan coba bahas Kubernetes Affinity dan Anti-Affinity untuk intelligent Pod scheduling. Kita akan mempelajari bagaimana Node Affinity, Pod Affinity, dan Pod Anti-Affinity work, dan best practice untuk workload placement.

Arman Dwi Pangestu
Arman Dwi PangestuApril 10, 2026
0 views
7 min read

Pendahuluan

Catatan

Untuk kalian yang ingin membaca episode sebelumnya, bisa click thumbnail episode 34 di bawah ini

Episode 34Episode 34

Di episode sebelumnya, kita menjelajahi Taints dan Tolerations, yang memungkinkan kita menolak Pod dari node tertentu. Sekarang kita akan mendalami Affinity dan Anti-Affinity, yang memberikan kontrol halus atas tempat Pod harus dijadwalkan berdasarkan karakteristik node dan lokasi Pod lainnya.

Catatan: Disini saya akan menggunakan Kubernetes Cluster yang di install melalui K3s.

Sementara Taints dan Tolerations bekerja pada model penolakan (menjaga Pod tetap jauh), Affinity bekerja pada model daya tarik (menarik Pod ke node tertentu atau menjauh dari Pod lain). Ini memungkinkan strategi penempatan beban kerja yang kuat seperti co-locating layanan terkait atau menyebarkan Pod di seluruh zona ketersediaan.

Memahami Affinity dan Anti-Affinity

Affinity dan Anti-Affinity adalah aturan penjadwalan yang mempengaruhi keputusan penempatan Pod. Pikirkan seperti pengaturan tempat duduk di konferensi. Taints dan Tolerations mengatakan "meja ini dicadangkan hanya untuk VIP." Affinity dan Anti-Affinity mengatakan "Saya ingin duduk dekat dengan anggota tim saya" atau "Saya ingin duduk jauh dari kerumunan yang bising."

Kubernetes menyediakan tiga jenis aturan affinity:

  1. Node Affinity - Jadwalkan Pod pada node tertentu berdasarkan label node
  2. Pod Affinity - Jadwalkan Pod dekat dengan Pod lain berdasarkan label Pod
  3. Pod Anti-Affinity - Jadwalkan Pod jauh dari Pod lain berdasarkan label Pod

Node Affinity

Node Affinity memungkinkan Anda membatasi node mana yang dapat dijadwalkan Pod Anda, berdasarkan label node. Ini lebih fleksibel daripada nodeSelector karena mendukung beberapa ekspresi pencocokan dan preferensi lunak.

Jenis Node Affinity

requiredDuringSchedulingIgnoredDuringExecution (Persyaratan Keras)

Ini adalah batasan keras. Pod hanya akan dijadwalkan jika node cocok dengan aturan affinity. Jika tidak ada node yang cocok, Pod tetap tidak terjadwal.

KubernetesNode Affinity - Persyaratan Keras
apiVersion: v1
kind: Pod
metadata:
  name: nginx-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: node-type
            operator: In
            values:
            - compute
            - gpu
  containers:
  - name: nginx
    image: nginx:latest

Dalam contoh ini, Pod hanya akan dijadwalkan pada node dengan label node-type=compute atau node-type=gpu.

preferredDuringSchedulingIgnoredDuringExecution (Preferensi Lunak)

Ini adalah preferensi lunak. Penjadwal akan mencoba menempatkan Pod pada node yang cocok, tetapi jika tidak ada node yang cocok, Pod akan dijadwalkan pada node yang tersedia. Anda juga dapat menetapkan bobot untuk lebih memilih node tertentu daripada yang lain.

KubernetesNode Affinity - Preferensi Lunak
apiVersion: v1
kind: Pod
metadata:
  name: nginx-preferred
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        preference:
          matchExpressions:
          - key: disk-type
            operator: In
            values:
            - ssd
      - weight: 50
        preference:
          matchExpressions:
          - key: zone
            operator: In
            values:
            - us-east-1a
  containers:
  - name: nginx
    image: nginx:latest

Penjadwal akan lebih memilih node dengan disk SSD (bobot 100) daripada node di us-east-1a (bobot 50). Bobot yang lebih tinggi memiliki prioritas lebih tinggi.

Operator Node Affinity

Node Affinity mendukung beberapa operator untuk pencocokan:

  • In - Nilai label ada dalam daftar yang disediakan
  • NotIn - Nilai label tidak ada dalam daftar yang disediakan
  • Exists - Kunci label ada (terlepas dari nilainya)
  • DoesNotExist - Kunci label tidak ada
  • Gt - Nilai label lebih besar dari nilai yang disediakan (perbandingan string)
  • Lt - Nilai label kurang dari nilai yang disediakan (perbandingan string)
KubernetesNode Affinity - Berbagai Operator
apiVersion: v1
kind: Pod
metadata:
  name: nginx-operators
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: node-type
            operator: In
            values:
            - compute
          - key: gpu
            operator: Exists
          - key: cpu-cores
            operator: Gt
            values:
            - "4"
  containers:
  - name: nginx
    image: nginx:latest

Pod ini memerlukan node dengan node-type=compute, label gpu (nilai apa pun), dan inti CPU lebih besar dari 4.

Pod Affinity

Pod Affinity memungkinkan Anda menjadwalkan Pod dekat dengan Pod lain. Ini berguna untuk co-locating beban kerja terkait untuk mengurangi latensi atau meningkatkan kinerja.

Jenis Pod Affinity

requiredDuringSchedulingIgnoredDuringExecution (Persyaratan Keras)

Pod hanya akan dijadwalkan pada node yang memiliki Pod lain yang cocok dengan aturan affinity.

KubernetesPod Affinity - Persyaratan Keras
apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - database
        topologyKey: kubernetes.io/hostname
  containers:
  - name: app
    image: myapp:latest

Pod ini hanya akan dijadwalkan pada node yang sudah memiliki Pod dengan label app=database. topologyKey mendefinisikan cakupan - kubernetes.io/hostname berarti node yang sama, sementara topology.kubernetes.io/zone berarti zona ketersediaan yang sama.

preferredDuringSchedulingIgnoredDuringExecution (Preferensi Lunak)

Penjadwal akan mencoba menempatkan Pod dekat dengan Pod yang cocok, tetapi akan menjadwalkannya di tempat lain jika diperlukan.

KubernetesPod Affinity - Preferensi Lunak
apiVersion: v1
kind: Pod
metadata:
  name: cache-pod
spec:
  affinity:
    podAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - web
          topologyKey: kubernetes.io/hostname
  containers:
  - name: cache
    image: redis:latest

Pod ini lebih suka dijadwalkan pada node yang sama dengan Pod app=web, tetapi dapat dijadwalkan di tempat lain jika diperlukan.

Topology Key

topologyKey sangat penting untuk Pod affinity. Ini mendefinisikan cakupan aturan affinity:

  • kubernetes.io/hostname - Node yang sama
  • topology.kubernetes.io/zone - Zona ketersediaan yang sama
  • topology.kubernetes.io/region - Region yang sama
  • Label kustom - Label topologi kustom apa pun

Pod Anti-Affinity

Pod Anti-Affinity memastikan Pod tersebar di seluruh node atau zona. Ini penting untuk ketersediaan tinggi dan toleransi kesalahan.

Anti-Affinity Keras

KubernetesPod Anti-Affinity - Persyaratan Keras
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: web
            topologyKey: kubernetes.io/hostname
      containers:
      - name: web
        image: nginx:latest

Deployment ini memastikan bahwa tidak ada dua Pod dengan app=web yang dijadwalkan pada node yang sama. Jika Anda memiliki 3 replika dan hanya 2 node, satu Pod akan tetap tidak terjadwal.

Anti-Affinity Lunak

KubernetesPod Anti-Affinity - Preferensi Lunak
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app-soft
spec:
  replicas: 5
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchLabels:
                  app: web
              topologyKey: kubernetes.io/hostname
      containers:
      - name: web
        image: nginx:latest

Deployment ini lebih suka menyebarkan Pod di seluruh node, tetapi akan co-locate mereka jika diperlukan. Dengan 5 replika dan 3 node, beberapa node akan memiliki beberapa Pod.

Menggabungkan Aturan Affinity

Anda dapat menggabungkan beberapa aturan affinity dalam spesifikasi Pod tunggal. Semua aturan harus dipenuhi agar Pod dapat dijadwalkan.

KubernetesAturan Affinity Gabungan
apiVersion: v1
kind: Pod
metadata:
  name: complex-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: node-type
            operator: In
            values:
            - compute
    podAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchLabels:
              app: database
          topologyKey: kubernetes.io/hostname
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchLabels:
            app: cache
        topologyKey: kubernetes.io/hostname
  containers:
  - name: app
    image: myapp:latest

Pod ini akan:

  1. Hanya dijadwalkan pada node dengan node-type=compute (diperlukan)
  2. Lebih suka berada pada node yang sama dengan Pod app=database (lunak)
  3. Tidak pernah berada pada node yang sama dengan Pod app=cache (diperlukan)

Contoh Praktis

Aplikasi Web Ketersediaan Tinggi

KubernetesAplikasi Web HA dengan Anti-Affinity
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-ha
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: web
            topologyKey: topology.kubernetes.io/zone
      containers:
      - name: web
        image: nginx:latest
        resources:
          requests:
            cpu: 100m
            memory: 128Mi

Ini memastikan setiap replika berada di zona ketersediaan yang berbeda untuk toleransi kesalahan maksimal.

Database dengan Cache Lokal

KubernetesDatabase dengan Cache Co-located
apiVersion: v1
kind: Pod
metadata:
  name: db-with-cache
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchLabels:
            app: database
        topologyKey: kubernetes.io/hostname
  containers:
  - name: cache
    image: redis:latest
    resources:
      requests:
        cpu: 50m
        memory: 256Mi

Pod cache ini akan selalu berjalan pada node yang sama dengan Pod database untuk akses latensi rendah.

Beban Kerja GPU dengan Node Affinity

KubernetesPenjadwalan Beban Kerja GPU
apiVersion: v1
kind: Pod
metadata:
  name: ml-training
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: accelerator
            operator: In
            values:
            - nvidia-gpu
          - key: gpu-memory
            operator: Gt
            values:
            - "8Gi"
  containers:
  - name: training
    image: ml-training:latest
    resources:
      requests:
        nvidia.com/gpu: 1

Pod ini hanya akan dijadwalkan pada node dengan GPU NVIDIA dan setidaknya 8GB memori GPU.

Kesalahan dan Jebakan Umum

Kesalahan 1: Menggunakan Affinity Keras Ketika Lunak Lebih Baik

Problem: Aturan affinity keras dapat menyebabkan Pod tetap tidak terjadwal jika tidak ada node yang cocok.

KubernetesKesalahan: Terlalu Ketat
# JANGAN LAKUKAN INI - Pod mungkin tidak pernah dijadwalkan
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: ultra-rare-label
          operator: In
          values:
          - value

Solusi: Gunakan preferensi lunak untuk fleksibilitas.

Kesalahan 2: Lupa Memberi Label Node

Problem: Aturan affinity bergantung pada label node. Jika node tidak diberi label, aturan affinity tidak akan berfungsi.

KubernetesBeri Label Node Anda
# Beri label node untuk aturan affinity
kubectl label nodes node-1 node-type=compute
kubectl label nodes node-2 node-type=storage

Kesalahan 3: Topology Key yang Salah

Problem: Menggunakan topology key yang salah dapat menyebabkan perilaku penjadwalan yang tidak terduga.

KubernetesKesalahan: Topology Key Salah
# JANGAN LAKUKAN INI - topology key tidak ada
affinity:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app: web
      topologyKey: non-existent-label

Kesalahan 4: Mencampur Affinity dengan Taints/Tolerations Secara Tidak Benar

Problem: Affinity dan Taints/Tolerations bekerja bersama tetapi melayani tujuan yang berbeda.

KubernetesBenar: Menggabungkan Affinity dan Taints
# Node memiliki taint: gpu=true:NoSchedule
# Pod memiliki toleration dan affinity
apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  tolerations:
  - key: gpu
    operator: Equal
    value: "true"
    effect: NoSchedule
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: accelerator
            operator: In
            values:
            - nvidia-gpu
  containers:
  - name: app
    image: myapp:latest

Kesalahan 5: Over-constraining dengan Beberapa Aturan Affinity

Problem: Terlalu banyak aturan affinity dapat membuat Pod tidak dapat dijadwalkan.

Solusi: Seimbangkan batasan dengan fleksibilitas.

Praktik Terbaik

Gunakan Preferensi Lunak untuk Fleksibilitas

Lebih suka preferredDuringSchedulingIgnoredDuringExecution daripada persyaratan keras kecuali benar-benar diperlukan. Ini memastikan Pod masih dapat dijadwalkan bahkan jika preferensi tidak dapat dipenuhi.

Gabungkan dengan Pod Disruption Budgets

Gunakan PodDisruptionBudgets dengan anti-affinity untuk memastikan ketersediaan tinggi selama pemeliharaan.

KubernetesPDB dengan Anti-Affinity
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: web

Gunakan Anti-Affinity Berbasis Zona untuk HA

Untuk beban kerja produksi, gunakan topology.kubernetes.io/zone sebagai topology key untuk menyebarkan Pod di seluruh zona ketersediaan.

KubernetesAnti-Affinity Berbasis Zona
affinity:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app: web
      topologyKey: topology.kubernetes.io/zone

Beri Label Node Secara Konsisten

Tetapkan konvensi pelabelan untuk cluster Anda. Label umum meliputi:

  • node-type (compute, storage, gpu)
  • zone (us-east-1a, us-east-1b)
  • disk-type (ssd, hdd)
  • workload-type (general, ml, database)

Pantau Pelanggaran Affinity

Periksa apakah Pod dijadwalkan sesuai dengan aturan affinity. Gunakan kubectl describe pod untuk melihat informasi affinity dan keputusan penjadwalan.

KubernetesPeriksa Status Affinity
kubectl describe pod <pod-name>
# Cari bagian "Events" untuk melihat keputusan penjadwalan

Uji Aturan Affinity

Sebelum menerapkan ke produksi, uji aturan affinity di lingkungan staging untuk memastikan mereka bekerja seperti yang diharapkan.

KubernetesUji Aturan Affinity
# Buat Pod uji dengan aturan affinity
kubectl apply -f test-affinity.yaml
 
# Periksa apakah Pod dijadwalkan
kubectl get pods -o wide
 
# Jelaskan Pod untuk melihat detail affinity
kubectl describe pod <pod-name>

Affinity vs Taints/Tolerations

Sementara keduanya mengontrol penempatan Pod, mereka bekerja berbeda:

AspekAffinityTaints/Tolerations
ModelDaya tarik (tarik)Penolakan (dorong)
CakupanBerpusat pada PodBerpusat pada Node
Kasus PenggunaanCo-locate beban kerjaCadangkan node
FleksibilitasLebih fleksibelLebih ketat
KinerjaPreferensi lunak tersediaHanya batasan keras

Gunakan Taints/Tolerations untuk reservasi node dan Affinity untuk penempatan beban kerja yang cerdas.

Kesimpulan

Pada episode 35 ini, kita telah membahas Affinity dan Anti-Affinity di Kubernetes secara mendalam. Kita sudah belajar bagaimana Node Affinity memungkinkan Anda menargetkan node tertentu, Pod Affinity co-locate beban kerja terkait, dan Pod Anti-Affinity menyebarkan Pod untuk ketersediaan tinggi.

Key takeaway:

  • Node Affinity - Target node tertentu berdasarkan label
  • Pod Affinity - Co-locate Pod dekat satu sama lain
  • Pod Anti-Affinity - Sebarkan Pod di seluruh node atau zona
  • Persyaratan keras - Pod tidak akan dijadwalkan jika tidak terpenuhi
  • Preferensi lunak - Pod dijadwalkan di tempat lain jika diperlukan
  • Topology key - Tentukan cakupan (node, zona, region)
  • Operator - In, NotIn, Exists, DoesNotExist, Gt, Lt
  • Gabungkan dengan Taints/Tolerations - Untuk penempatan yang tepat
  • Beri label node secara konsisten - Penting untuk aturan affinity
  • Uji secara menyeluruh - Sebelum penerapan produksi
  • Pantau penjadwalan - Verifikasi aturan affinity bekerja seperti yang diharapkan

Dengan menggabungkan ini dengan pelabelan node yang tepat dan topology key, Anda dapat membangun cluster Kubernetes yang tangguh dan berkinerja tinggi.

Catatan

Untuk kalian yang ingin melanjutkan ke episode selanjutnya, bisa click thumbnail episode 36 di bawah ini

Episode 36Episode 36

Related Posts