Kubernetes: Percepat layanan Anda dengan menghilangkan batasan CPU

Kembali pada tahun 2016 kami di Buffer beralih ke Kubernetes, dan sekarang sekitar 60 node (di AWS) dan 1500 kontainer sedang bekerja di cluster k8s kami yang dikelola oleh tendangan. Namun, kami beralih ke layanan mikro melalui trial and error, dan bahkan setelah beberapa tahun bekerja dengan k8s kami masih menghadapi masalah baru. Pada postingan kali ini kita akan membahasnya keterbatasan prosesor: mengapa kami menganggapnya sebagai praktik yang baik dan mengapa pada akhirnya tidak begitu baik.

Keterbatasan dan pembatasan prosesor

Seperti banyak pengguna Kubernetes lainnya, Google sangat menyarankan untuk menetapkan batas CPU. Tanpa pengaturan seperti itu, container dalam sebuah node dapat menghabiskan seluruh daya prosesor, yang pada gilirannya menyebabkan proses-proses penting Kubernetes (misalnya kubelet) akan berhenti menanggapi permintaan. Oleh karena itu, menetapkan batas CPU adalah cara yang baik untuk melindungi node Anda.

Batas prosesor menetapkan container ke waktu CPU maksimum yang dapat digunakan untuk jangka waktu tertentu (defaultnya adalah 100 md), dan container tidak akan pernah melebihi batas ini. Di Kubernetes untuk pembatasan wadah dan mencegahnya melebihi batas, digunakan alat khusus Kuota CFS, namun batasan CPU buatan ini pada akhirnya mengganggu kinerja dan meningkatkan waktu respons container Anda.

Apa yang terjadi jika kita tidak menetapkan batasan prosesor?

Sayangnya, kami sendiri yang harus menghadapi masalah ini. Setiap node memiliki proses yang bertanggung jawab untuk mengelola container kubelet, dan dia berhenti menanggapi permintaan. Node, ketika ini terjadi, akan masuk ke dalam keadaan NotReady, dan kontainer darinya akan dialihkan ke tempat lain dan menimbulkan masalah yang sama pada node baru. Setidaknya ini bukanlah skenario yang ideal.

Manifestasi dari masalah pelambatan dan respon

Metrik utama untuk pelacakan kontainer adalah trottling, ini menunjukkan berapa kali kontainer Anda telah dibatasi. Kami memperhatikan dengan penuh minat adanya pelambatan di beberapa container, terlepas dari apakah beban prosesornya ekstrem atau tidak. Sebagai contoh, mari kita lihat salah satu API utama kami:

Kubernetes: Percepat layanan Anda dengan menghilangkan batasan CPU

Seperti yang Anda lihat di bawah, kami telah menetapkan batasnya 800m (0.8 atau 80% inti), dan nilai puncak pada jangkauan terbaik 200m (20% inti). Tampaknya sebelum membatasi layanan, kami masih memiliki banyak kekuatan prosesor, namun...

Kubernetes: Percepat layanan Anda dengan menghilangkan batasan CPU
Anda mungkin telah memperhatikan bahwa meskipun beban prosesor berada di bawah batas yang ditentukan - jauh di bawah - pembatasan masih terjadi.

Menghadapi hal ini, kami segera menemukan beberapa sumber (masalah di github, presentasi di zadano, posting di omio) tentang penurunan kinerja dan waktu respons layanan karena pembatasan.

Mengapa kita melihat pembatasan pada beban CPU rendah? Versi singkatnya adalah: “ada bug di kernel Linux yang menyebabkan pembatasan yang tidak perlu pada container dengan batas prosesor yang ditentukan.” Jika Anda tertarik dengan sifat masalahnya, Anda dapat membaca presentasinya (Video и teks pilihan) oleh Dave Chiluk.

Menghapus batasan CPU (dengan sangat hati-hati)

