Kubernetes: Percepatkan perkhidmatan anda dengan mengalih keluar had CPU

Kembali pada tahun 2016 kami di Buffer bertukar kepada Kubernetes, dan kini kira-kira 60 nod (pada AWS) dan 1500 kontena sedang bekerja pada kluster k8 kami yang diuruskan oleh tendang. Walau bagaimanapun, kami berpindah ke perkhidmatan mikro melalui percubaan dan kesilapan, dan walaupun selepas beberapa tahun bekerja dengan k8, kami masih berhadapan dengan masalah baharu. Dalam entri ini kita akan bercakap tentang had pemproses: mengapa kami fikir mereka adalah amalan yang baik dan mengapa mereka akhirnya tidak begitu baik.

Had pemproses dan pendikit

Seperti ramai pengguna Kubernetes lain, Google sangat mengesyorkan menetapkan had CPU. Tanpa tetapan sedemikian, bekas dalam nod boleh mengambil semua kuasa pemproses, yang seterusnya menyebabkan proses Kubernetes yang penting (contohnya kubelet) akan berhenti bertindak balas terhadap permintaan. Oleh itu, menetapkan had CPU ialah cara yang baik untuk melindungi nod anda.

Had pemproses menetapkan bekas kepada masa CPU maksimum yang boleh digunakan untuk tempoh tertentu (lalai ialah 100ms), dan bekas itu tidak akan melebihi had ini. Dalam Kubernetes untuk pendikit bekas dan mengelakkannya daripada melebihi had, alat khas digunakan Kuota CFS, tetapi had CPU tiruan ini akhirnya menjejaskan prestasi dan meningkatkan masa tindak balas bekas anda.

Apakah yang boleh berlaku jika kita tidak menetapkan had pemproses?

Malangnya, kami sendiri terpaksa menghadapi masalah ini. Setiap nod mempunyai proses yang bertanggungjawab untuk menguruskan bekas kubelet, dan dia berhenti menjawab permintaan. Nod, apabila ini berlaku, akan masuk ke dalam keadaan NotReady, dan bekas daripadanya akan diubah hala ke tempat lain dan mencipta masalah yang sama pada nod baharu. Bukan senario yang ideal, boleh dikatakan.

Manifestasi masalah pendikit dan tindak balas

Metrik utama untuk penjejakan kontena ialah trottling, ia menunjukkan berapa kali bekas anda telah didikit. Kami melihat dengan penuh minat kehadiran pendikitan dalam beberapa bekas, tidak kira sama ada beban pemproses adalah melampau atau tidak. Sebagai contoh, mari kita lihat salah satu API utama kami:

Kubernetes: Percepatkan perkhidmatan anda dengan mengalih keluar had CPU

Seperti yang anda lihat di bawah, kami telah menetapkan had kepada 800m (0.8 atau 80% teras), dan nilai puncak pada capaian terbaik 200m (20% teras). Nampaknya sebelum mengecilkan perkhidmatan kami masih mempunyai banyak kuasa pemproses, namun...

Kubernetes: Percepatkan perkhidmatan anda dengan mengalih keluar had CPU
Anda mungkin perasan bahawa walaupun beban pemproses berada di bawah had yang ditentukan - jauh di bawah - pendikitan masih berlaku.

Menghadapi ini, kami tidak lama lagi menemui beberapa sumber (masalah pada github, pembentangan pada zadano, siarkan di omio) tentang penurunan prestasi dan masa tindak balas perkhidmatan akibat pendikit.

Mengapa kita melihat pendikitan pada beban CPU yang rendah? Versi ringkasnya ialah: "terdapat pepijat dalam kernel Linux yang menyebabkan pendikitan bekas yang tidak perlu dengan had pemproses tertentu." Jika anda berminat dengan sifat masalah, anda boleh membaca pembentangan (video и teks pilihan) oleh Dave Chiluk.

Mengeluarkan sekatan CPU (dengan sangat berhati-hati)

