Tempatkan Pod Kubernetes di Amazon EKS dengan menggunakan afinitas node, taint, dan toleransi - AWS Prescriptive Guidance

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

Tempatkan Pod Kubernetes di Amazon EKS dengan menggunakan afinitas node, taint, dan toleransi

Hitesh Parikh dan Raghu Bhamidimarri, Amazon Web Services

Ringkasan

Pola ini menunjukkan penggunaan afinitas node Kubernetes, node taints, dan toleransi Pod untuk secara sengaja menjadwalkan Pod aplikasi pada node pekerja tertentu dalam klaster Amazon Elastic Kubernetes Service (Amazon EKS) di Amazon Web Services (AWS) Cloud.

Taint adalah properti node yang memungkinkan node untuk menolak satu set pod. Tolerasi adalah properti Pod yang memungkinkan penjadwal Kubernetes untuk menjadwalkan Pod pada node yang memiliki taint yang cocok.

Namun, toleransi saja tidak dapat mencegah penjadwal menempatkan Pod pada node pekerja yang tidak memiliki noda apa pun. Misalnya, Pod komputasi intensif dengan toleransi dapat secara tidak sengaja dijadwalkan pada node untainted tujuan umum. Dalam skenario itu, properti afinitas node dari sebuah Pod menginstruksikan scheduler untuk menempatkan Pod pada sebuah node yang memenuhi kriteria pemilihan node yang ditentukan dalam afinitas node.

Taints, tolerations, dan affinity node bersama-sama menginstruksikan scheduler untuk menjadwalkan Pod secara konsisten pada node dengan taints yang cocok dan label node yang cocok dengan kriteria pemilihan node afinitas node yang ditentukan pada Pod.

Pola ini memberikan contoh berkas manifes deployment Kubernetes, dan langkah-langkah untuk membuat klaster EKS, menyebarkan aplikasi, dan memvalidasi penempatan Pod.

Prasyarat dan batasan

Prasyarat

Batasan

  • Pola ini tidak menyediakan kode Java, dan mengasumsikan bahwa Anda sudah terbiasa dengan Java. Untuk membuat layanan mikro Java dasar, lihat Menerapkan contoh layanan mikro Java di Amazon EKS.

  • Langkah-langkah dalam artikel ini membuat sumber daya AWS yang dapat menambah biaya. Pastikan Anda membersihkan sumber daya AWS setelah Anda menyelesaikan langkah-langkah untuk menerapkan dan memvalidasi pola.

Arsitektur

Tumpukan teknologi target

  • Amazon EKS

  • Java

  • Docker

  • Amazon Elastic Container Registry (Amazon ECR)

Arsitektur target

Diagram arsitektur solusi menunjukkan Amazon EKS dengan dua Pod (Deployment 1 dan Deployment 2) dan dua grup node (ng1 dan ng2) dengan masing-masing dua node. Pod dan node memiliki properti berikut.

 

Penerapan 1 Pod

Penerapan 2 Pod

Grup simpul 1 (ng1)

Grup simpul 2 (ng2)

Toleransi

kunci: classified_workload, nilai: true, efek: NoSchedule

kunci: machine_learning_workload, nilai: true, efek: NoSchedule

Tidak ada

 

 

Afinitas simpul

kunci: alpha.eksctl.io/nodegroup-name = ng1;

Tidak ada

NodeGroups.name = ng1

 

Noda

 

 

kunci: classified_workload, nilai: true, efek: NoSchedule

kunci: machine_learning_workload, nilai: true, efek: NoSchedule

Tidak ada

Konfigurasi Amazon EKS dengan dua pod dan dua grup node.
  1. Pod Deployment 1 memiliki toleransi dan afinitas node yang ditentukan, yang menginstruksikan scheduler Kubernetes untuk menempatkan Pod deployment pada Node group 1 (ng1) node.

  2. Node group 2 (ng2) tidak memiliki label node yang cocok dengan ekspresi pemilih node afinitas node untuk Deployment 1, sehingga Pod tidak akan dijadwalkan pada node ng2.

  3. Pod Deployment 2 tidak memiliki toleransi atau afinitas node yang ditentukan dalam manifes penerapan. Scheduler akan menolak penjadwalan Deployment 2 Pod pada Node group 1 karena adanya noda pada node.

  4. Pod Deployment 2 akan ditempatkan pada Node group 2 sebagai gantinya, karena node tidak memiliki noda.

Pola ini menunjukkan bahwa dengan menggunakan taint dan toleransi, dikombinasikan dengan afinitas node, Anda dapat mengontrol penempatan Pod pada set node pekerja tertentu.

Alat

Layanan AWS

Alat lainnya

  • Docker adalah seperangkat produk platform as a service (PaaS) yang menggunakan virtualisasi pada tingkat sistem operasi untuk mengirimkan perangkat lunak dalam wadah.

  • kubectl adalah antarmuka baris perintah yang membantu Anda menjalankan perintah terhadap klaster Kubernetes.

Epik

TugasDeskripsiKeterampilan yang dibutuhkan

Buat file cluster.yaml.

Buat file yang disebut cluster.yaml dengan kode berikut.

apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: eks-taint-demo region: us-west-1 # Unmanaged nodegroups with and without taints. nodeGroups: - name: ng1 instanceType: m5.xlarge minSize: 2 maxSize: 3 taints: - key: classified_workload value: "true" effect: NoSchedule - key: machine_learning_workload value: "true" effect: NoSchedule - name: ng2 instanceType: m5.xlarge minSize: 2 maxSize: 3
Pemilik aplikasi, AWS DevOps, administrator Cloud, DevOps insinyur

Buat cluster dengan menggunakan eksctl.

Jalankan cluster.yaml file untuk membuat cluster EKS. Membuat cluster mungkin memakan waktu beberapa menit.

eksctl create cluster -f cluster.yaml
AWS DevOps, administrator sistem AWS, Pengembang aplikasi
TugasDeskripsiKeterampilan yang dibutuhkan

Buat repositori pribadi Amazon ECR.

Untuk membuat repositori Amazon ECR, lihat Membuat repositori pribadi. Perhatikan URI repo.

AWS DevOps, DevOps insinyur, Pengembang aplikasi

Buat Dockerfile.

Jika Anda memiliki gambar kontainer Docker yang ingin Anda gunakan untuk menguji polanya, Anda dapat melewati langkah ini.

Untuk membuat Dockerfile, gunakan cuplikan berikut sebagai referensi. Jika Anda mengalami kesalahan, lihat bagian Pemecahan Masalah.

FROM adoptopenjdk/openjdk11:jdk-11.0.14.1_1-alpine RUN apk add maven WORKDIR /code # Prepare by downloading dependencies ADD pom.xml /code/pom.xml RUN ["mvn", "dependency:resolve"] RUN ["mvn", "verify"] # Adding source, compile and package into a fat jar ADD src /code/src RUN ["mvn", "package"] EXPOSE 4567 CMD ["java", "-jar", "target/eksExample-jar-with-dependencies.jar"]
AWS DevOps, DevOps insinyur

Buat pom.xml dan file sumber, dan bangun dan dorong gambar Docker.

Untuk membuat pom.xml file dan file sumber Java, lihat Menerapkan contoh layanan mikro Java pada pola Amazon EKS.

Gunakan instruksi dalam pola itu untuk membangun dan mendorong gambar Docker.

AWS DevOps, DevOps insinyur, Pengembang aplikasi
TugasDeskripsiKeterampilan yang dibutuhkan

Buat file deployment.yaml.

Untuk membuat deployment.yaml file, gunakan kode di bagian Informasi tambahan.

Dalam kode, kunci untuk afinitas simpul adalah label apa pun yang Anda buat saat membuat grup simpul. Pola ini menggunakan label default yang dibuat oleh eksctl. Untuk informasi tentang menyesuaikan label, lihat Menetapkan Pod ke Node dalam dokumentasi Kubernetes.

Nilai untuk kunci afinitas simpul adalah nama grup simpul yang dibuat olehcluster.yaml.

Untuk mendapatkan kunci dan nilai untuk taint, jalankan perintah berikut.

kubectl get nodes -o json | jq '.items[].spec.taints'

Gambar adalah URI dari repositori Amazon ECR yang Anda buat pada langkah sebelumnya.

AWS DevOps, DevOps insinyur, Pengembang aplikasi

Menyebarkan file.

Untuk menyebarkan ke Amazon EKS, jalankan perintah berikut.

kubectl apply -f deployment.yaml
Pengembang aplikasi, DevOps insinyur, AWS DevOps

Periksa penyebaran.

  1. Untuk memeriksa apakah pod sudah SIAP, jalankan perintah berikut.

    kubectl get pods -o wide

    Jika POD sudah siap, output akan terlihat mirip dengan berikut ini, dengan STATUS as Running.

    NAME        READY    STATUS    RESTARTS   AGE   IP  NODE  NOMINATED NODE   READINESS GATES <pod_name>   1/1     Running   0          12d   192.168.18.50   ip-192-168-20-110.us-west-1.compute.internal   <none>           <none>

    Perhatikan nama Pod dan nama node. Anda dapat melewati langkah berikutnya.

  2. (Opsional) Untuk mendapatkan rincian tambahan tentang Pod dan memeriksa toleransi pada Pod, jalankan perintah berikut.

    kubectl describe pod <pod_name>

    Contoh output ada di bagian Informasi tambahan.

  3. Untuk memvalidasi bahwa penempatan Pod pada node sudah benar, jalankan perintah berikut.

    kubectl describe node <node name> | grep -A 1 "Taints"

    Konfirmasikan bahwa taint pada node cocok dengan toleransi, dan label pada node cocok dengan afinitas node yang ditentukan dalam. deployment.yaml

    Pod dengan toleransi dan afinitas node harus ditempatkan pada sebuah node dengan taints yang cocok dan label afinitas node. Perintah sebelumnya memberi Anda noda pada node. Berikut ini adalah output contoh.

    kubectl describe node ip-192-168-29-181.us-west-1.compute.internal | grep -A 1 "Taints" Taints:             classifled_workload=true:NoSchedule                     machine_learning_workload=true:NoSchedule

    Selain itu, jalankan perintah berikut untuk memeriksa bahwa node tempat Pod ditempatkan memiliki label yang cocok dengan label node affinity node.

    kubectl get node <node name> --show-labels
  4. Untuk memverifikasi bahwa aplikasi melakukan apa yang dimaksudkan untuk dilakukan, periksa log Pod dengan menjalankan perintah berikut.

    kubectl logs -f <name-of-the-pod>