Setelah berdiskusi panjang lebar, kami memutuskan untuk menghapus pembatasan prosesor dari semua layanan yang secara langsung atau tidak langsung memengaruhi fungsi penting bagi pengguna kami.

Keputusan ini tidak mudah karena kami sangat menghargai stabilitas cluster kami. Di masa lalu, kami telah bereksperimen dengan ketidakstabilan cluster kami, dan kemudian layanan menghabiskan terlalu banyak sumber daya dan memperlambat seluruh node mereka. Sekarang semuanya agak berbeda: kami memiliki pemahaman yang jelas tentang apa yang kami harapkan dari cluster kami, serta strategi yang baik untuk mengimplementasikan perubahan yang direncanakan.

Kubernetes: Percepat layanan Anda dengan menghilangkan batasan CPU
Korespondensi bisnis tentang masalah mendesak.

Bagaimana cara melindungi node Anda ketika pembatasan dicabut?

Isolasi layanan “tidak terbatas”:

Di masa lalu, kita telah melihat beberapa node masuk ke dalam suatu keadaan notReady, terutama disebabkan oleh layanan yang menghabiskan terlalu banyak sumber daya.

Kami memutuskan untuk menempatkan layanan tersebut di node terpisah (“berlabel”) sehingga tidak mengganggu layanan “terkait”. Hasilnya, dengan menandai beberapa node dan menambahkan parameter toleransi ke layanan yang “tidak terkait”, kami mendapatkan kontrol yang lebih besar terhadap cluster, dan menjadi lebih mudah bagi kami untuk mengidentifikasi masalah dengan node. Untuk melakukan sendiri proses serupa, Anda dapat membiasakan diri dengannya dokumentasi.

Kubernetes: Percepat layanan Anda dengan menghilangkan batasan CPU

Menetapkan permintaan prosesor dan memori yang benar:

Ketakutan terbesar kami adalah proses tersebut akan menghabiskan terlalu banyak sumber daya dan node akan berhenti merespons permintaan. Karena sekarang (berkat Datadog) kami dapat memantau dengan jelas semua layanan di cluster kami, saya menganalisis beberapa bulan pengoperasian layanan yang kami rencanakan untuk ditetapkan sebagai "tidak terkait". Saya cukup mengatur penggunaan CPU maksimum dengan margin 20%, dan dengan demikian mengalokasikan ruang di node jika k8s mencoba menetapkan layanan lain ke node.

Kubernetes: Percepat layanan Anda dengan menghilangkan batasan CPU

Seperti yang Anda lihat pada grafik, beban maksimum pada prosesor telah tercapai 242m Inti CPU (inti prosesor 0.242). Untuk permintaan prosesor, cukup mengambil angka yang sedikit lebih besar dari nilai ini. Harap dicatat bahwa karena layanan ini berpusat pada pengguna, nilai beban puncak bertepatan dengan lalu lintas.

Lakukan hal yang sama dengan penggunaan memori dan kueri, dan voila - Anda sudah siap! Untuk keamanan yang lebih baik, Anda dapat menambahkan penskalaan otomatis pod horizontal. Jadi, setiap kali beban sumber daya tinggi, penskalaan otomatis akan membuat pod baru, dan kubernetes akan mendistribusikannya ke node yang memiliki ruang kosong. Jika tidak ada ruang tersisa di cluster itu sendiri, Anda dapat mengatur peringatan sendiri atau mengonfigurasi penambahan node baru melalui penskalaan otomatisnya.

Dari kekurangannya, perlu dicatat bahwa kami kalah dalam “kepadatan kontainer", yaitu jumlah kontainer yang berjalan pada satu node. Kami mungkin juga mengalami banyak “relaksasi” pada kepadatan lalu lintas yang rendah, dan ada juga kemungkinan Anda akan mencapai beban prosesor yang tinggi, tetapi node penskalaan otomatis akan membantu mengatasi hal tersebut.

Temuan

