Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

27 April di konferensi Pemogokan 2019, sebagai bagian dari bagian “DevOps”, laporan “Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes” diberikan. Ini membahas tentang bagaimana Anda dapat menggunakan K8 untuk memastikan ketersediaan tinggi aplikasi Anda dan memastikan kinerja puncak.

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Secara tradisi, kami dengan senang hati mempersembahkan video laporan tersebut (44 menit, jauh lebih informatif dibandingkan artikel) dan ringkasan utama dalam bentuk teks. Pergi!

Mari kita analisa topik laporan kata demi kata dan mulai dari akhir.

Kubernetes

Katakanlah kita memiliki container Docker di host kita. Untuk apa? Untuk memastikan pengulangan dan isolasi, yang pada gilirannya memungkinkan penerapan yang sederhana dan baik, CI/CD. Kami memiliki banyak kendaraan dengan kontainer.

Apa yang disediakan Kubernetes dalam kasus ini?

  1. Kami berhenti memikirkan mesin-mesin ini dan mulai bekerja dengan “cloud” sekelompok kontainer atau pod (kelompok kontainer).
  2. Selain itu, kami bahkan tidak memikirkan pod individual, namun mengelola lebih banyakоkelompok yang lebih besar. Seperti primitif tingkat tinggi izinkan kami mengatakan bahwa ada templat untuk menjalankan beban kerja tertentu, dan berikut adalah jumlah instance yang diperlukan untuk menjalankannya. Jika kami kemudian mengubah template, semua instance akan berubah.
  3. Dengan API deklaratif Daripada menjalankan serangkaian perintah tertentu, kami mendeskripsikan “struktur dunia” (dalam YAML), yang dibuat oleh Kubernetes. Dan lagi: ketika deskripsinya berubah, tampilan sebenarnya juga akan berubah.

Pengelolaan sumber daya

CPU

Mari kita jalankan nginx, php-fpm dan mysql di server. Layanan ini sebenarnya akan menjalankan lebih banyak proses, yang masing-masing memerlukan sumber daya komputasi:

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)
(angka-angka pada slide adalah “burung beo”, kebutuhan abstrak setiap proses akan daya komputasi)

Untuk membuatnya lebih mudah untuk bekerja dengan ini, adalah logis untuk menggabungkan proses ke dalam kelompok (misalnya, semua proses nginx ke dalam satu kelompok “nginx”). Cara sederhana dan jelas untuk melakukan ini adalah dengan menempatkan setiap grup dalam sebuah wadah:

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Untuk melanjutkan, Anda perlu mengingat apa itu container (di Linux). Kemunculannya dimungkinkan berkat tiga fitur utama di kernel, yang diterapkan sejak lama: kemampuan, ruang nama и grup c. Dan pengembangan lebih lanjut difasilitasi oleh teknologi lain (termasuk “shell” yang nyaman seperti Docker):

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Dalam konteks laporan, kami hanya tertarik pada grup c, karena grup kontrol adalah bagian dari fungsionalitas container (Docker, dll.) yang mengimplementasikan manajemen sumber daya. Proses yang digabungkan ke dalam kelompok, seperti yang kita inginkan, adalah kelompok kontrol.

Mari kembali ke persyaratan CPU untuk proses ini, dan sekarang untuk grup proses:

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)
(Saya ulangi bahwa semua angka adalah ekspresi abstrak dari kebutuhan sumber daya)

Pada saat yang sama, CPU itu sendiri memiliki sumber daya tertentu yang terbatas (dalam contoh ini adalah 1000), yang mungkin tidak dimiliki setiap orang (jumlah kebutuhan semua kelompok adalah 150+850+460=1460). Apa yang akan terjadi dalam kasus ini?

Kernel mulai mendistribusikan sumber daya dan melakukannya secara “adil”, memberikan jumlah sumber daya yang sama kepada setiap kelompok. Namun dalam kasus pertama, jumlahnya lebih banyak dari yang dibutuhkan (333>150), sehingga kelebihannya (333-150=183) tetap menjadi cadangan, yang juga didistribusikan secara merata di antara dua wadah lainnya:

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Akibatnya: kontainer pertama memiliki sumber daya yang cukup, kontainer kedua – tidak memiliki sumber daya yang cukup, dan kontainer ketiga – tidak memiliki sumber daya yang cukup. Ini adalah hasil dari tindakan penjadwal "jujur" di Linux - CFS. Pengoperasiannya dapat disesuaikan menggunakan penugasan beban masing-masing wadah. Misalnya seperti ini:

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Mari kita lihat kasus kekurangan resource di container kedua (php-fpm). Semua sumber daya kontainer didistribusikan secara merata antar proses. Hasilnya, proses master berjalan dengan baik, namun semua pekerja melambat, menerima kurang dari setengah dari apa yang mereka butuhkan:

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Beginilah cara kerja penjadwal CFS. Kami selanjutnya akan menyebut bobot yang kami tetapkan pada wadah permintaan. Mengapa demikian - lihat lebih jauh.

