Cara mengakses resource Kubernetes Pod

Imbalan oleh Tohad



Saat memulai dengan Kubernetes, biasanya orang lupa tentang mengonfigurasi resource container. Pada tahap ini, Anda hanya perlu memastikan bahwa image Docker berfungsi dan dapat diterapkan ke cluster Kubernetes Anda.



Namun nantinya, aplikasi perlu diterapkan ke cluster produksi bersama dengan aplikasi lain. Untuk melakukan ini, Anda perlu mengalokasikan sumber daya untuk penampung dan memastikan bahwa ada cukup sumber daya untuk memulai dan menjalankan aplikasi, dan di aplikasi lain yang sedang berjalan tidak akan ada masalah.



Tim Kubernetes aaS dari Mail.ru telah menerjemahkan artikel tentang sumber daya kontainer (CPU & MEM), permintaan, dan batas sumber daya. Anda akan mempelajari manfaat dari pengaturan ini dan apa yang terjadi jika Anda tidak menginstalnya.



Menghitung sumber daya



Kami memiliki dua jenis sumber daya dengan unit berikut:



  • Unit pemrosesan pusat (CPU) - inti;
  • Memory (MEM) - byte.


Sumber daya ditentukan untuk setiap penampung. Dalam file pod YAML berikut, Anda akan melihat bagian sumber daya yang berisi sumber daya yang diminta dan dibatasi:



  • Resource Pod yang Diminta = jumlah resource yang diminta dari semua pod;
  • Batas Pod = jumlah resource batas semua pod.


apiVersion: v1
kind: Pod
metadata:
  name: backend-pod-name
  labels:
    application: backend
spec:
  containers:
    โ€” name: main-container
      image: my-backend
      tag: v1
      ports:
      โ€” containerPort: 8080
      resources:
        requests:
          cpu: 0.2 # REQUESTED CPU: 200m cores
          memory: "1Gi" # REQUESTED MEM: 1Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi
    โ€” name: other-container
      image: other-app
      tag: v1
      ports:
      โ€” containerPort: 8000
      resources:
        requests:
          cpu: "200m" # REQUESTED CPU: 200m cores
          memory: "0.5Gi" # REQUESTED MEM: 0.5Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi
Contoh Resource yang Diminta dan Batasi



Kolom resources.requesteddari spesifikasi Pod adalah salah satu elemen yang digunakan untuk menemukan node yang diinginkan. Sudah di atasnya, Anda dapat menjadwalkan penerapan Pod. Bagaimana Anda menemukan node yang cocok?



Kubernetes terdiri dari beberapa komponen, antara lain master node atau master node (Kubernetes Control Plane). Ada beberapa proses dalam node master: kube-apiserver, kube-controller-manager, dan kube-scheduler.



Proses kube-scheduler bertanggung jawab untuk melihat modul yang baru dibuat dan mencari kemungkinan node pekerja yang cocok dengan semua permintaan modul, termasuk jumlah sumber daya yang diminta. Daftar node yang ditemukan oleh kube-scheduler diberi peringkat. Pod direncanakan untuk situs dengan skor tertinggi.



Dimana Pod ungu akan ditempatkan?



Gambar menunjukkan bahwa kube-scheduler harus menjadwalkan Pod ungu baru. Cluster Kubernetes berisi dua node: A dan B. Seperti yang Anda lihat, kube-scheduler tidak dapat menjadwalkan sebuah Pod ke node A - resource yang tersedia (tidak diminta) tidak sesuai dengan permintaan untuk Pod ungu. Misalnya, 1GB memori yang diminta oleh Pod ungu tidak akan muat di node A, karena memori yang tersedia adalah 0,5GB. Tetapi Node B memiliki sumber daya yang cukup. Hasilnya, kube-scheduler memutuskan bahwa tujuan dari Pod ungu adalah Node B.



Sekarang kita tahu bagaimana sumber daya yang diminta mempengaruhi pilihan node untuk memulai Pod. Tapi bagaimana pengaruh sumber daya marjinal?



Sumber daya batas adalah batas yang tidak dapat dilintasi CPU / MEM. Akan tetapi, CPU-nya fleksibel, sehingga container yang mencapai batas CPU tidak akan menyebabkan Pod tersebut mati. Sebaliknya, pelambatan CPU akan dimulai. Jika batas penggunaan MEM tercapai, kontainer akan dihentikan karena OOM-Killer dan dimulai ulang, jika diizinkan oleh pengaturan RestartPolicy.



