Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

27 April di persidangan itu Mogok 2019, sebagai sebahagian daripada bahagian "DevOps", laporan "Penskalaan automatik dan pengurusan sumber dalam Kubernetes" telah diberikan. Ia bercakap tentang cara anda boleh menggunakan K8 untuk memastikan ketersediaan tinggi aplikasi anda dan memastikan prestasi puncak.

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Mengikut tradisi, kami berbesar hati untuk mempersembahkan video laporan tersebut (44 minit, lebih bermaklumat daripada artikel) dan ringkasan utama dalam bentuk teks. Pergi!

Mari analisa topik laporan perkataan demi perkataan dan mulakan dari akhir.

Kubernetes

Katakan kami mempunyai bekas Docker pada hos kami. Untuk apa? Untuk memastikan kebolehulangan dan pengasingan, yang seterusnya membolehkan penggunaan mudah dan baik, CI/CD. Kami mempunyai banyak kenderaan sedemikian dengan kontena.

Apakah yang Kubernetes sediakan dalam kes ini?

  1. Kami berhenti memikirkan mesin ini dan mula bekerja dengan "awan" kelompok bekas atau buah (kumpulan bekas).
  2. Lebih-lebih lagi, kami tidak memikirkan pod individu, tetapi mengurus lebih banyak lagiΠΎkumpulan yang lebih besar. begitu primitif peringkat tinggi benarkan kami mengatakan bahawa terdapat templat untuk menjalankan beban kerja tertentu, dan berikut ialah bilangan kejadian yang diperlukan untuk menjalankannya. Jika kami kemudian menukar templat, semua kejadian akan berubah.
  3. Dengan API perisytiharan Daripada melaksanakan urutan perintah tertentu, kami menerangkan "struktur dunia" (dalam YAML), yang dicipta oleh Kubernetes. Dan sekali lagi: apabila perihalan berubah, paparan sebenar juga akan berubah.

Pengurusan sumber

CPU

Mari kita jalankan nginx, php-fpm dan mysql pada pelayan. Perkhidmatan ini sebenarnya akan mempunyai lebih banyak proses yang sedang berjalan, setiap satunya memerlukan sumber pengkomputeran:

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)
(nombor pada slaid adalah "burung kakak tua", keperluan abstrak setiap proses untuk kuasa pengkomputeran)

Untuk menjadikannya lebih mudah untuk bekerja dengan ini, adalah logik untuk menggabungkan proses ke dalam kumpulan (contohnya, semua proses nginx menjadi satu kumpulan "nginx"). Cara yang mudah dan jelas untuk melakukan ini ialah meletakkan setiap kumpulan dalam bekas:

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Untuk meneruskan, anda perlu ingat apa itu bekas (dalam Linux). Penampilan mereka dimungkinkan terima kasih kepada tiga ciri utama dalam kernel, yang dilaksanakan agak lama dahulu: keupayaan, ruang nama ΠΈ kumpulan. Dan pembangunan selanjutnya difasilitasi oleh teknologi lain (termasuk "cangkang" yang mudah seperti Docker):

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Dalam konteks laporan, kami hanya berminat kumpulan, kerana kumpulan kawalan adalah sebahagian daripada kefungsian bekas (Docker, dsb.) yang melaksanakan pengurusan sumber. Proses yang digabungkan ke dalam kumpulan, seperti yang kami mahu, adalah kumpulan kawalan.

Mari kembali kepada keperluan CPU untuk proses ini, dan sekarang untuk kumpulan proses:

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)
(Saya ulangi bahawa semua nombor adalah ungkapan abstrak tentang keperluan sumber)

Pada masa yang sama, CPU itu sendiri mempunyai sumber terhingga tertentu (dalam contoh ini ialah 1000), yang mungkin kekurangan semua orang (jumlah keperluan semua kumpulan ialah 150+850+460=1460). Apa yang akan berlaku dalam kes ini?

Kernel mula mengagihkan sumber dan melakukannya "secara adil", memberikan jumlah sumber yang sama kepada setiap kumpulan. Tetapi dalam kes pertama, terdapat lebih banyak daripada yang diperlukan (333>150), jadi lebihan (333-150=183) kekal dalam simpanan, yang juga diagihkan sama rata antara dua bekas lain:

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Akibatnya: bekas pertama mempunyai sumber yang mencukupi, yang kedua - ia tidak mempunyai sumber yang mencukupi, yang ketiga - ia tidak mempunyai sumber yang mencukupi. Ini adalah hasil daripada tindakan penjadual "jujur" dalam Linux - CFS. Operasinya boleh dilaraskan menggunakan tugasan berat setiap bekas. Sebagai contoh, seperti ini:

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Mari kita lihat kes kekurangan sumber dalam bekas kedua (php-fpm). Semua sumber kontena diagihkan sama rata antara proses. Akibatnya, proses induk berfungsi dengan baik, tetapi semua pekerja perlahan, menerima kurang daripada separuh daripada apa yang mereka perlukan:

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Beginilah cara penjadual CFS berfungsi. Kami akan memanggil pemberat yang kami tetapkan kepada bekas permintaan. Mengapa ini begitu - lihat lebih lanjut.