Selepas perbincangan yang panjang, kami memutuskan untuk mengalih keluar sekatan pemproses daripada semua perkhidmatan yang secara langsung atau tidak langsung menjejaskan fungsi kritikal untuk pengguna kami.

Keputusan itu tidak mudah kerana kami sangat menghargai kestabilan kluster kami. Pada masa lalu, kami telah pun bereksperimen dengan ketidakstabilan kluster kami, dan kemudian perkhidmatan menggunakan terlalu banyak sumber dan memperlahankan kerja keseluruhan nod mereka. Kini segala-galanya agak berbeza: kami mempunyai pemahaman yang jelas tentang apa yang kami jangkakan daripada kelompok kami, serta strategi yang baik untuk melaksanakan perubahan yang dirancang.

Kubernetes: Percepatkan perkhidmatan anda dengan mengalih keluar had CPU
Surat-menyurat perniagaan mengenai isu yang mendesak.

Bagaimana untuk melindungi nod anda apabila sekatan ditarik balik?

Pengasingan perkhidmatan "tidak terhad":

Pada masa lalu, kita telah melihat beberapa nod masuk ke dalam keadaan notReady, terutamanya disebabkan oleh perkhidmatan yang menggunakan terlalu banyak sumber.

Kami memutuskan untuk meletakkan perkhidmatan sedemikian dalam nod berasingan (“berlabel”) supaya ia tidak mengganggu perkhidmatan “berkaitan”. Akibatnya, dengan menandai beberapa nod dan menambah parameter toleransi kepada perkhidmatan "tidak berkaitan", kami mencapai kawalan yang lebih besar ke atas kluster, dan menjadi lebih mudah bagi kami untuk mengenal pasti masalah dengan nod. Untuk menjalankan proses yang sama sendiri, anda boleh membiasakan diri anda dokumentasi.

Kubernetes: Percepatkan perkhidmatan anda dengan mengalih keluar had CPU

Menetapkan permintaan pemproses dan memori yang betul:

Ketakutan terbesar kami ialah proses itu akan menggunakan terlalu banyak sumber dan nod akan berhenti bertindak balas kepada permintaan. Sejak sekarang (terima kasih kepada Datadog) kami dapat memantau dengan jelas semua perkhidmatan pada kluster kami, saya menganalisis beberapa bulan operasi perkhidmatan yang kami rancang untuk tetapkan sebagai "tidak berkaitan". Saya hanya menetapkan penggunaan CPU maksimum dengan margin 20%, dan dengan itu memperuntukkan ruang dalam nod sekiranya k8s cuba memberikan perkhidmatan lain kepada nod.

Kubernetes: Percepatkan perkhidmatan anda dengan mengalih keluar had CPU

Seperti yang anda lihat dalam graf, beban maksimum pada pemproses telah dicapai 242m Teras CPU (teras pemproses 0.242). Untuk permintaan pemproses, cukup untuk mengambil nombor yang lebih besar sedikit daripada nilai ini. Sila ambil perhatian bahawa oleh kerana perkhidmatan adalah berpusatkan pengguna, nilai muatan puncak bertepatan dengan lalu lintas.

Lakukan perkara yang sama dengan penggunaan memori dan pertanyaan, dan voila - anda sudah bersedia! Untuk keselamatan yang lebih baik, anda boleh menambah penskalaan auto pod mendatar. Oleh itu, setiap kali beban sumber adalah tinggi, penskalaan automatik akan mencipta pod baharu dan kubernetes akan mengedarkannya ke nod dengan ruang kosong. Sekiranya tiada ruang yang tinggal dalam kluster itu sendiri, anda boleh menetapkan sendiri amaran atau mengkonfigurasi penambahan nod baharu melalui penskalaan automatiknya.

Daripada minus, perlu diperhatikan bahawa kami kalah dalam "ketumpatan bekas", iaitu. bilangan bekas yang berjalan pada satu nod. Kami juga mungkin mempunyai banyak "kelonggaran" pada ketumpatan trafik yang rendah, dan terdapat juga kemungkinan anda akan mencapai beban pemproses yang tinggi, tetapi nod penskalaan automatik harus membantu dengan yang terakhir.