Meminta dan membatasi sumber daya secara detail



Hubungan Sumber Daya Antara Docker dan Kubernetes Cara



terbaik untuk menjelaskan cara kerja sumber daya yang diminta dan dibatasi adalah dengan merepresentasikan hubungan antara Kubernetes dan Docker. Pada gambar di atas, Anda dapat melihat bagaimana bidang Kubernetes dan flag peluncuran Docker terkait.



Memori: Permintaan dan Batasan



containers:
...
 resources:
   requests:
     memory: "0.5Gi"
   limits:
     memory: "1Gi"


Seperti disebutkan di atas, memori diukur dalam byte. Berdasarkan dokumentasi Kubernetes , kita dapat menentukan memori sebagai angka. Biasanya ini adalah bilangan bulat, misalnya 2678 - yaitu, 2678 byte. Anda juga dapat menggunakan sufiks Gdan Gi, yang terpenting, ingatlah bahwa sufiks itu tidak setara. Yang pertama adalah desimal dan yang kedua adalah biner. Sebagai contoh, disebutkan dalam K8S dokumentasi: 128974848, 129e6, 129M, 123Mi- mereka hampir setara.



Parameter Kubernetes limits.memorycocok dengan flag --memorydari Docker. Dalam kasusrequest.memorytidak ada panah untuk Docker karena Docker tidak menggunakan bidang ini. Anda mungkin bertanya apakah ini perlu? Ya perlu. Seperti yang saya katakan sebelumnya, bidang ini penting bagi Kubernetes. Berdasarkan informasi darinya, kube-scheduler memutuskan node mana yang akan menjadwalkan Pod.



Apa yang terjadi jika tidak ada cukup memori yang dipasang untuk kueri?



Jika container mencapai batas memori yang diminta, maka Pod tersebut akan ditempatkan di grup Pod, yang akan berhenti jika tidak ada memori di node tersebut.



Apa yang terjadi jika Anda menyetel batas memori terlalu rendah?



Jika penampung melebihi batas memori, itu akan dihentikan karena OOM-Killed. Dan itu akan dimulai ulang jika memungkinkan berdasarkan RestartPolicy, di mana default-nya Always.



Apa yang terjadi jika Anda tidak menentukan memori yang diminta?



Kubernetes akan mengambil batasan dan menetapkannya sebagai default.



Apa yang dapat terjadi jika Anda tidak menentukan batas memori?



Penampung tidak memiliki batasan, ia dapat menggunakan memori sebanyak yang diinginkan. Jika dia mulai menggunakan semua memori yang tersedia dari node, maka OOM akan membunuhnya. Penampung kemudian akan dimulai ulang jika memungkinkan berdasarkan RestartPolicy.



Apa yang terjadi jika Anda tidak menentukan batas memori?



Ini adalah skenario kasus terburuk: penjadwal tidak tahu berapa banyak sumber daya yang dibutuhkan penampung, dan ini dapat menyebabkan masalah serius pada node. Dalam kasus ini, alangkah baiknya memiliki batasan namespace default (disetel oleh LimitRange). Tidak ada batasan secara default - Pod tidak memiliki batasan, Pod dapat menggunakan memori sebanyak yang diinginkan.



Jika memori yang diminta lebih dari yang dapat ditawarkan node, Pod tidak akan dijadwalkan. Penting untuk diingat bahwa Requests.memoryini bukanlah nilai minimum. Ini adalah deskripsi jumlah memori yang cukup untuk wadah untuk terus berjalan.



Biasanya disarankan untuk menyetel nilai yang sama untuk request.memorydanlimit.memory... Hal ini mencegah Kubernetes untuk menjadwalkan Pod pada node yang memiliki cukup memori untuk menjalankan Pod tetapi tidak cukup untuk dijalankan. Perlu diingat: Saat menjadwalkan Pod, Kubernetes hanya menghitung requests.memory, limits.memorybukan menghitung.



CPU: permintaan dan batas



containers:
...
 resources:
   requests:
     cpu: 1
   limits:
     cpu: "1200m"