Mari kita lihat keseluruhan keadaan dari sisi lain. Seperti yang anda tahu, semua jalan menuju ke Rom, dan dalam kes komputer, ke CPU. Satu CPU, banyak tugas - anda memerlukan lampu isyarat. Cara paling mudah untuk mengurus sumber ialah "lampu isyarat": mereka memberikan satu proses masa akses tetap kepada CPU, kemudian yang seterusnya, dsb.

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Pendekatan ini dipanggil kuota keras (had keras). Mari kita ingat ia hanya sebagai had. Walau bagaimanapun, jika anda mengedarkan had kepada semua bekas, masalah timbul: mysql sedang memandu di sepanjang jalan dan pada satu ketika keperluannya untuk CPU berakhir, tetapi semua proses lain terpaksa menunggu sehingga CPU terbiar.

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Mari kembali ke kernel Linux dan interaksinya dengan CPU - gambaran keseluruhan adalah seperti berikut:

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

cgroup mempunyai dua tetapan - pada dasarnya ini adalah dua "putaran" mudah yang membolehkan anda menentukan:

  1. berat untuk bekas (permintaan) ialah saham;
  2. peratusan jumlah masa CPU untuk mengerjakan tugas kontena (had) adalah kuota.

Bagaimana untuk mengukur CPU?

Terdapat cara yang berbeza:

  1. Apakah burung kakak tua, tiada siapa yang tahu - anda perlu berunding setiap masa.
  2. Faedah lebih jelas, tetapi relatif: 50% pelayan dengan 4 teras dan dengan 20 teras adalah perkara yang sama sekali berbeza.
  3. Anda boleh menggunakan yang telah disebutkan berat, yang Linux tahu, tetapi ia juga relatif.
  4. Pilihan yang paling mencukupi adalah untuk mengukur sumber pengkomputeran dalam detik. Itu. dalam saat masa pemproses berbanding saat masa nyata: 1 saat masa pemproses diberikan setiap 1 saat nyata - ini adalah satu keseluruhan teras CPU.

Untuk menjadikannya lebih mudah untuk bercakap, mereka mula mengukur secara langsung biji, bermakna oleh mereka masa CPU yang sama berbanding dengan yang sebenar. Memandangkan Linux memahami berat, tetapi tidak begitu banyak masa/teras CPU, mekanisme diperlukan untuk menterjemah dari satu ke yang lain.

Mari kita pertimbangkan contoh mudah dengan pelayan dengan 3 teras CPU, di mana tiga pod akan diberi pemberat (500, 1000 dan 1500) yang mudah ditukar kepada bahagian teras yang sepadan yang diperuntukkan kepada mereka (0,5, 1 dan 1,5).

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Jika anda mengambil pelayan kedua, di mana terdapat dua kali lebih banyak teras (6), dan meletakkan pod yang sama di sana, pengagihan teras boleh dikira dengan mudah dengan hanya mendarab dengan 2 (1, 2 dan 3, masing-masing). Tetapi detik penting berlaku apabila pod keempat muncul pada pelayan ini, yang beratnya, untuk kemudahan, ialah 3000. Ia menghilangkan sebahagian daripada sumber CPU (separuh teras), dan untuk pod yang tinggal ia dikira semula (dibelah dua):

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Kubernet dan sumber CPU

Dalam Kubernetes, sumber CPU biasanya diukur dalam milliadrax, iaitu 0,001 teras diambil sebagai berat asas. (Perkara yang sama dalam terminologi Linux/cgroups dipanggil bahagian CPU, walaupun, lebih tepat lagi, 1000 milicores = 1024 bahagian CPU.) K8s memastikan bahawa ia tidak meletakkan lebih banyak pod pada pelayan daripada sumber CPU untuk jumlah berat semua pod.

Bagaimana ini berlaku? Apabila anda menambah pelayan pada kluster Kubernetes, dilaporkan bilangan teras CPU yang tersedia. Dan apabila mencipta pod baharu, penjadual Kubernetes mengetahui berapa banyak teras yang diperlukan oleh pod ini. Oleh itu, pod akan diberikan kepada pelayan yang mempunyai teras yang mencukupi.