Pengembang aplikasi, DevOps insinyur, AWS DevOps

Buat file deployment .yaml kedua tanpa toleransi dan afinitas node.

Langkah tambahan ini adalah memvalidasi bahwa ketika tidak ada afinitas atau toleransi node yang ditentukan dalam file manifes deployment, Pod yang dihasilkan tidak dijadwalkan pada node dengan taints. (Ini harus dijadwalkan pada node yang tidak memiliki noda apa pun). Gunakan kode berikut untuk membuat file deployment baru yang disebutdeploy_no_taint.yaml.

apiVersion: apps/v1 kind: Deployment metadata: name: microservice-deployment-non-tainted spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: java-microservice-no-taint template: metadata: labels: app.kubernetes.io/name: java-microservice-no-taint spec: containers: - name: java-microservice-container-2 image: <account_number>.dkr.ecr<region>.amazonaws.com/<repository_name>:latest ports: - containerPort: 4567
Pengembang aplikasi, AWS DevOps, DevOps insinyur

Menerapkan berkas .yaml deployment kedua, dan validasi penempatan Pod

  1. Jalankan perintah berikut.

    kubectl apply -f deploy_no_taint.yaml
  2. Setelah penerapan berhasil, jalankan perintah yang sama dengan yang Anda jalankan sebelumnya untuk memeriksa penempatan Pod di grup node tanpa taint.

    kubectl describe node <node_name> | grep "Taints"

    Outputnya harus sebagai berikut.

    Taints: <none>

    Ini menyelesaikan pengujian.

Pengembang aplikasi, AWS DevOps, DevOps insinyur
TugasDeskripsiKeterampilan yang dibutuhkan

Bersihkan sumber daya.

Untuk menghindari biaya AWS untuk sumber daya yang dibiarkan berjalan, gunakan perintah berikut.

eksctl delete cluster --name <Name of the cluster> --region <region-code>
AWS DevOps, Pengembang aplikasi

Pemecahan Masalah

IsuSolusi

Beberapa perintah ini mungkin tidak berjalan jika sistem Anda menggunakan arsitektur arm64 (terutama jika Anda menjalankan ini pada Mac M1). Baris berikut mungkin error out.

FROM adoptopenjdk/openjdk11:jdk-11.0.14.1_1-alpine

Jika Anda memiliki kesalahan saat menjalankan Dockerfile, ganti FROM baris dengan baris berikut.

FROM bellsoft/liberica-openjdk-alpine-musl:17

Sumber daya terkait

Informasi tambahan

deployment.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: microservice-deployment spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: java-microservice template: metadata: labels: app.kubernetes.io/name: java-microservice spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: alpha.eksctl.io/nodegroup-name operator: In values: - <node-group-name-from-cluster.yaml> tolerations: #only this pod has toleration and is viable to go to ng with taint - key: "<Taint key>" #classified_workload in our case operator: Equal value: "<Taint value>" #true effect: "NoSchedule" - key: "<Taint key>" #machine_learning_workload in our case operator: Equal value: "<Taint value>" #true effect: "NoSchedule" containers: - name: java-microservice-container image: <account_number>.dkr.ecr<region>.amazonaws.com/<repository_name>:latest ports: - containerPort: 4567

jelaskan contoh output pod

Name: microservice-deployment-in-tainted-nodes-5684cc495b-vpcfx Namespace: default Priority: 0 Node: ip-192-168-29-181.us-west-1.compute.internal/192.168.29.181 Start Time: Wed, 14 Sep 2022 11:06:47 -0400 Labels: app.kubernetes.io/name=java-microservice-taint pod-template-hash=5684cc495b Annotations: kubernetes.io/psp: eks.privileged Status: Running IP: 192.168.13.44 IPs: IP: 192.168.13.44 Controlled By: ReplicaSet/microservice-deployment-in-tainted-nodes-5684cc495b Containers: java-microservice-container-1: Container ID: docker://5c158df8cc160de8f57f62f3ee16b12725a87510a809d90a1fb9e5d873c320a4 Image: 934188034500.dkr.ecr.us-east-1.amazonaws.com/java-eks-apg Image ID: docker-pullable://934188034500.dkr.ecr.us-east-1.amazonaws.com/java-eks-apg@sha256:d223924aca8315aab20d54eddf3443929eba511b6433017474d01b63a4114835 Port: 4567/TCP Host Port: 0/TCP State: Running Started: Wed, 14 Sep 2022 11:07:02 -0400 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-ddvvw (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: kube-api-access-ddvvw: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: classifled_workload=true:NoSchedule machine_learning_workload=true:NoSchedule node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: <none>