Dengan CPU, semuanya menjadi sedikit lebih rumit. Kembali ke gambar hubungan antara Kubernetes dan Docker, Anda dapat melihat bahwa itu request.cpucocok --cpu-shares, sementara itu limit.cpucocok dengan flag cpusdi Docker.



CPU yang diminta Kubernetes dikalikan dengan 1024, proporsi siklus CPU. Jika Anda ingin meminta 1 inti penuh, Anda harus menambahkan cpu: 1seperti yang ditunjukkan di atas.



Meminta kernel lengkap (proporsi = 1024) tidak berarti penampung Anda akan menerimanya. Jika mesin host Anda hanya memiliki satu inti dan Anda menggunakan lebih dari satu penampung, maka semua penampung harus berbagi CPU yang tersedia di antara mereka sendiri. Bagaimana ini bisa terjadi? Mari kita lihat gambarnya.





Permintaan CPU - Sistem Inti Tunggal



Katakanlah Anda memiliki sistem host inti tunggal yang menjalankan wadah. Ibu (Kubernetes) telah membuat kue (CPU) dan ingin membagikannya kepada anak-anak (wadah). Tiga anak menginginkan satu kue utuh (proporsi = 1024), anak lain menginginkan separuh kue (512). Ibu ingin bersikap adil dan melakukan perhitungan sederhana.



#    ?
# 3           
cakesNumberKidsWant = (3 * 1) + (1 * 0.5) = 3.5
#   :
3 (/) * 1 ( / ) + 1 (/) * 0.5 ( / )
#   ?
availableCakesNumber = 1
#   ()    ?
newMaxRequest = 1 / 3.5 =~ 28%


Berdasarkan perhitungan, tiga turunan akan menerima 28% dari kernel, dan bukan keseluruhan kernel. Anak keempat akan mendapatkan 14% dari seluruh kernel, bukan setengahnya. Tetapi segalanya akan berbeda jika Anda memiliki sistem multi-core.





Permintaan CPU - Sistem Multi-core (4)



Pada gambar di atas, Anda dapat melihat bahwa tiga anak menginginkan kue utuh dan satu menginginkan setengah. Karena ibu telah memanggang empat kue, setiap anaknya akan mendapatkan sebanyak yang mereka inginkan. Dalam sistem multi-inti, sumber daya prosesor tersebar di semua inti prosesor yang tersedia. Jika sebuah kontainer dibatasi kurang dari satu inti CPU penuh, itu masih dapat menggunakannya 100%.



Perhitungan di atas telah disederhanakan untuk memahami bagaimana CPU dialokasikan di antara container. Tentu saja, selain container itu sendiri, ada proses lain yang juga menggunakan resource CPU. Saat proses dalam satu container menganggur, yang lain dapat menggunakan resource-nya. CPU: "200m"sesuai CPU: 0,2, yang berarti sekitar 20% dari satu inti.



Sekarang mari kita bicarakanlimit.cpu... CPU yang membatasi Kubernetes dikalikan dengan 100. Hasilnya adalah jumlah waktu yang dapat digunakan container setiap 100 ฮผs ( cpu-period).



limit.cpucocok dengan bendera Docker --cpus. Ini adalah kombinasi baru antara lama --cpu-perioddan --cpu-quota. Dengan menyetelnya, kami menunjukkan berapa banyak sumber daya CPU yang tersedia yang dapat digunakan penampung secara maksimal hingga mulai membatasi:



  • cpus adalah kombinasi dari cpu-perioddan cpu-quota. cpus = 1.5setara dengan pengaturan cpu-period = 100000dan cpu-quota = 150000;
  • cpu-period - CPU CFS scheduler period , secara default 100 mikrodetik;
  • cpu-quota - jumlah mikrodetik di cpu-perioddalam wadah yang dibatasi.


Apa yang terjadi jika CPU yang diminta tidak mencukupi?



Jika wadah membutuhkan lebih dari yang dipasang, maka itu akan mencuri CPU dari proses lain.



Apa yang terjadi jika Anda menetapkan batas CPU yang tidak mencukupi?



Karena sumber daya CPU dapat disesuaikan, pembatasan akan diaktifkan.



Apa yang terjadi jika Anda tidak menentukan permintaan CPU?



Seperti halnya memori, nilai permintaan sama dengan batasnya.