Mari kita lihat keseluruhan situasi dari sisi lain. Seperti yang Anda ketahui, semua jalan menuju ke Roma, dan dalam kasus komputer, ke CPU. Satu CPU, banyak tugas - Anda memerlukan lampu lalu lintas. Cara paling sederhana untuk mengelola sumber daya adalah “lampu lalu lintas”: mereka memberi satu proses waktu akses tetap ke CPU, lalu proses berikutnya, dan seterusnya.

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Pendekatan ini disebut kuota keras (pembatasan keras). Mari kita mengingatnya secara sederhana sebagai batas. Namun, jika Anda mendistribusikan batasan ke semua kontainer, masalah muncul: mysql melaju di sepanjang jalan dan pada titik tertentu kebutuhannya akan CPU berakhir, tetapi semua proses lainnya terpaksa menunggu hingga CPU menganggur.

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Mari kita kembali ke kernel Linux dan interaksinya dengan CPU - gambaran keseluruhannya adalah sebagai berikut:

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

cgroup memiliki dua pengaturan - pada dasarnya ini adalah dua “twist” sederhana yang memungkinkan Anda untuk menentukan:

  1. berat untuk wadah (permintaan) adalah 'share';
  2. persentase dari total waktu CPU untuk mengerjakan tugas kontainer (batas) adalah saham.

Bagaimana cara mengukur CPU?

Ada beberapa cara berbeda:

  1. Apa burung beo, tidak ada yang tahu - Anda harus bernegosiasi setiap saat.
  2. Bunga lebih jelas, tetapi relatif: 50% server dengan 4 core dan 20 core adalah hal yang sangat berbeda.
  3. Anda dapat menggunakan yang telah disebutkan beban, yang diketahui Linux, tetapi keduanya juga relatif.
  4. Pilihan yang paling memadai adalah mengukur sumber daya komputasi detik. Itu. dalam detik waktu prosesor relatif terhadap detik waktu nyata: 1 detik waktu prosesor diberikan per 1 detik nyata - ini adalah satu inti CPU keseluruhan.

Untuk membuatnya lebih mudah untuk berbicara, mereka mulai mengukur secara langsung kernel, artinya waktu CPU yang sama dibandingkan dengan waktu CPU yang sebenarnya. Karena Linux memahami bobot, tetapi tidak terlalu memahami waktu/inti CPU, diperlukan mekanisme untuk menerjemahkan dari satu bobot ke bobot lainnya.

Mari kita pertimbangkan contoh sederhana dengan server dengan 3 inti CPU, di mana tiga pod akan diberi bobot (500, 1000, dan 1500) yang dengan mudah diubah menjadi bagian inti yang sesuai yang dialokasikan padanya (0,5, 1, dan 1,5).

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Jika Anda mengambil server kedua, yang mana akan terdapat dua kali lebih banyak inti (6), dan menempatkan pod yang sama di sana, distribusi inti dapat dengan mudah dihitung hanya dengan mengalikan dengan 2 (masing-masing 1, 2, dan 3). Namun momen penting terjadi ketika pod keempat muncul di server ini, yang bobotnya, demi kenyamanan, adalah 3000. Ini menghabiskan sebagian sumber daya CPU (setengah inti), dan untuk pod yang tersisa dihitung ulang (dibelah dua):

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Kubernetes dan sumber daya CPU

Di Kubernetes, sumber daya CPU biasanya diukur miliadrax, yaitu 0,001 inti diambil sebagai berat dasar. (Hal yang sama dalam terminologi Linux/cgroups disebut pembagian CPU, meskipun, lebih tepatnya, 1000 milicore = 1024 pembagian CPU.) K8s memastikan bahwa ia tidak menempatkan lebih banyak pod di server daripada sumber daya CPU yang tersedia untuk jumlah bobot semua pod.

Bagaimana ini bisa terjadi? Saat Anda menambahkan server ke cluster Kubernetes, dilaporkan berapa banyak inti CPU yang tersedia. Dan saat membuat pod baru, penjadwal Kubernetes mengetahui berapa banyak inti yang dibutuhkan pod ini. Dengan demikian, pod akan ditugaskan ke server yang memiliki cukup core.

