

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Sebarkan beban kerja di seluruh node dan Availability Zone
<a name="spread-workloads"></a>

Mendistribusikan beban kerja di seluruh [domain kegagalan](https://cluster-api-aws.sigs.k8s.io/topics/failure-domains/) seperti Availability Zones dan node meningkatkan ketersediaan komponen dan mengurangi kemungkinan kegagalan untuk aplikasi yang dapat diskalakan secara horizontal. Bagian berikut memperkenalkan cara untuk menyebarkan beban kerja di seluruh node dan Availability Zones.

## Gunakan kendala penyebaran topologi pod
<a name="spread-constraints"></a>

[Kendala penyebaran topologi pod Kubernetes menginstruksikan](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/) penjadwal Kubernetes untuk mendistribusikan pod yang dikelola oleh `ReplicaSet` atau `StatefulSet` di seluruh domain kegagalan yang berbeda (Availability Zone, node, dan tipe hardware). Saat Anda menggunakan kendala penyebaran topologi pod, Anda dapat melakukan hal berikut:
+ Mendistribusikan atau memusatkan pod di seluruh domain kegagalan yang berbeda tergantung pada persyaratan aplikasi. Misalnya, Anda dapat mendistribusikan pod untuk ketahanan, dan Anda dapat memusatkan pod untuk kinerja jaringan.
+ Menggabungkan kondisi yang berbeda, seperti mendistribusikan di seluruh Availability Zones dan mendistribusikan di seluruh node.
+ Tentukan tindakan yang diinginkan jika kondisi tidak dapat dipenuhi:
  + Gunakan `whenUnsatisfiable: DoNotSchedule` dengan kombinasi `maxSkew` dan `minDomains` untuk membuat persyaratan sulit untuk penjadwal.
  + Gunakan `whenUnsatisfiable: ScheduleAnyway` untuk mengurangi`maxSkew`.

Jika zona kegagalan menjadi tidak tersedia, pod di zona itu menjadi tidak sehat. Kubernetes menjadwal ulang polong sambil mengikuti kendala penyebaran jika memungkinkan.

Kode berikut menunjukkan contoh penggunaan kendala penyebaran topologi pod di seluruh Availability Zones atau di seluruh node:

```
...
spec:
  selector:
    matchLabels:
      app: <your-app-label>
    replicas: 3
    template:
      metadata:
        labels: <your-app-label>
      spec:
        serviceAccountName: <ServiceAccountName>
...
        topologySpreadConstraints:
        - labelSelector:
            matchLabels:
              app: <your-app-label>
          maxSkew: 1
          topologyKey: topology.kubernetes.io/zone # <---spread those pods evenly over all availability zones
          whenUnsatisfiable: ScheduleAnyway
        - labelSelector:
            matchLabels:
              app: <your-app-label>
          maxSkew: 1
          topologyKey: kubernetes.io/hostname # <---spread those pods evenly over all nodes
          whenUnsatisfiable: ScheduleAnyway
```

### Kendala penyebaran topologi seluruh cluster default
<a name="default-constraints"></a>

Secara default, Kubernetes menyediakan [serangkaian batasan penyebaran topologi untuk mendistribusikan Pod di seluruh node dan Availability Zone](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/#internal-default-constraints):

```
defaultConstraints:
  - maxSkew: 3
    topologyKey: "kubernetes.io/hostname"
    whenUnsatisfiable: ScheduleAnyway
  - maxSkew: 5
    topologyKey: "topology.kubernetes.io/zone"
    whenUnsatisfiable: ScheduleAnyway
```

**catatan**  
Aplikasi yang membutuhkan berbagai jenis kendala topologi dapat mengesampingkan kebijakan tingkat cluster.

Batasan default menetapkan tinggi`maxSkew`, yang tidak berguna untuk penerapan yang memiliki sejumlah kecil pod. Sampai sekarang, [tidak `KubeSchedulerConfiguration` dapat diubah](https://github.com/aws/containers-roadmap/issues/1468) di Amazon EKS. Jika Anda perlu menegakkan set batasan penyebaran topologi lainnya, pertimbangkan untuk menggunakan pengontrol penerimaan yang bermutasi seperti pada bagian di bawah ini. Anda juga dapat mengontrol batasan penyebaran topologi default jika Anda menjalankan penjadwal alternatif. Namun, mengelola penjadwal khusus menambah kompleksitas dan dapat berimplikasi pada ketahanan cluster dan HA. Untuk alasan ini, kami tidak menyarankan menggunakan penjadwal alternatif untuk batasan penyebaran topologi saja.

### Kebijakan Gatekeeper untuk topologi menyebarkan kendala
<a name="gatekeeper-policy"></a>

[Pilihan lain untuk menegakkan kendala penyebaran topologi adalah dengan menggunakan kebijakan dari proyek Gatekeeper.](https://open-policy-agent.github.io/gatekeeper/website/docs/) Kebijakan penjaga gerbang didefinisikan di tingkat aplikasi.

Contoh kode berikut menunjukkan penggunaan `Gatekeeper OPA` kebijakan untuk penerapan. Anda dapat mengubah kebijakan untuk kebutuhan Anda. Misalnya, terapkan kebijakan hanya pada penerapan yang memiliki label`HA=true`, atau tulis kebijakan serupa menggunakan pengontrol kebijakan yang berbeda.

Contoh pertama ini menunjukkan `ConstraintTemplate` digunakan dengan`k8stopologyspreadrequired_template.yml`:

```
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8stopologyspreadrequired
spec:
  crd:
    spec:
      names:
        kind: K8sTopologySpreadRequired
      validation:
        openAPIV3Schema:
          type: object
          properties:
            message:
              type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8stopologyspreadrequired

        get_message(parameters, _default) =3D msg {
          not parameters.message
          msg :=_default
        }


        get_message(parameters, _default) =3D msg {
          msg := parameters.message
        }

        violation[{"msg": msg}] {
          input.review.kind.kind ="Deployment"
          not input.review.object.spec.template.spec.topologySpreadConstraint
          def_msg :"Pod Topology Spread Constraints are required for Deployments"
          msg :get_message(input.parameters, def_msg)

        }
```

Kode berikut menunjukkan manifes `constraints` `k8stopologyspreadrequired_constraint.yml` YAMB:

```
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sTopologySpreadRequired
metadata:
  name: require-topologyspread-for-deployments
spec:
  match:
    kinds:
      - apiGroups: ["apps"]
        kinds: ["Deployment"]
    namespaces:  ## Without theses two lines will apply to the whole cluster
      - "example"
```

### Kapan menggunakan kendala penyebaran topologi
<a name="when-to-use"></a>

Pertimbangkan untuk menggunakan kendala penyebaran topologi untuk skenario berikut:
+ Aplikasi apa pun yang dapat diskalakan secara horizontal (misalnya, layanan web tanpa kewarganegaraan)
+ Aplikasi dengan replika aktif-aktif atau aktif-pasif (misalnya, database atau cache NoSQL)
+ Aplikasi dengan replika siaga (misalnya, pengontrol)

Komponen sistem yang dapat digunakan untuk skenario yang dapat diskalakan secara horizontal, misalnya, meliputi:
+ [Cluster Autoscaler](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler) dan [Karpenter](https://karpenter.sh/) (dengan dan) `replicaCount > 1` `leader-elect = true`
+ [AWS Pengontrol Load Balancer](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/)
+ [CoreDNS](https://coredns.io/)

## Afinitas pod dan anti-afinitas
<a name="anti-affinity"></a>

Dalam beberapa kasus, akan bermanfaat untuk memastikan bahwa tidak lebih dari satu pod dari tipe tertentu berjalan pada sebuah node. Misalnya, untuk menghindari penjadwalan beberapa pod yang berat jaringan pada node yang sama, Anda dapat menggunakan aturan anti-afinitas dengan label atau. `Ingress` `Network-heavy` Saat Anda menggunakan`anti-affinity`, Anda juga dapat menggunakan kombinasi berikut ini:
+ Taints pada node yang dioptimalkan jaringan
+ Toleransi yang sesuai pada pod yang berat jaringan
+ Afinitas node atau pemilih node untuk memastikan bahwa pod yang berat jaringan menggunakan instance yang dioptimalkan jaringan

Pod yang berat jaringan digunakan sebagai contoh. Anda mungkin memiliki persyaratan yang berbeda, seperti GPU, memori, atau penyimpanan lokal. Untuk contoh penggunaan dan opsi konfigurasi lainnya, lihat dokumentasi [Kubernetes](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity).

### Menyeimbangkan kembali polong
<a name="rebalance-pods"></a>

Bagian ini membahas dua pendekatan untuk menyeimbangkan kembali pod dalam klaster Kubernetes. Yang pertama menggunakan Descheduler untuk Kubernetes. Descheduler membantu mempertahankan distribusi pod dengan menerapkan strategi untuk menghapus pod yang melanggar batasan penyebaran topologi atau aturan anti-afinitas. Pendekatan kedua menggunakan fitur konsolidasi Karpenter dan pengepakan sampah. Konsolidasi terus mengevaluasi dan mengoptimalkan penggunaan sumber daya dengan mengkonsolidasikan beban kerja ke node yang dikemas lebih sedikit dan lebih efisien.

Kami merekomendasikan menggunakan Descheduler jika Anda tidak menggunakan Karpenter. Jika Anda menggunakan Karpenter dan Cluster Autoscaler bersama-sama, Anda dapat menggunakan Descheduler dengan Cluster Autoscaler untuk grup node.

#### Descheduler untuk node tanpa grup
<a name="descheduler"></a>

Tidak ada jaminan bahwa kendala topologi tetap terpenuhi saat pod dihapus. Misalnya, mengurangi penerapan dapat mengakibatkan distribusi pod tidak seimbang. Namun, karena Kubernetes menggunakan kendala penyebaran topologi pod hanya pada tahap penjadwalan, pod dibiarkan tidak seimbang di seluruh domain kegagalan.

Untuk mempertahankan distribusi pod yang seimbang dalam skenario seperti itu, Anda dapat menggunakan [Descheduler](https://github.com/kubernetes-sigs/descheduler) untuk Kubernetes. Descheduler adalah alat yang berguna untuk berbagai tujuan, seperti untuk menegakkan usia pod maksimum atau time to live (TTL), atau untuk meningkatkan penggunaan infrastruktur. Dalam konteks ketahanan dan ketersediaan tinggi (HA), pertimbangkan strategi Descheduler berikut:
+ [RemovePodsViolatingTopologySpreadConstraint](https://github.com/kubernetes-sigs/descheduler?tab=readme-ov-file#removepodsviolatingtopologyspreadconstraint)
+ [RemovePodsViolatingInterPodAntiAffinity](https://github.com/kubernetes-sigs/descheduler?tab=readme-ov-file#removepodsviolatinginterpodantiaffinity)
+ [RemoveDuplicates](https://github.com/kubernetes-sigs/descheduler?tab=readme-ov-file#removeduplicates)

#### Konsolidasi karpenter dan fitur pengepakan sampah
<a name="karpenter"></a>

Untuk beban kerja yang menggunakan Karpenter, Anda dapat menggunakan fungsi konsolidasi dan pengemasan sampah untuk mengoptimalkan pemanfaatan sumber daya dan mengurangi biaya di klaster Kubernetes. Karpenter terus mengevaluasi penempatan pod dan pemanfaatan node, dan mencoba untuk mengkonsolidasikan beban kerja ke node yang dikemas lebih sedikit dan lebih efisien bila memungkinkan. Proses ini melibatkan analisis kebutuhan sumber daya, mempertimbangkan kendala seperti aturan afinitas pod, dan berpotensi memindahkan pod antar node untuk meningkatkan efisiensi klaster secara keseluruhan. Kode berikut memberikan contoh:

```
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
  name: default
spec:
  disruption:
    consolidationPolicy: WhenUnderutilized
    expireAfter: 720h
```

Untuk`consolidationPolicy`, Anda dapat menggunakan `WhenUnderutilized` atau`WhenEmpty`:
+ Ketika `consolidationPolicy` diatur ke`WhenUnderutilized`, Karpenter mempertimbangkan semua node untuk konsolidasi. Ketika Karpenter menemukan node yang kosong atau kurang digunakan, Karpenter mencoba untuk menghapus atau mengganti node untuk mengurangi biaya.
+ Ketika `consolidationPolicy` disetel ke`WhenEmpty`, Karpenter mempertimbangkan untuk konsolidasi hanya node yang tidak mengandung pod beban kerja.

Keputusan konsolidasi Karpenter tidak hanya didasarkan pada persentase pemanfaatan CPU atau memori yang mungkin Anda lihat di alat pemantauan. Sebaliknya, Karpenter menggunakan algoritma yang lebih kompleks berdasarkan permintaan sumber daya pod dan pengoptimalan biaya potensial. Untuk informasi lebih lanjut, lihat dokumentasi [Karpenter](https://karpenter.sh/docs/concepts/disruption/#consolidation).