Apa yang terjadi jika Anda tidak menentukan batas CPU?



Penampung akan menggunakan CPU sebanyak yang dibutuhkan. Jika kebijakan CPU default (LimitRange) ditentukan di namespace, batas ini juga digunakan untuk penampung.



Apa yang terjadi jika Anda tidak menentukan permintaan atau batas CPU?



Mengenai memori, ini adalah skenario kasus terburuk. Penjadwal tidak mengetahui berapa banyak sumber daya yang dibutuhkan penampung Anda, dan ini dapat menyebabkan masalah serius pada node. Untuk menghindarinya, Anda perlu menyetel batas default untuk namespace (LimitRange).



Ingat, jika Anda meminta lebih banyak CPU daripada yang dapat disuplai oleh node, maka Pod tidak akan dijadwalkan. Requests.cpu- bukan nilai minimum, tetapi nilai yang cukup untuk memulai Pod dan berjalan dengan lancar. Jika aplikasi Anda tidak melakukan penghitungan yang rumit, opsi terbaik adalah menginstal request.cpu <= 1dan menjalankan replika sebanyak yang diperlukan.



Jumlah ideal sumber daya yang diminta atau batas sumber daya



Kami belajar tentang batasan sumber daya komputasi. Sekarang saatnya menjawab pertanyaan, โ€œBerapa banyak resource yang dibutuhkan Pod saya untuk menjalankan aplikasi tanpa masalah? Berapa jumlah yang ideal? "



Sayangnya, tidak ada jawaban pasti untuk pertanyaan-pertanyaan tersebut. Jika Anda tidak tahu bagaimana kinerja aplikasi Anda, berapa banyak CPU atau memori yang dibutuhkan, opsi terbaik adalah memberi aplikasi banyak memori dan CPU, lalu menjalankan benchmark.



Selain tes kinerja, amati perilaku pemantauan aplikasi selama seminggu. Jika grafik menunjukkan bahwa aplikasi Anda mengonsumsi lebih sedikit sumber daya daripada yang Anda minta, Anda dapat mengurangi jumlah CPU atau memori yang diminta.



Lihat dashboard Grafana ini sebagai contoh .... Ini menampilkan perbedaan antara sumber daya yang diminta atau batas sumber daya dan penggunaan sumber daya saat ini.



Kesimpulan



Membuat kueri dan membatasi resource membantu menjaga cluster Kubernetes Anda tetap sehat. Mengonfigurasi batas dengan benar meminimalkan biaya dan menjaga aplikasi tetap berjalan setiap saat.



Singkatnya, ada beberapa hal yang perlu diperhatikan:



  1. Resource yang diminta adalah konfigurasi yang dipertimbangkan selama startup (ketika Kubernetes berencana untuk menghosting aplikasi). Sebaliknya, membatasi sumber daya penting pada waktu proses - saat aplikasi sudah berjalan di node.
  2. Dibandingkan dengan memori, CPU adalah sumber daya yang diatur. Jika CPU tidak mencukupi, Pod Anda tidak akan mati, Pod Anda akan mulai dibatasi.
  3. Sumber daya yang diminta dan batas sumber daya bukanlah nilai minimum dan maksimum! Dengan mengidentifikasi sumber daya yang diminta, Anda memastikan bahwa aplikasi Anda akan berjalan dengan lancar.
  4. Ini adalah praktik yang baik untuk menyetel permintaan memori sama dengan batas memori.
  5. Sebaiknya instal seperti yang diminta CPU <=1jika aplikasi tidak melakukan penghitungan yang rumit.
  6. Jika Anda meminta lebih banyak sumber daya daripada yang dimiliki node, maka Pod tidak akan pernah dijadwalkan untuk node tersebut.
  7. Gunakan pengujian dan pemantauan beban untuk menentukan jumlah yang benar dari sumber daya / batas sumber daya yang diminta.


Semoga artikel ini membantu Anda memahami konsep dasar pembatasan sumber daya. Dan Anda akan dapat menerapkan pengetahuan ini dalam pekerjaan Anda.



Semoga berhasil!



Apa lagi yang harus dibaca:



  1. SRE observability: namespace dan struktur metrik .
  2. 90+ Kubernetes: , , , .
  3. Kubernetes .



All Articles