Apa yang akan terjadi jika tidak permintaan ditentukan (yaitu pod tidak memiliki jumlah inti yang dibutuhkan)? Mari kita cari tahu bagaimana Kubernetes menghitung sumber daya secara umum.

Untuk sebuah pod, Anda dapat menentukan permintaan (penjadwal CFS) dan batasannya (ingat lampu lalu lintas?):

  • Jika nilainya sama, maka pod akan diberi kelas QoS terjamin. Jumlah inti yang selalu tersedia dijamin.
  • Jika permintaan kurang dari batas - kelas QoS mudah meledak. Itu. Kita mengharapkan sebuah pod, misalnya, untuk selalu menggunakan 1 inti, namun nilai ini bukan batasannya: kadang-kadang pod dapat menggunakan lebih banyak (bila server memiliki sumber daya gratis untuk ini).
  • Ada juga kelas QoS upaya terbaik — ini mencakup pod-pod yang permintaannya tidak ditentukan. Sumber daya diberikan kepada mereka terakhir.

ingatan

Dengan memori, situasinya serupa, tetapi sedikit berbeda - lagipula, sifat sumber daya ini berbeda. Secara umum analoginya adalah sebagai berikut:

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Mari kita lihat bagaimana permintaan diimplementasikan dalam memori. Biarkan pod hidup di server, mengubah konsumsi memori, hingga salah satu pod menjadi sangat besar sehingga kehabisan memori. Dalam kasus ini, pembunuh OOM muncul dan mematikan proses terbesar:

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Hal ini tidak selalu cocok untuk kita, jadi ada kemungkinan untuk mengatur proses mana yang penting bagi kita dan tidak boleh dihentikan. Untuk melakukan ini, gunakan parameter oom_score_adj.

Mari kembali ke kelas QoS CPU dan menggambar analogi dengan nilai oom_score_adj yang menentukan prioritas konsumsi memori untuk pod:

  • Nilai oom_score_adj terendah untuk sebuah pod - -998 - berarti pod tersebut harus dimatikan terakhir, ini terjamin.
  • Yang tertinggi - 1000 - adalah upaya terbaik, pod tersebut dibunuh terlebih dahulu.
  • Untuk menghitung nilai yang tersisa (mudah meledak) terdapat rumus yang intinya adalah semakin banyak sumber daya yang diminta sebuah pod, semakin kecil kemungkinannya untuk dibunuh.

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

"Putaran" kedua - batas_dalam_byte - untuk batasan. Dengan itu, semuanya menjadi lebih sederhana: kita cukup menetapkan jumlah maksimum memori yang dikeluarkan, dan di sini (tidak seperti CPU) tidak ada pertanyaan tentang bagaimana mengukurnya (memori).

Total

Setiap pod di Kubernetes diberikan requests и limits - kedua parameter untuk CPU dan memori:

  1. Berdasarkan permintaan, penjadwal Kubernetes bekerja, yang mendistribusikan pod antar server;
  2. berdasarkan seluruh parameter, kelas QoS pod ditentukan;
  3. Bobot relatif dihitung berdasarkan permintaan CPU;
  4. penjadwal CFS dikonfigurasikan berdasarkan permintaan CPU;
  5. OOM killer dikonfigurasi berdasarkan permintaan memori;
  6. “lampu lalu lintas” dikonfigurasi berdasarkan batas CPU;
  7. Berdasarkan batas memori, batas dikonfigurasi untuk cgroup.

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Secara umum, gambaran ini menjawab semua pertanyaan tentang bagaimana bagian utama pengelolaan sumber daya terjadi di Kubernetes.

Penskalaan otomatis

Penskala otomatis kluster K8

Bayangkan seluruh cluster sudah terisi dan pod baru perlu dibuat. Meskipun pod tidak dapat muncul, statusnya hang Pending. Agar muncul, kita dapat menghubungkan server baru ke cluster atau... menginstal cluster-autoscaler, yang akan melakukannya untuk kita: memesan mesin virtual dari penyedia cloud (menggunakan permintaan API) dan menghubungkannya ke cluster , setelah itu pod akan ditambahkan.

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Ini adalah penskalaan otomatis cluster Kubernetes, yang berfungsi dengan baik (menurut pengalaman kami). Namun, seperti di tempat lain, ada beberapa perbedaan di sini...