Apakah yang akan berlaku sekiranya tiada permintaan ditentukan (iaitu pod tidak mempunyai bilangan teras tertentu yang diperlukannya)? Mari kita fikirkan cara Kubernetes biasanya mengira sumber.

Untuk pod anda boleh menentukan kedua-dua permintaan (penjadual CFS) dan had (ingat lampu isyarat?):

  • Jika ia dinyatakan sama, maka pod diberikan kelas QoS dijamin. Bilangan teras ini sentiasa tersedia untuknya dijamin.
  • Jika permintaan kurang daripada had - kelas QoS boleh pecah. Itu. Kami menjangkakan pod, sebagai contoh, sentiasa menggunakan 1 teras, tetapi nilai ini bukan pengehadan untuknya: kadang-kadang pod boleh menggunakan lebih banyak (apabila pelayan mempunyai sumber percuma untuk ini).
  • Terdapat juga kelas QoS usaha terbaik β€” ia termasuk pod yang permintaannya tidak dinyatakan. Sumber diberikan kepada mereka yang terakhir.

memori

Dengan ingatan, keadaannya serupa, tetapi sedikit berbeza - lagipun, sifat sumber ini berbeza. Secara umum, analoginya adalah seperti berikut:

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Mari lihat bagaimana permintaan dilaksanakan dalam ingatan. Biarkan pod hidup di pelayan, menukar penggunaan memori, sehingga salah satu daripadanya menjadi begitu besar sehingga ia kehabisan memori. Dalam kes ini, pembunuh OOM muncul dan membunuh proses terbesar:

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Ini tidak selalunya sesuai dengan kita, jadi adalah mungkin untuk mengawal selia proses mana yang penting kepada kita dan tidak boleh dibunuh. Untuk melakukan ini, gunakan parameter oom_skor_adj.

Mari kembali ke kelas QoS CPU dan lukiskan analogi dengan nilai oom_score_adj yang menentukan keutamaan penggunaan memori untuk pod:

  • Nilai oom_score_adj terendah untuk pod - -998 - bermakna pod sedemikian harus dibunuh terakhir, ini dijamin.
  • Yang tertinggi - 1000 - ialah usaha terbaik, buah sebegitu dibunuh terlebih dahulu.
  • Untuk mengira nilai yang tinggal (boleh pecah) terdapat formula, intipatinya berpunca daripada fakta bahawa lebih banyak sumber yang diminta oleh pod, semakin kecil kemungkinan ia akan dibunuh.

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

"Twist" kedua - had_dalam_bait - untuk had. Dengan itu, semuanya lebih mudah: kami hanya menetapkan jumlah maksimum memori yang dikeluarkan, dan di sini (tidak seperti CPU) tidak ada persoalan tentang cara mengukurnya (memori).

Dalam jumlah

Setiap pod dalam Kubernetes diberikan requests ΠΈ limits - kedua-dua parameter untuk CPU dan memori:

  1. berdasarkan permintaan, penjadual Kubernetes berfungsi, yang mengedarkan pod antara pelayan;
  2. berdasarkan semua parameter, kelas QoS pod ditentukan;
  3. Berat relatif dikira berdasarkan permintaan CPU;
  4. penjadual CFS dikonfigurasikan berdasarkan permintaan CPU;
  5. Pembunuh OOM dikonfigurasikan berdasarkan permintaan memori;
  6. "lampu isyarat" dikonfigurasikan berdasarkan had CPU;
  7. Berdasarkan had ingatan, had dikonfigurasikan untuk cgroup.

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Secara umum, gambar ini menjawab semua soalan tentang bagaimana bahagian utama pengurusan sumber berlaku dalam Kubernetes.

Autoscaling

K8s cluster-autoscaler

Mari bayangkan bahawa keseluruhan kluster sudah diduduki dan pod baharu perlu dibuat. Walaupun pod tidak boleh muncul, ia tergantung dalam status Menunggu. Untuk ia muncul, kita boleh menyambungkan pelayan baharu ke kluster atau... pasang cluster-autoscaler, yang akan melakukannya untuk kita: pesan mesin maya daripada pembekal awan (menggunakan permintaan API) dan sambungkannya ke kluster , selepas itu pod akan ditambah .

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Ini ialah penskalaan automatik bagi gugusan Kubernetes, yang berfungsi dengan baik (mengikut pengalaman kami). Walau bagaimanapun, seperti di tempat lain, terdapat beberapa nuansa di sini...