Saya senang untuk mempublikasikan hasil luar biasa ini dari eksperimen selama beberapa minggu terakhir; kami telah melihat peningkatan yang signifikan dalam respons di semua layanan yang dimodifikasi:

Kubernetes: Percepat layanan Anda dengan menghilangkan batasan CPU

Kami mencapai hasil terbaik di beranda kami (buffer.com), di sana layanan dipercepat dua puluh dua kali!

Kubernetes: Percepat layanan Anda dengan menghilangkan batasan CPU

Apakah bug kernel Linux telah diperbaiki?

Iya Nih, Bug telah diperbaiki dan perbaikan telah ditambahkan ke kernel distribusi versi 4.19 dan lebih tinggi.

Namun, setelah membaca masalah kubernetes di github untuk tanggal 2020 September XNUMX kami masih menemukan penyebutan beberapa proyek Linux dengan bug serupa. Saya yakin beberapa distribusi Linux masih memiliki bug ini dan sedang berupaya memperbaikinya.

Jika versi distribusi Anda lebih rendah dari 4.19, saya akan merekomendasikan memperbarui ke yang terbaru, tetapi bagaimanapun juga, Anda harus mencoba menghilangkan batasan prosesor dan melihat apakah pembatasan masih berlanjut. Di bawah ini Anda dapat melihat sebagian daftar layanan manajemen Kubernetes dan distribusi Linux:

  • Debian: perbaikan terintegrasi ke dalam distribusi versi terbaru, buster, dan terlihat cukup segar (Agustus 2020). Beberapa versi sebelumnya mungkin juga diperbaiki.
  • Ubuntu: perbaikan terintegrasi ke dalam versi terbaru Fossa Fokus Ubuntu 20.04
  • EKS sudah mendapatkan perbaikan pada bulan Desember 2019. Jika versi Anda lebih rendah dari ini, Anda harus memperbarui AMI.
  • polisi: Mulai Juni 2020 у kops 1.18+ Gambar host utama adalah Ubuntu 20.04. Jika versi kops Anda lebih lama, Anda mungkin harus menunggu perbaikan. Kami sendiri sedang menunggu sekarang.
  • GKE (Google Cloud): Perbaikan terintegrasi pada bulan Januari 2020, namun ada masalah dengan pembatasan masih diamati.

Apa yang harus dilakukan jika perbaikan telah memperbaiki masalah pembatasan?

Saya tidak yakin masalahnya sudah teratasi sepenuhnya. Ketika kita mendapatkan versi kernel dengan perbaikannya, saya akan menguji cluster dan memperbarui postingan. Jika ada yang sudah memperbarui, saya tertarik membaca hasil Anda.

Kesimpulan

  • Jika Anda bekerja dengan container Docker di Linux (tidak peduli Kubernetes, Mesos, Swarm, atau lainnya), container Anda mungkin kehilangan kinerja karena pembatasan;
  • Coba perbarui ke versi terbaru distribusi Anda dengan harapan bug telah diperbaiki;
  • Menghapus batasan prosesor akan menyelesaikan masalah, tetapi ini adalah teknik berbahaya yang harus digunakan dengan sangat hati-hati (lebih baik memperbarui kernel terlebih dahulu dan membandingkan hasilnya);
  • Jika Anda telah menghapus batas CPU, pantau penggunaan CPU dan memori Anda dengan cermat dan pastikan sumber daya CPU Anda melebihi konsumsi Anda;
  • Pilihan yang aman adalah melakukan penskalaan otomatis pada pod untuk membuat pod baru jika beban perangkat keras tinggi, sehingga kubernetes menugaskannya ke node bebas.

Saya harap postingan ini membantu Anda meningkatkan kinerja sistem kontainer Anda.

PS Di sini penulis berkorespondensi dengan pembaca dan komentator (dalam bahasa Inggris).


Sumber: www.habr.com

Tambah komentar