Selama kami meningkatkan ukuran cluster, semuanya baik-baik saja, tetapi apa yang terjadi ketika cluster tersebut mulai membebaskan dirinya? Masalahnya adalah migrasi pod (untuk membebaskan host) secara teknis sangat sulit dan mahal dalam hal sumber daya. Kubernetes menggunakan pendekatan yang sangat berbeda.

Pertimbangkan sekelompok 3 server yang memiliki Deployment. Ini memiliki 6 pod: sekarang ada 2 untuk setiap server. Entah kenapa kami ingin mematikan salah satu server. Untuk melakukan ini kita akan menggunakan perintah kubectl drain, yang:

  • akan melarang pengiriman pod baru ke server ini;
  • akan menghapus pod yang ada di server.

Karena Kubernetes bertanggung jawab untuk menjaga jumlah pod (6), itu sederhana akan membuat ulang mereka pada node lain, namun tidak pada node yang dinonaktifkan, karena node tersebut sudah ditandai sebagai tidak tersedia untuk menghosting pod baru. Ini adalah mekanisme mendasar bagi Kubernetes.

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Namun, ada nuansa di sini juga. Dalam situasi serupa, untuk StatefulSet (bukan Deployment), tindakannya akan berbeda. Sekarang kita sudah memiliki aplikasi stateful - misalnya, tiga pod dengan MongoDB, salah satunya mengalami masalah (data rusak atau kesalahan lain yang menghalangi pod untuk memulai dengan benar). Dan kami kembali memutuskan untuk menonaktifkan satu server. Apa yang akan terjadi?

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

MongoDB bisa mati karena memerlukan kuorum: untuk cluster yang terdiri dari tiga instalasi, setidaknya dua harus berfungsi. Namun, ini tidak terjadi - terimakasih untuk Anggaran PodDisruption. Parameter ini menentukan jumlah minimum pod kerja yang diperlukan. Mengetahui bahwa salah satu pod MongoDB tidak lagi berfungsi, dan melihat bahwa PodDisruptionBudget disetel untuk MongoDB minAvailable: 2, Kubernetes tidak akan mengizinkan Anda menghapus sebuah pod.

Intinya: agar pergerakan (dan pada kenyataannya, pembuatan ulang) pod dapat berfungsi dengan benar saat cluster dirilis, PodDisruptionBudget perlu dikonfigurasi.

Penskalaan horizontal

Mari kita pertimbangkan situasi lain. Ada aplikasi yang berjalan sebagai Deployment di Kubernetes. Lalu lintas pengguna datang ke podnya (misalnya, ada tiga), dan kami mengukur indikator tertentu di dalamnya (misalnya, beban CPU). Saat beban bertambah, kami mencatatnya sesuai jadwal dan menambah jumlah pod untuk mendistribusikan permintaan.

Saat ini di Kubernetes hal ini tidak perlu dilakukan secara manual: penambahan/pengurangan otomatis jumlah pod dikonfigurasikan bergantung pada nilai indikator beban yang diukur.

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Pertanyaan utama di sini adalah: apa sebenarnya yang harus diukur и bagaimana menafsirkan nilai yang diperoleh (untuk mengambil keputusan mengubah jumlah pod). Anda dapat mengukur banyak hal:

Penskalaan otomatis dan pengelolaan sumber daya di Kubernetes (ikhtisar dan laporan video)

Cara melakukan ini secara teknis - kumpulkan metrik, dll. — Saya berbicara secara rinci dalam laporan tentang Pemantauan dan Kubernetes. Dan saran utama untuk memilih parameter optimal adalah percobaan!

Ada metode GUNAKAN (Saturasi dan Kesalahan Pemanfaatan), maksudnya adalah sebagai berikut. Atas dasar apa masuk akal untuk menskalakan, misalnya, php-fpm? Berdasarkan fakta bahwa pekerja hampir habis, hal ini terjadi pemanfaatan. Dan jika pekerja sudah habis dan koneksi baru tidak diterima, ini sudah terjadi kejenuhan. Kedua parameter ini harus diukur, dan bergantung pada nilainya, penskalaan harus dilakukan.

Alih-alih sebuah kesimpulan

Laporan ini memiliki kelanjutan: tentang penskalaan vertikal dan cara memilih sumber daya yang tepat. Saya akan membicarakan hal ini di video mendatang YouTube kami - berlangganan agar Anda tidak ketinggalan!

Video dan slide

Video dari pertunjukan (44 menit):

Penyajian laporan:

PS

Laporan lain tentang Kubernetes di blog kami:

Sumber: www.habr.com

Tambah komentar