Penemuan

Saya berbesar hati untuk menerbitkan hasil percubaan yang cemerlang ini sejak beberapa minggu lalu; kami telah melihat peningkatan yang ketara sebagai tindak balas merentas semua perkhidmatan yang diubah suai:

Kubernetes: Percepatkan perkhidmatan anda dengan mengalih keluar had CPU

Kami mencapai hasil terbaik di halaman utama kami (buffer.com), di sana perkhidmatan dipercepatkan dua puluh dua kali!

Kubernetes: Percepatkan perkhidmatan anda dengan mengalih keluar had CPU

Adakah pepijat kernel Linux diperbaiki?

Ya, Pepijat telah pun diperbaiki dan pembaikan telah ditambahkan pada kernel pengedaran versi 4.19 dan lebih tinggi.

Namun, apabila membaca masalah kubernetes pada github untuk kedua September 2020 kami masih menemui sebutan beberapa projek Linux dengan pepijat yang serupa. Saya percaya bahawa sesetengah pengedaran Linux masih mempunyai pepijat ini dan hanya berusaha untuk membetulkannya.

Jika versi pengedaran anda lebih rendah daripada 4.19, saya akan mengesyorkan anda mengemas kini kepada yang terkini, tetapi dalam apa jua keadaan anda harus cuba mengalih keluar sekatan pemproses dan lihat jika pendikitan berterusan. Di bawah anda boleh melihat senarai separa perkhidmatan pengurusan Kubernetes dan pengedaran Linux:

  • Debian: betulkan disepadukan ke dalam versi pengedaran terkini, Buster, dan kelihatan agak segar (Ogos 2020). Beberapa versi sebelumnya juga boleh diperbaiki.
  • Ubuntu: betulkan disepadukan ke dalam versi terkini Focal Fossa Ubuntu 20.04
  • EKS telah mendapat pembetulan lagi pada Disember 2019. Jika versi anda lebih rendah daripada ini, anda harus mengemas kini AMI.
  • kops: Mulai Jun 2020 у kops 1.18+ Imej hos utama ialah Ubuntu 20.04. Jika versi kops anda lebih lama, anda mungkin perlu menunggu untuk pembetulan. Kami sendiri sedang menunggu sekarang.
  • GKE (Google Cloud): Betulkan bersepadu pada Januari 2020, walau bagaimanapun terdapat masalah dengan pendikit masih diperhatikan.

Apakah yang perlu dilakukan jika pembetulan membetulkan masalah pendikit?

Saya tidak pasti masalah itu selesai sepenuhnya. Apabila kita sampai ke versi kernel dengan pembetulan, saya akan menguji kluster dan mengemas kini siaran. Jika sesiapa telah mengemas kini, saya berminat untuk membaca keputusan anda.

Kesimpulan

  • Jika anda bekerja dengan bekas Docker di bawah Linux (tidak kira Kubernetes, Mesos, Swarm atau lain-lain), bekas anda mungkin kehilangan prestasi akibat pendikit;
  • Cuba kemas kini kepada versi terbaharu pengedaran anda dengan harapan pepijat telah pun dibetulkan;
  • Mengeluarkan had pemproses akan menyelesaikan masalah, tetapi ini adalah teknik berbahaya yang harus digunakan dengan sangat berhati-hati (lebih baik untuk mengemas kini kernel dahulu dan membandingkan hasilnya);
  • Jika anda telah mengalih keluar had CPU, pantau dengan teliti penggunaan CPU dan memori anda dan pastikan sumber CPU anda melebihi penggunaan anda;
  • Pilihan yang selamat adalah dengan autoscale pod untuk mencipta pod baharu sekiranya beban perkakasan tinggi, supaya kubernetes menugaskannya kepada nod bebas.

Saya harap siaran ini membantu anda meningkatkan prestasi sistem kontena anda.

PS ia adalah penulis sepadan dengan pembaca dan pengulas (dalam bahasa Inggeris).


Sumber: www.habr.com

Tambah komen