Selagi kami meningkatkan saiz kluster, semuanya baik-baik saja, tetapi apa yang berlaku apabila kluster mula membebaskan dirinya? Masalahnya ialah memindahkan pod (untuk membebaskan hos) secara teknikalnya sukar dan mahal dari segi sumber. Kubernetes menggunakan pendekatan yang sama sekali berbeza.

Pertimbangkan kumpulan 3 pelayan yang mempunyai Deployment. Ia mempunyai 6 pod: kini terdapat 2 untuk setiap pelayan. Atas sebab tertentu kami ingin mematikan salah satu pelayan. Untuk melakukan ini, kami akan menggunakan arahan kubectl drain, yang:

  • akan melarang menghantar pod baharu ke pelayan ini;
  • akan memadam pod sedia ada pada pelayan.

Oleh kerana Kubernetes bertanggungjawab untuk mengekalkan bilangan pod (6), ia hanya akan mencipta semula mereka pada nod lain, tetapi bukan pada nod yang dilumpuhkan, kerana ia sudah ditandai sebagai tidak tersedia untuk mengehos pod baharu. Ini adalah mekanik asas untuk Kubernetes.

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Walau bagaimanapun, terdapat nuansa di sini juga. Dalam situasi yang sama, untuk StatefulSet (bukannya Deployment), tindakan akan berbeza. Sekarang kita sudah mempunyai aplikasi stateful - contohnya, tiga pod dengan MongoDB, satu daripadanya mempunyai beberapa jenis masalah (data telah rosak atau ralat lain yang menghalang pod daripada bermula dengan betul). Dan kami sekali lagi memutuskan untuk melumpuhkan satu pelayan. Apa yang akan berlaku?

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

MongoDB boleh mati kerana ia memerlukan kuorum: untuk sekumpulan tiga pemasangan, sekurang-kurangnya dua mesti berfungsi. Walau bagaimanapun, ini tidak berlaku - terima kasih kepada PodDisruptionBudget. Parameter ini menentukan bilangan minimum pod kerja yang diperlukan. Mengetahui bahawa salah satu pod MongoDB tidak lagi berfungsi dan melihat bahawa PodDisruptionBudget ditetapkan untuk MongoDB minAvailable: 2, Kubernetes tidak akan membenarkan anda memadamkan pod.

Intinya: agar pergerakan (dan sebenarnya, penciptaan semula) pod berfungsi dengan betul apabila kluster dikeluarkan, adalah perlu untuk mengkonfigurasi PodDisruptionBudget.

Skala mendatar

Mari kita pertimbangkan situasi lain. Terdapat aplikasi berjalan sebagai Deployment dalam Kubernetes. Trafik pengguna datang ke podnya (contohnya, terdapat tiga daripadanya), dan kami mengukur penunjuk tertentu di dalamnya (katakan, beban CPU). Apabila beban meningkat, kami merekodkannya pada jadual dan menambah bilangan pod untuk mengedarkan permintaan.

Hari ini di Kubernetes ini tidak perlu dilakukan secara manual: peningkatan/penurunan automatik dalam bilangan pod dikonfigurasikan bergantung pada nilai penunjuk beban yang diukur.

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Soalan utama di sini ialah: apa sebenarnya yang hendak diukur ΠΈ bagaimana untuk mentafsir nilai yang diperolehi (untuk membuat keputusan untuk menukar bilangan pod). Anda boleh mengukur banyak:

Autoscaling dan pengurusan sumber dalam Kubernetes (gambaran keseluruhan dan laporan video)

Cara melakukan ini secara teknikal - kumpulkan metrik, dsb. β€” Saya bercakap secara terperinci dalam laporan tentang Pemantauan dan Kubernetes. Dan nasihat utama untuk memilih parameter optimum ialah eksperimen!

Terdapat GUNAKAN kaedah (Tepu Penggunaan dan Ralat), maksudnya adalah seperti berikut. Atas dasar apakah ia masuk akal untuk skala, sebagai contoh, php-fpm? Berdasarkan fakta bahawa pekerja kehabisan, ini adalah penggunaan. Dan jika pekerja sudah tamat dan sambungan baru tidak diterima, ini sudah pun tepu. Kedua-dua parameter ini mesti diukur, dan bergantung pada nilai, penskalaan mesti dijalankan.

Daripada kesimpulan

Laporan ini mempunyai sambungan: tentang penskalaan menegak dan cara memilih sumber yang betul. Saya akan bercakap tentang ini dalam video akan datang pada YouTube kami - langgan supaya anda tidak ketinggalan!

Video dan slaid

Video daripada persembahan (44 minit):

Pembentangan laporan:

PS

Laporan lain tentang Kubernetes di blog kami:

Sumber: www.habr.com

Tambah komen