Persyaratan untuk mengembangkan aplikasi di Kubernetes

Hari ini saya berencana untuk berbicara tentang cara menulis aplikasi dan apa saja persyaratan agar aplikasi Anda dapat berfungsi dengan baik di Kubernetes. Sehingga tidak ada sakit kepala dengan aplikasi ini, sehingga Anda tidak perlu menemukan dan membangun “celah” apa pun di sekitarnya - dan semuanya berjalan sesuai keinginan Kubernetes.

Kuliah ini adalah bagian dari "Sekolah Malam Slurm di Kubernetes" Anda dapat melihat kuliah teori terbuka di Sekolah Malam di Youtube, dikelompokkan ke dalam playlist. Bagi yang lebih menyukai teks daripada video, artikel ini telah kami siapkan.

Nama saya Pavel Selivanov, saat ini saya adalah insinyur DevOps terkemuka di Mail.ru Cloud Solutions, kami membuat cloud, kami membuat kubernet manajemen, dan sebagainya. Tugas saya sekarang mencakup bantuan dalam pengembangan, meluncurkan cloud ini, meluncurkan aplikasi yang kami tulis, dan secara langsung mengembangkan alat yang kami sediakan untuk pengguna kami.

Persyaratan untuk mengembangkan aplikasi di Kubernetes

Saya telah melakukan DevOps, mungkin selama tiga tahun terakhir. Namun, pada prinsipnya, saya mungkin telah melakukan apa yang dilakukan DevOps sekitar lima tahun sekarang. Sebelumnya, saya lebih banyak terlibat dalam urusan admin. Saya mulai bekerja dengan Kubernetes sejak lama - mungkin sekitar empat tahun telah berlalu sejak saya mulai mengerjakannya.

Secara umum, saya memulainya ketika Kubernetes masih versi 1.3, dan mungkin 1.2 - ketika masih dalam masa pertumbuhan. Sekarang ini sudah tidak lagi dalam tahap awal - dan jelas bahwa ada permintaan yang besar di pasar untuk para insinyur yang ingin dapat melakukan Kubernetes. Dan perusahaan memiliki permintaan yang sangat tinggi terhadap orang-orang seperti itu. Oleh karena itu, sebenarnya ceramah ini muncul.

Kalau kita bicara sesuai rencana yang akan saya bicarakan, tampilannya seperti ini, di dalam tanda kurung ada tertulis (TL;DR) - “terlalu panjang; jangan membaca". Presentasi saya hari ini akan terdiri dari daftar yang tak ada habisnya.

Persyaratan untuk mengembangkan aplikasi di Kubernetes

Sebenarnya, saya sendiri tidak suka presentasi seperti itu ketika dibuat, tetapi topiknya sedemikian rupa sehingga ketika saya mempersiapkan presentasi ini, saya tidak terlalu memikirkan bagaimana mengatur informasi ini secara berbeda.

Karena, pada umumnya, informasi ini adalah “ctrl+c, ctrl+v”, antara lain dari Wiki kami di bagian DevOps, di mana kami telah menulis persyaratan untuk pengembang: “teman-teman, agar kami meluncurkan aplikasi Anda di Kubernetes, seharusnya seperti ini."

Itu sebabnya presentasinya menjadi daftar yang sangat besar. Maaf. Saya akan berusaha menceritakannya sedetail mungkin agar tidak membosankan jika memungkinkan.

Apa yang akan kita lihat sekarang:

  • ini adalah, pertama, log (log aplikasi?), apa yang harus dilakukan dengannya di Kubernetes, apa yang harus dilakukan dengannya, apa yang seharusnya;
  • apa yang harus dilakukan dengan konfigurasi di Kubernetes, apa cara terbaik dan terburuk untuk mengkonfigurasi aplikasi untuk Kubernetes;
  • Mari kita bahas tentang pemeriksaan aksesibilitas secara umum, seperti apa tampilannya;
  • mari kita bicara tentang apa itu penutupan yang baik;
  • mari kita bicara tentang sumber daya lagi;
  • Mari kita bahas topik penyimpanan data sekali lagi;
  • dan di bagian akhir saya akan memberi tahu Anda apa istilah aplikasi cloud-native misterius ini. Cloudnativeness, sebagai kata sifat dari istilah ini.

Log

Saya sarankan memulai dengan log - di mana log ini perlu dimasukkan ke dalam Kubernetes. Sekarang Anda telah meluncurkan aplikasi di Kubernetes. Menurut klasik, aplikasi sebelumnya selalu menulis log di suatu tempat dalam sebuah file. Aplikasi buruk menulis log ke file di direktori home pengembang yang meluncurkan aplikasi. Aplikasi yang bagus menulis log ke file di suatu tempat /var/log.

Persyaratan untuk mengembangkan aplikasi di Kubernetes

Oleh karena itu, selanjutnya, administrator yang baik memiliki beberapa hal yang dikonfigurasi dalam infrastruktur mereka sehingga log ini dapat diputar - rsyslog yang sama, yang melihat log ini dan ketika sesuatu terjadi pada mereka, ada banyak dari mereka, itu membuat salinan cadangan, meletakkan log di sana , menghapus file lama, lebih dari seminggu, enam bulan, dan beberapa waktu lainnya. Secara teori, kita harus mempunyai ketentuan sehingga hanya karena aplikasi menulis log, ruang di server produksi (server tempur?) tidak habis. Dan karenanya, seluruh produksi tidak berhenti karena kayu gelondongan.

Ketika kita pindah ke dunia Kubernetes dan menjalankan hal yang sama di sana, hal pertama yang dapat Anda perhatikan adalah kenyataan bahwa orang-orang, saat mereka menulis log dalam sebuah file, terus menulisnya.

Ternyata jika kita berbicara tentang Kubernetes, tempat yang tepat untuk menulis log dari wadah buruh pelabuhan adalah dengan menuliskannya dari aplikasi ke apa yang disebut Stdout/Stderr, yaitu aliran keluaran standar sistem operasi, kesalahan standar keluaran. Ini adalah cara paling benar, paling sederhana dan paling logis untuk meletakkan log pada prinsipnya di Docker dan khususnya di Kubernetis. Karena jika aplikasi Anda menulis log ke Stdout/Stderr, maka Docker dan add-on Kuberneteslah yang memutuskan apa yang harus dilakukan dengan log tersebut. Docker secara default akan membuat file khususnya dalam format JSON.

Di sini muncul pertanyaan, apa yang akan Anda lakukan selanjutnya dengan log tersebut? Cara termudahnya jelas, kita punya kemampuan untuk melakukannya kubectl logs dan lihat log dari “pod” ini. Tapi, mungkin, ini bukan pilihan yang baik - ada hal lain yang perlu dilakukan dengan log.

Untuk saat ini, mari kita bicara pada saat yang sama, karena kita telah menyentuh topik log, tentang apa itu log seharusnya. Artinya, hal ini tidak berlaku secara langsung pada Kubernetes, namun saat kita mulai memikirkan tentang apa yang harus dilakukan dengan log, ada baiknya kita memikirkan hal ini juga.

Kami memerlukan semacam alat, dengan cara yang bersahabat, yang akan mengambil log yang dimasukkan oleh buruh pelabuhan kami ke dalam filenya dan mengirimkannya ke suatu tempat. Pada umumnya, kami biasanya meluncurkan beberapa jenis agen di dalam Kubernetes dalam bentuk DaemonSet - pengumpul log, yang hanya memberi tahu di mana lokasi log yang dikumpulkan Docker. Dan agen pengumpul ini hanya mengambilnya, bahkan mungkin menguraikannya, mungkin memperkayanya dengan beberapa informasi meta tambahan dan, pada akhirnya, mengirimkannya untuk disimpan di suatu tempat. Variasi sudah dimungkinkan di sana. Yang paling umum mungkin adalah Elasticsearch, tempat Anda dapat menyimpan log dan dengan mudah mengambilnya dari sana. Kemudian, menggunakan permintaan, menggunakan Kibana, misalnya, membuat grafik berdasarkan permintaan tersebut, membuat peringatan berdasarkan hal tersebut, dan seterusnya.

Ide yang paling penting, saya ingin mengulanginya lagi, adalah bahwa di dalam Docker, khususnya di dalam Kubernetes, menyimpan log Anda dalam sebuah file adalah ide yang sangat buruk.

Karena pertama, sulit untuk memasukkan log ke dalam container ke dalam file. Anda harus terlebih dahulu masuk ke dalam container, exec di sana, lalu melihat lognya. Poin berikutnya adalah jika Anda memiliki log dalam suatu file, maka container biasanya memiliki lingkungan minimalis dan tidak ada utilitas yang biasanya diperlukan untuk pekerjaan normal dengan log. Kubur, lihat, buka di editor teks. Momen berikutnya adalah ketika kita memiliki log dalam sebuah file di dalam sebuah container, jika container ini dihapus, maklum, log tersebut akan ikut mati. Oleh karena itu, setiap restart container berarti tidak ada lagi log. Sekali lagi, pilihan yang buruk.

Dan poin terakhir adalah di dalam container Anda biasanya memiliki aplikasi Anda sendiri dan hanya itu - biasanya ini adalah satu-satunya proses yang berjalan. Tidak ada pembicaraan sama sekali tentang proses apa pun yang akan memutar file dengan log Anda. Segera setelah log mulai ditulis ke file, ini berarti, permisi, kami akan mulai kehilangan server produksi. Karena, pertama, mereka sulit ditemukan, tidak ada yang melacaknya, ditambah lagi tidak ada yang mengontrolnya - oleh karena itu, file tersebut bertambah tanpa henti hingga ruang di server habis. Oleh karena itu, saya katakan lagi bahwa masuk ke Docker, khususnya di Kubernetes, ke suatu file adalah ide yang buruk.

Poin selanjutnya, di sini saya ingin membicarakan hal ini lagi - karena kita sedang menyentuh topik log, alangkah baiknya jika kita membicarakan tentang tampilan log agar nyaman untuk digunakan. Seperti yang saya katakan, topik ini tidak berhubungan langsung dengan Kubernetes, tetapi sangat berkaitan dengan topik DevOps. Tentang topik budaya pengembangan dan persahabatan antara dua departemen yang berbeda - Dev dan Ops, sehingga semua orang merasa nyaman.

Artinya, idealnya, saat ini, log harus ditulis dalam format JSON. Jika Anda memiliki aplikasi Anda sendiri yang tidak dapat dipahami, yang menulis log dalam format yang tidak dapat dipahami karena Anda memasukkan semacam cetakan atau semacamnya, maka inilah saatnya mencari semacam kerangka kerja di Google, semacam pembungkus yang memungkinkan Anda mengimplementasikan logging normal; aktifkan parameter logging di JSON di sana, karena JSON adalah format yang sederhana, penguraiannya sederhana.

Jika JSON Anda tidak berfungsi menurut beberapa kriteria, tidak ada yang tahu apa, setidaknya tulis log dalam format yang dapat diurai. Di sini, ada baiknya memikirkan fakta bahwa, misalnya, jika Anda menjalankan banyak container atau hanya memproses dengan nginx, dan masing-masing memiliki pengaturan logging sendiri, maka mungkin akan sangat merepotkan bagi Anda untuk melakukannya. menguraikannya. Karena untuk setiap instance nginx baru Anda perlu menulis parser Anda sendiri, karena mereka menulis log secara berbeda. Sekali lagi, mungkin ada baiknya memikirkan untuk memastikan bahwa semua instance nginx ini memiliki konfigurasi logging yang sama, dan menulis semua lognya dengan seragam. Hal yang sama berlaku untuk semua aplikasi.

Pada akhirnya, saya juga ingin menambahkan bahan bakar ke dalam api yang, idealnya, log format multi-baris harus dihindari. Masalahnya adalah, jika Anda pernah bekerja dengan pengumpul kayu gelondongan, kemungkinan besar Anda telah melihat apa yang mereka janjikan kepada Anda, bahwa mereka dapat bekerja dengan kayu gelondongan multi-baris, mengetahui cara mengumpulkannya, dan sebagainya. Faktanya, menurut saya, tidak ada satu pun kolektor saat ini yang dapat mengumpulkan log multi-baris secara normal, lengkap, dan tanpa kesalahan. Secara manusiawi, sehingga nyaman dan bebas dari kesalahan.

Persyaratan untuk mengembangkan aplikasi di Kubernetes

Namun pelacakan tumpukan selalu berupa log multi-baris dan cara menghindarinya. Pertanyaannya di sini adalah bahwa log adalah catatan suatu peristiwa, dan stactrace sebenarnya bukan log. Jika kami mengumpulkan log dan meletakkannya di suatu tempat di Elasticsearch dan kemudian menggambar grafik darinya, membuat beberapa laporan aktivitas pengguna di situs Anda, maka ketika Anda mendapatkan jejak tumpukan, itu berarti terjadi sesuatu yang tidak terduga, yaitu situasi yang tidak tertangani dalam aplikasi Anda. Dan masuk akal untuk secara otomatis mengunggah jejak tumpukan di suatu tempat ke dalam sistem yang dapat melacaknya.

Ini adalah perangkat lunak (Sentry yang sama) yang dibuat khusus untuk bekerja dengan pelacakan tumpukan. Itu dapat segera membuat tugas otomatis, menugaskannya kepada seseorang, memperingatkan ketika jejak jejak terjadi, mengelompokkan jejak jejak ini berdasarkan satu jenis, dan seterusnya. Pada prinsipnya, tidak masuk akal untuk berbicara tentang stactraces ketika kita berbicara tentang log, karena ini adalah hal yang berbeda dengan tujuan yang berbeda.

Konfigurasi

Selanjutnya kita berbicara tentang konfigurasi di Kubernetes: apa yang harus dilakukan dengannya dan bagaimana aplikasi di dalam Kubernetes harus dikonfigurasi. Secara umum, saya biasanya mengatakan bahwa Docker bukan tentang container. Semua orang tahu bahwa Docker adalah tentang container, bahkan mereka yang belum banyak bekerja dengan Docker. Saya ulangi, Docker bukan tentang container.

Docker, menurut saya, adalah tentang standar. Dan ada standar untuk hampir semua hal: standar untuk membangun aplikasi Anda, standar untuk menginstal aplikasi Anda.

Persyaratan untuk mengembangkan aplikasi di Kubernetes

Dan hal ini - kami pernah menggunakannya sebelumnya, hal ini menjadi sangat populer dengan munculnya container - hal ini disebut variabel ENV (lingkungan), yaitu variabel lingkungan yang ada di sistem operasi Anda. Ini biasanya merupakan cara ideal untuk mengonfigurasi aplikasi Anda, karena jika Anda memiliki aplikasi dalam JAVA, Python, Go, Perl, amit-amit, dan semuanya dapat membaca host database, pengguna database, variabel kata sandi database, maka itu ideal. Anda memiliki aplikasi dalam empat bahasa berbeda yang dikonfigurasi dalam paket database dengan cara yang sama. Tidak ada lagi konfigurasi yang berbeda.

Semuanya dapat dikonfigurasi menggunakan variabel ENV. Saat kita berbicara tentang Kubernetes, ada cara bagus untuk mendeklarasikan variabel ENV langsung di dalam Deployment. Oleh karena itu, jika kita berbicara tentang data rahasia, maka kita dapat segera memasukkan data rahasia dari variabel ENV (kata sandi ke database, dll.) menjadi rahasia, membuat cluster rahasia dan menunjukkan dalam deskripsi ENV di Deployment bahwa kita tidak mendeklarasikannya secara langsung nilai variabel ini, dan nilai variabel kata sandi database ini akan dibaca dari rahasianya. Ini adalah perilaku standar Kubernetes. Dan ini adalah opsi paling ideal untuk mengonfigurasi aplikasi Anda. Hanya pada tingkat kode, sekali lagi ini berlaku untuk pengembang. Jika Anda seorang DevOps, Anda dapat bertanya: “Teman-teman, tolong ajari aplikasi Anda membaca variabel lingkungan. Dan kita semua akan bahagia.”

Jika semua orang di perusahaan membaca variabel lingkungan dengan nama yang sama, itu bagus. Agar tidak terjadi ada yang menunggu database postgres, ada yang menunggu nama database, ada yang menunggu yang lain, ada pula yang menunggu semacam dbn, sehingga ada keseragaman.

Masalahnya muncul ketika Anda memiliki begitu banyak variabel lingkungan sehingga Anda baru saja membuka Deployment - dan ada lima ratus baris variabel lingkungan. Dalam hal ini, variabel lingkungan Anda sudah terlalu besar - dan Anda tidak perlu lagi menyiksa diri sendiri. Dalam hal ini, masuk akal untuk mulai menggunakan konfigurasi. Artinya, latih aplikasi Anda untuk menggunakan konfigurasi.

Satu-satunya pertanyaan adalah konfigurasinya tidak seperti yang Anda pikirkan. Config.pi bukanlah konfigurasi yang nyaman digunakan. Atau beberapa konfigurasi dalam format Anda sendiri, sebagai alternatif - ini juga bukan konfigurasi yang saya maksud.

Yang saya bicarakan adalah konfigurasi dalam format yang dapat diterima, yaitu standar yang paling populer sejauh ini adalah standar .yaml. Jelas cara bacanya, bisa dibaca manusia, jelas cara bacanya dari aplikasi.

Oleh karena itu, selain YAML, Anda juga dapat, misalnya, menggunakan JSON, penguraiannya sama nyamannya dengan YAML dalam hal membaca konfigurasi aplikasi dari sana. Hal ini terasa lebih merepotkan bagi orang untuk membaca. Anda dapat mencoba formatnya, ala ini. Cukup nyaman untuk dibaca, dari sudut pandang manusia, tetapi mungkin merepotkan untuk memprosesnya secara otomatis, dalam artian jika Anda ingin membuat konfigurasi sendiri, format ini mungkin sudah merepotkan untuk dibuat.

Namun bagaimanapun juga, format apa pun yang Anda pilih, intinya dari sudut pandang Kubernetes, format ini sangat nyaman. Anda dapat memasukkan seluruh konfigurasi Anda ke dalam Kubernetes, di ConfigMap. Dan kemudian ambil configmap ini dan minta untuk dipasang di dalam pod Anda di beberapa direktori tertentu, di mana aplikasi Anda akan membaca konfigurasi dari configmap ini seolah-olah itu hanya sebuah file. Faktanya, inilah hal yang baik untuk dilakukan ketika Anda memiliki banyak opsi konfigurasi di aplikasi Anda. Atau itu hanya semacam struktur yang rumit, ada yang bersarang.

Jika Anda memiliki configmap, maka Anda dapat mengajarkan aplikasi Anda dengan baik, misalnya, untuk secara otomatis melacak perubahan dalam file tempat configmap dipasang, dan juga secara otomatis memuat ulang aplikasi Anda ketika konfigurasi berubah. Ini umumnya merupakan pilihan ideal.

Sekali lagi, saya sudah membicarakan hal ini - informasi rahasia tidak ada di configmap, informasi rahasia tidak ada dalam variabel, informasi rahasia tidak ada dalam rahasia. Dari sana, hubungkan informasi rahasia ini dengan diplomasi. Biasanya kami menyimpan semua deskripsi objek Kubernetes, penerapan, peta konfigurasi, layanan di git. Oleh karena itu, memasukkan kata sandi ke database dalam git, meskipun itu adalah git Anda, yang Anda miliki secara internal di perusahaan, adalah ide yang buruk. Karena, minimal, git mengingat semuanya dan menghapus kata sandi dari sana tidaklah mudah.

Cek kesehatan

Poin berikutnya adalah yang namanya Pemeriksaan Kesehatan. Secara umum, pemeriksaan Kesehatan hanyalah memeriksa apakah aplikasi Anda berfungsi. Pada saat yang sama, kita paling sering berbicara tentang aplikasi web tertentu, yang karenanya, dari sudut pandang pemeriksaan kesehatan (lebih baik tidak menerjemahkan di sini dan lebih jauh) ini akan menjadi beberapa URL khusus, yang mereka proses sebagai standar, biasanya mereka melakukannya /health.

Oleh karena itu, saat mengakses URL ini, aplikasi kita mengatakan "ya, oke, semuanya baik-baik saja dengan saya, 200" atau "tidak, semuanya tidak baik dengan saya, sekitar 500". Oleh karena itu, jika aplikasi kita bukan http, bukan aplikasi web, sekarang kita berbicara tentang beberapa jenis daemon, kita dapat mengetahui cara melakukan pemeriksaan kesehatan. Artinya tidak perlu, jika aplikasinya bukan http, maka semuanya berfungsi tanpa health check dan ini tidak bisa dilakukan dengan cara apapun. Anda dapat memperbarui beberapa informasi dalam file secara berkala, Anda dapat membuat beberapa perintah khusus untuk daemon Anda, seperti, daemon status, yang akan mengatakan “ya, semuanya baik-baik saja, daemon berfungsi, hidup.”

Untuk apa? Hal pertama dan paling jelas mungkin mengapa pemeriksaan kesehatan diperlukan - untuk memahami bahwa aplikasi berfungsi. Maksudku, itu bodoh sekali, kalau sudah sampai sekarang, sepertinya berhasil, jadi bisa dipastikan itu berhasil. Dan ternyata aplikasinya berjalan, wadahnya berjalan, instance berfungsi, semuanya baik-baik saja - dan kemudian pengguna telah memutus semua nomor telepon dari dukungan teknis dan berkata “apa yang kamu..., kamu tertidur, tidak ada yang berhasil.”

Pemeriksaan kesehatan hanyalah cara untuk melihat dari sudut pandang pengguna bahwa pemeriksaan tersebut berhasil. Salah satu metodenya. Mari kita begini. Dari sudut pandang Kubernetes, ini juga merupakan cara untuk memahami kapan aplikasi dimulai, karena kami memahami bahwa ada perbedaan antara saat container diluncurkan, dibuat, dan dimulai, dan saat aplikasi diluncurkan langsung di container tersebut. Karena jika kita menggunakan aplikasi java rata-rata dan mencoba meluncurkannya di dock, maka selama empat puluh detik, atau bahkan satu menit, atau bahkan sepuluh, aplikasi tersebut dapat dimulai dengan baik. Dalam hal ini, Anda setidaknya dapat mengetuk portnya, ia tidak akan menjawab di sana, artinya ia belum siap menerima lalu lintas.

Sekali lagi, dengan bantuan pemeriksaan kesehatan dan dengan bantuan fakta yang kita bahas di sini, kita dapat memahami di Kubernetes bahwa tidak hanya container yang telah naik dalam aplikasi, tetapi aplikasi itu sendiri telah dimulai, ia sudah merespons terhadap health check, artinya kita bisa mengirimkan traffic ke sana.

Persyaratan untuk mengembangkan aplikasi di Kubernetes

Apa yang saya bicarakan sekarang disebut tes Kesiapan/Keaktifan dalam Kubernetes; oleh karena itu, tes kesiapan kami bertanggung jawab atas ketersediaan aplikasi dalam penyeimbangan. Artinya, jika uji kesiapan dilakukan di aplikasi, maka semuanya baik-baik saja, lalu lintas klien menuju ke aplikasi. Jika tes kesiapan tidak dilakukan, maka aplikasi tidak berpartisipasi, contoh khusus ini tidak berpartisipasi dalam penyeimbangan, dihapus dari penyeimbangan, lalu lintas klien tidak mengalir. Oleh karena itu, pengujian Liveness dalam Kubernetes diperlukan agar jika aplikasi macet, aplikasi dapat dimulai ulang. Jika uji keaktifan tidak berfungsi untuk aplikasi yang dideklarasikan di Kubernetes, maka aplikasi tersebut tidak hanya dihapus dari penyeimbangan, tetapi juga di-restart.

Dan inilah poin penting yang ingin saya sampaikan: dari sudut pandang praktis, tes kesiapan biasanya lebih sering digunakan dan lebih sering dibutuhkan daripada tes keaktifan. Artinya, mendeklarasikan pengujian kesiapan dan keaktifan tanpa berpikir panjang, karena Kubernetes dapat melakukan hal tersebut, dan mari kita gunakan semua yang dapat dilakukannya, bukanlah ide yang baik. Saya akan menjelaskan alasannya. Karena poin nomor dua dalam pengujian adalah sebaiknya periksa layanan yang mendasarinya dalam pemeriksaan kesehatan Anda. Ini berarti bahwa jika Anda memiliki aplikasi web yang memberikan beberapa informasi, yang pada gilirannya, tentu saja, harus diambil dari suatu tempat. Misalnya dalam database. Ya, itu menyimpan informasi yang masuk ke REST API ini ke dalam database yang sama. Oleh karena itu, jika pemeriksaan kesehatan Anda merespons seperti halnya Slashhealth yang dihubungi, aplikasi mengatakan “200, oke, semuanya baik-baik saja,” dan pada saat yang sama database aplikasi Anda tidak dapat diakses, dan aplikasi pemeriksaan kesehatan mengatakan “200, oke, semuanya baik-baik saja ” - Ini adalah pemeriksaan kesehatan yang buruk. Ini bukanlah cara yang seharusnya dilakukan.

Yaitu, aplikasi Anda, ketika ada permintaan yang datang padanya /health, ia tidak hanya merespons, “200, oke”, pertama-tama ia masuk, misalnya, ke database, mencoba menyambungkannya, melakukan sesuatu yang sangat mendasar di sana, seperti memilih satu, cukup memeriksa apakah ada sambungan di database dan Anda dapat menanyakan database. Jika semua ini berhasil, maka jawabannya adalah “200, oke.” Jika tidak berhasil dikatakan ada error, database tidak tersedia.

Oleh karena itu, dalam hal ini, saya kembali lagi ke tes Kesiapan/Kehidupan - mengapa Anda kemungkinan besar memerlukan tes kesiapan, tetapi tes keaktifan dipertanyakan. Karena jika Anda mendeskripsikan health check persis seperti yang saya katakan tadi, ternyata tidak tersedia di bagian instanceв или со всех instancemisalnya dalam database. Ketika Anda mendeklarasikan tes kesiapan, pemeriksaan kesehatan kami mulai gagal, dan oleh karena itu, semua aplikasi yang databasenya tidak dapat diakses, mereka dimatikan begitu saja dari penyeimbangan dan bahkan "hang" dalam keadaan terbengkalai dan menunggu database mereka untuk bekerja.

Jika kita telah mendeklarasikan pengujian keaktifan, bayangkan, database kita rusak, dan separuh dari semuanya di Kubernetes Anda mulai dimulai ulang karena pengujian keaktifan gagal. Ini berarti Anda perlu memulai ulang. Ini sama sekali bukan yang Anda inginkan, saya bahkan punya pengalaman pribadi dalam praktiknya. Kami memiliki aplikasi obrolan yang ditulis dalam JS dan dimasukkan ke dalam database Mongo. Dan masalahnya adalah di awal pekerjaan saya dengan Kubernetes, kami menjelaskan kesiapan, keaktifan pengujian berdasarkan prinsip bahwa Kubernetes dapat melakukannya, jadi kami akan menggunakannya. Oleh karena itu, pada titik tertentu Mongo menjadi sedikit “membosankan” dan sampelnya mulai gagal. Oleh karena itu, menurut uji hujan, buah tersebut mulai “mati”.

Seperti yang Anda pahami, ketika mereka "dibunuh", ini adalah obrolan, artinya ada banyak koneksi dari klien yang tergantung di sana. Mereka juga "dibunuh" - tidak, bukan klien, hanya koneksi - tidak semuanya pada saat yang sama, dan karena fakta bahwa mereka tidak dibunuh pada saat yang sama, ada yang lebih awal, ada yang belakangan, mereka tidak memulai pada saat yang sama waktu. Ditambah standar acak, kami tidak dapat memprediksi dengan akurasi milidetik waktu mulai aplikasi setiap kali, jadi mereka melakukannya satu per satu. Satu infospot naik, ditambahkan ke keseimbangan, semua klien datang ke sana, tidak dapat menahan beban seperti itu, karena sendirian, dan, secara kasar, ada selusin dari mereka yang bekerja di sana, dan itu jatuh. Yang berikutnya naik, seluruh beban ada padanya, dia juga jatuh. Nah, air terjun ini terus mengalir. Pada akhirnya, bagaimana hal ini diselesaikan - kami hanya perlu menghentikan lalu lintas pengguna ke aplikasi ini dengan ketat, membiarkan semua instance naik dan kemudian memulai semua lalu lintas pengguna sekaligus sehingga sudah didistribusikan ke sepuluh instance.

Jika bukan karena uji keaktifan ini diumumkan, yang akan memaksa semuanya dimulai ulang, aplikasi akan menanganinya dengan baik. Tapi segala sesuatu mulai dari penyeimbangan dinonaktifkan untuk kami, karena database tidak dapat diakses dan semua pengguna “jatuh”. Kemudian, ketika database ini tersedia, semuanya sudah termasuk dalam penyeimbangan, namun aplikasi tidak perlu dijalankan lagi, dan tidak perlu membuang waktu dan sumber daya untuk hal ini. Semuanya sudah ada di sini, siap untuk lalu lintas, jadi lalu lintas terbuka saja, semuanya baik-baik saja - aplikasi ada, semuanya terus berfungsi.

Oleh karena itu, tes kesiapan dan keaktifan itu berbeda-beda, terlebih lagi secara teoritis Anda dapat melakukan pemeriksaan kesehatan yang berbeda, satu jenis jari-jari, satu jenis liv misalnya, dan memeriksa berbagai hal. Selama tes kesiapan, periksa backend Anda. Dan pada tes keaktifan, misalnya, Anda tidak memeriksa dari sudut pandang bahwa tes keaktifan umumnya hanya sebuah aplikasi yang merespons, jika mampu merespons sama sekali.

Karena ujian keaktifan pada umumnya adalah saat kita “terjebak”. Perulangan tanpa akhir telah dimulai atau sesuatu yang lain - dan tidak ada lagi permintaan yang diproses. Oleh karena itu, masuk akal untuk memisahkannya - dan menerapkan logika yang berbeda di dalamnya.

Mengenai apa yang perlu dijawab saat tes, saat melakukan pemeriksaan kesehatan. Sungguh menyebalkan. Mereka yang akrab dengan ini mungkin akan tertawa - tapi serius, saya telah melihat layanan dalam hidup saya yang menjawab “200” dalam XNUMX% kasus. Artinya, siapa yang sukses. Namun pada saat yang sama, di badan tanggapan mereka menulis “kesalahan ini dan itu”.

Artinya, status respons datang kepada Anda - semuanya berhasil. Namun pada saat yang sama, Anda harus mengurai isi tersebut, karena isi tersebut mengatakan "maaf, permintaan berakhir dengan kesalahan" dan ini hanyalah kenyataan. Saya melihat ini dalam kehidupan nyata.

Dan agar sebagian orang tidak menganggapnya lucu, dan sebagian lagi menganggapnya sangat menyakitkan, ada baiknya tetap mengikuti aturan sederhana. Dalam pemeriksaan kesehatan, dan pada prinsipnya saat bekerja dengan aplikasi web.

Jika semuanya berjalan baik, maka tanggapi dengan jawaban ke dua ratus. Pada prinsipnya, jawaban dua ratus mana pun cocok untuk Anda. Jika Anda membaca dengan sangat baik dan mengetahui bahwa beberapa status respons berbeda dari yang lain, jawablah dengan yang sesuai: 204, 5, 10, 15, apa pun. Jika tidak terlalu bagus, maka cukup “dua nol nol”. Jika semuanya berjalan buruk dan pemeriksaan kesehatan tidak merespons, jawablah dengan lima ratus. Sekali lagi, jika Anda memahami cara merespons, betapa berbedanya status respons satu sama lain. Jika Anda belum paham, maka 502 adalah pilihan Anda untuk merespons healthcheck jika terjadi kesalahan.

Ini poin lainnya, saya ingin kembali sedikit tentang pengecekan layanan yang mendasarinya. Jika Anda memulai, misalnya, memeriksa semua layanan dasar yang ada di belakang aplikasi Anda - semuanya secara umum. Apa yang kami dapatkan dari sudut pandang arsitektur layanan mikro, kami memiliki konsep seperti “penggandengan rendah” - yaitu, ketika layanan Anda memiliki ketergantungan minimal satu sama lain. Jika salah satu dari mereka gagal, semua yang lain tanpa fungsi ini akan terus bekerja. Beberapa fungsi tidak berfungsi. Oleh karena itu, jika Anda mengaitkan semua pemeriksaan kesehatan satu sama lain, maka Anda akan mengalami satu hal yang gagal dalam infrastruktur, dan karena hal tersebut gagal, semua pemeriksaan kesehatan di semua layanan juga mulai gagal - dan terdapat lebih banyak infrastruktur secara umum untuk layanan tersebut. seluruh arsitektur layanan mikro No. Semuanya menjadi gelap di sana.

Oleh karena itu, saya ingin mengulanginya lagi bahwa Anda perlu memeriksa layanan yang mendasarinya, layanan yang tanpanya aplikasi Anda dalam seratus persen kasus tidak dapat melakukan tugasnya. Artinya, logis bahwa jika Anda memiliki REST API yang digunakan pengguna untuk menyimpan ke database atau mengambil dari database, maka jika tidak ada database, Anda tidak dapat menjamin pekerjaan dengan pengguna Anda.

Tetapi jika pengguna Anda, ketika Anda mengeluarkannya dari database, juga diperkaya dengan beberapa metadata lain, dari backend lain, yang Anda masukkan sebelum mengirim respons ke frontend - dan backend ini tidak tersedia, ini berarti Anda memberikan jawaban tanpa bagian metadata apa pun.

Selanjutnya, kami juga menghadapi salah satu masalah yang menyakitkan saat meluncurkan aplikasi.

Faktanya, hal ini tidak hanya berlaku pada Kubernetes secara umum; kebetulan saja budaya semacam pengembangan massal dan DevOps pada khususnya mulai menyebar pada waktu yang sama dengan Kubernetes. Oleh karena itu, pada umumnya, ternyata Anda perlu mematikan aplikasi Anda dengan baik tanpa Kubernetes. Bahkan sebelum Kubernetes, orang-orang melakukan hal ini, namun dengan munculnya Kubernetes, kami mulai membicarakannya secara massal.

Shutdown Anggun

Secara umum, apa itu Graceful Shutdown dan mengapa diperlukan? Ini tentang ketika aplikasi Anda mogok karena suatu alasan, yang perlu Anda lakukan app stop - atau Anda menerima, misalnya, sinyal dari sistem operasi, aplikasi Anda harus memahaminya dan melakukan sesuatu untuk mengatasinya. Skenario terburuknya, tentu saja, adalah saat aplikasi Anda menerima SIGTERM dan berkata, “SIGTERM, ayo tunggu, bekerja, jangan lakukan apa pun.” Ini adalah pilihan yang sangat buruk.

Persyaratan untuk mengembangkan aplikasi di Kubernetes

Pilihan yang hampir sama buruknya adalah ketika aplikasi Anda menerima SIGTERM dan seperti “mereka bilang segterm, itu artinya kita berakhir, saya belum melihat, saya tidak tahu permintaan pengguna apa pun, saya tidak tahu apa jenisnya permintaan yang sedang saya kerjakan saat ini, katanya SIGTERM, itu artinya kita berakhir" Ini juga merupakan pilihan yang buruk.

Pilihan mana yang bagus? Poin pertama adalah memperhitungkan penyelesaian operasi. Pilihan yang baik adalah server Anda tetap memperhitungkan apa yang dilakukannya jika menerima SIGTERM.

SIGTERM adalah soft shutdown, dirancang khusus, dapat disadap pada level kode, dapat diproses, katakanlah sekarang, tunggu, kita selesaikan dulu pekerjaan yang kita miliki, lalu kita akan keluar.

Dari perspektif Kubernetes, seperti inilah tampilannya. Saat kita mengatakan pada sebuah pod yang berjalan di cluster Kubernetes, “tolong hentikan, pergilah,” atau kita memulai ulang, atau pembaruan terjadi ketika Kubernetes membuat ulang pod tersebut, Kubernetes mengirimkan pesan SIGTERM yang sama ke pod tersebut, menunggu hingga beberapa waktu, dan , ini adalah waktu yang dia tunggu, itu juga dikonfigurasi, ada parameter khusus dalam diploma dan itu disebut Graceful ShutdownTimeout. Seperti yang Anda pahami, tidak sia-sia disebut demikian, dan bukan tanpa alasan kita membicarakannya sekarang.

Di sana kita dapat secara spesifik mengatakan berapa lama kita harus menunggu antara waktu kita mengirim SIGTERM ke aplikasi dan ketika kita memahami bahwa aplikasi tersebut tampaknya menjadi gila karena sesuatu atau "macet" dan tidak akan berakhir - dan kita perlu melakukannya kirimkan SIGKILL, yaitu menyelesaikan pekerjaannya dengan susah payah. Artinya, kami menjalankan semacam daemon, yang memproses operasi. Kami memahami bahwa rata-rata operasi yang dijalankan daemon tidak lebih dari 30 detik setiap kalinya. Oleh karena itu, ketika SIGTERM tiba, kami memahami bahwa daemon kami dapat, paling lama, selesai 30 detik setelah SIGTERM. Kita tuliskan misalnya 45 detik untuk berjaga-jaga dan ucapkan SIGTERM. Setelah itu kita tunggu 45 detik. Secara teori, selama ini iblis seharusnya menyelesaikan pekerjaannya dan mengakhiri dirinya sendiri. Tapi kalau tiba-tiba tidak bisa, berarti kemungkinan besar stuck—tidak lagi memproses permintaan kita secara normal. Dan dalam 45 detik Anda dapat dengan aman menangkapnya.

Dan di sini, sebenarnya, 2 aspek pun dapat diperhitungkan. Pertama, pahami bahwa jika Anda menerima permintaan, Anda mulai mengerjakannya dan tidak memberikan respons kepada pengguna, tetapi Anda menerima SIGTERM, misalnya. Masuk akal untuk menyempurnakannya dan memberikan jawaban kepada pengguna. Ini adalah poin nomor satu dalam hal ini. Poin nomor dua di sini adalah jika Anda menulis aplikasi Anda sendiri, umumnya membangun arsitektur sedemikian rupa sehingga Anda menerima permintaan untuk aplikasi Anda, kemudian Anda memulai beberapa pekerjaan, mulai mengunduh file dari suatu tempat, mengunduh database, dan yang lainnya. - Itu. Secara umum, pengguna Anda, permintaan Anda hang selama setengah jam dan menunggu Anda menjawabnya - kemungkinan besar, Anda perlu mengerjakan arsitekturnya. Artinya, pertimbangkan saja akal sehat bahwa jika operasi Anda pendek, maka masuk akal untuk mengabaikan SIGTERM dan memodifikasinya. Jika operasi Anda panjang, maka tidak masuk akal mengabaikan SIGTERM dalam kasus ini. Masuk akal untuk mendesain ulang arsitektur untuk menghindari operasi yang lama. Sehingga pengguna tidak hanya berdiam diri dan menunggu. Entahlah, buat semacam websocket di sana, buat reverse hook yang sudah dikirim server Anda ke klien, apa saja, tapi jangan paksa pengguna untuk hang selama setengah jam dan tunggu saja satu sesi sampai Anda jawab dia. Karena tidak dapat diprediksi di mana kemungkinan pecahnya.

Saat aplikasi Anda berhenti, Anda harus mengembalikan kode keluar yang wajar. Artinya, jika aplikasi Anda diminta untuk ditutup, dihentikan, dan dapat berhenti secara normal dengan sendirinya, maka tidak perlu mengembalikan kode keluar seperti 1, 5, 255, dan seterusnya. Apa pun yang bukan nol, setidaknya dalam Linux Dalam sistem, saya sangat yakin akan hal ini, itu dianggap tidak berhasil. Artinya, aplikasi Anda dianggap telah dihentikan dengan kesalahan. Dengan demikian, jika aplikasi Anda dihentikan tanpa kesalahan, Anda akan melaporkan kode keluar 0. Jika aplikasi Anda dihentikan dengan kesalahan karena suatu alasan, Anda tidak akan melaporkan kode keluar 0. Dan Anda dapat menggunakan informasi ini.

Dan opsi terakhir. Ini buruk ketika pengguna Anda mengirimkan permintaan dan hang selama setengah jam saat Anda memprosesnya. Namun secara umum, saya juga ingin mengatakan tentang apa yang secara umum bermanfaat dari sisi klien. Tidak masalah jika Anda memiliki aplikasi seluler, front-end, dll. Perlu diingat bahwa secara umum sesi pengguna dapat dihentikan, apa pun bisa terjadi. Permintaan mungkin dikirim, misalnya, tidak diproses dan tidak ada tanggapan yang dikembalikan. Frontend atau aplikasi seluler Anda - frontend apa pun secara umum, anggap saja seperti itu - harus mempertimbangkan hal ini. Jika Anda bekerja dengan websockets, ini biasanya merupakan penderitaan terburuk yang pernah saya alami.

Ketika pengembang beberapa chat biasa tidak mengetahuinya, ternyata websocketnya bisa rusak. Bagi mereka, ketika sesuatu terjadi pada proxy, kami hanya mengubah konfigurasinya, dan itu memuat ulang. Tentu saja, semua sesi jangka panjang terkoyak dalam kasus ini. Pengembang mendatangi kami dan berkata: "Teman-teman, apa yang kamu lakukan, obrolan untuk semua klien kami terganggu!" Kami memberi tahu mereka: “Apa yang kamu lakukan? Apakah klien Anda tidak dapat terhubung kembali? Mereka berkata: “Tidak, kami ingin sesi-sesi tersebut tidak terkoyak.” Singkatnya, ini sebenarnya tidak masuk akal. Sisi klien perlu diperhitungkan. Terutama, seperti yang saya katakan, dengan sesi yang berumur panjang seperti websockets, sesi tersebut dapat rusak dan, tanpa disadari oleh pengguna, Anda harus dapat menginstal ulang sesi tersebut. Dan kemudian semuanya sempurna.

Sumber daya

Sebenarnya disini saya hanya akan menceritakan kisahnya secara langsung saja. Sekali lagi dari kehidupan nyata. Hal paling sakit yang pernah saya dengar tentang sumber daya.

Sumber daya dalam hal ini, maksud saya, semacam permintaan, batasan yang dapat Anda masukkan ke dalam pod di cluster Kubernetes Anda. Hal paling lucu yang saya dengar dari seorang pengembang... Salah satu rekan pengembang saya di tempat kerja sebelumnya pernah berkata: “Aplikasi saya tidak dapat dijalankan di cluster.” Saya melihat bahwa itu belum dimulai, tapi mungkin tidak sesuai dengan sumber dayanya, atau mereka telah menetapkan batasan yang sangat kecil. Singkatnya, aplikasi tidak dapat dijalankan karena sumber daya. Saya berkata: “Ini tidak akan dimulai karena sumber daya, Anda memutuskan berapa banyak yang Anda butuhkan dan menetapkan nilai yang memadai.” Dia berkata: “Sumber daya apa?” Saya mulai menjelaskan kepadanya bahwa Kubernetes, batasan permintaan dan bla, bla, bla perlu ditetapkan. Pria itu mendengarkan selama lima menit, mengangguk dan berkata: “Saya datang ke sini untuk bekerja sebagai pengembang, saya tidak ingin tahu apa pun tentang sumber daya apa pun. Saya datang ke sini untuk menulis kode dan hanya itu.” Sedih. Ini adalah konsep yang sangat menyedihkan dari sudut pandang pengembang. Terutama di dunia modern, bisa dikatakan, negara-negara yang menganut paham progresif.

Mengapa sumber daya dibutuhkan? Ada 2 jenis sumber daya di Kubernetes. Ada yang disebut permintaan, ada pula yang disebut batasan. Dari segi sumber daya kita akan memahami bahwa pada dasarnya hanya ada dua batasan dasar. Artinya, batas waktu CPU dan batas RAM untuk container yang berjalan di Kubernetes.

Batasan menempatkan batas atas pada bagaimana sumber daya dapat digunakan dalam aplikasi Anda. Oleh karena itu, jika Anda mengatakan batasan RAM 1GB, maka aplikasi Anda tidak akan dapat menggunakan lebih dari 1GB RAM. Dan jika dia tiba-tiba ingin dan mencoba melakukan ini, maka sebuah proses yang disebut oom killer, kehabisan memori, akan datang dan mematikan aplikasi Anda - yaitu, aplikasi akan restart begitu saja. Aplikasi tidak akan dimulai ulang berdasarkan CPU. Dalam hal CPU, jika suatu aplikasi mencoba menggunakan lebih banyak, lebih dari batas yang ditentukan, CPU akan dipilih secara ketat. Hal ini tidak menyebabkan restart. Ini adalah batasnya - ini adalah batas atasnya.

Dan ada permintaan. Permintaan adalah cara Kubernetes memahami bagaimana node di cluster Kubernetes Anda diisi dengan aplikasi. Artinya, permintaan adalah semacam penerapan aplikasi Anda. Dikatakan apa yang ingin saya gunakan: "Saya ingin Anda mencadangkan CPU dan memori sebanyak ini untuk saya." Analogi yang sederhana. Bagaimana jika kita memiliki sebuah node yang, entahlah, memiliki total 8 CPU. Dan sebuah pod tiba di sana, yang permintaannya mengatakan 1 CPU, yang berarti node tersebut memiliki 7 CPU tersisa. Oleh karena itu, segera setelah 8 pod tiba di node ini, yang masing-masing memiliki 1 CPU dalam permintaannya, node tersebut, seolah-olah dari sudut pandang Kubernetes, telah kehabisan CPU dan lebih banyak pod dengan permintaan tidak dapat diterima. diluncurkan pada node ini. Jika semua node kehabisan CPU, maka Kubernetes akan mulai mengatakan bahwa tidak ada node yang cocok di cluster untuk menjalankan pod Anda karena CPU telah habis.

Mengapa permintaan diperlukan dan mengapa tanpa permintaan, menurut saya tidak perlu meluncurkan apa pun di Kubernetes? Mari kita bayangkan sebuah situasi hipotetis. Anda meluncurkan aplikasi Anda tanpa permintaan, Kubernetes tidak tahu berapa banyak yang Anda miliki, ke node mana Anda dapat mendorongnya. Yah, dia mendorong, mendorong, mendorong ke simpul. Pada titik tertentu, Anda akan mulai mendapatkan lalu lintas ke aplikasi Anda. Dan salah satu aplikasi tiba-tiba mulai menggunakan sumber daya hingga batas yang dimilikinya. Ternyata ada aplikasi lain di dekatnya dan juga membutuhkan sumber daya. Node sebenarnya mulai kehabisan sumber daya secara fisik, misalnya OP. Node sebenarnya mulai kehabisan sumber daya secara fisik, misalnya memori akses acak (RAM). Ketika sebuah node kehabisan daya, pertama-tama buruh pelabuhan akan berhenti merespons, lalu kubus, lalu OS. Mereka akan pingsan dan SEMUANYA pasti akan berhenti bekerja untuk Anda. Artinya, ini akan menyebabkan node Anda macet dan Anda harus memulai ulang. Singkatnya, situasinya tidak terlalu baik.

Dan ketika Anda memiliki permintaan, batasannya tidak jauh berbeda, setidaknya tidak berkali-kali lipat dari batasan atau permintaan, maka Anda dapat memiliki pengisian aplikasi yang normal dan rasional di seluruh node cluster Kubernetes. Pada saat yang sama, Kubernetes secara kasar mengetahui berapa banyak dari apa yang ditempatkan di suatu tempat, dan berapa banyak dari apa yang digunakan di suatu tempat. Artinya, ini hanyalah momen seperti itu. Penting untuk memahaminya. Dan penting untuk mengontrol bahwa hal ini diindikasikan.

Penyimpanan data

Poin kami berikutnya adalah tentang penyimpanan data. Apa yang harus dilakukan terhadap mereka dan secara umum, apa yang harus dilakukan dengan kegigihan di Kubernetes?

Saya pikir, sekali lagi, di dalam diri kita Sekolah Malam, ada topik tentang database di Kubernetes. Dan sepertinya saya tahu secara kasar apa yang dikatakan rekan Anda ketika ditanya: “Apakah mungkin menjalankan database di Kubernetes?” Untuk beberapa alasan, menurut saya kolega Anda seharusnya memberi tahu Anda bahwa jika Anda bertanya apakah mungkin menjalankan database di Kubernetes, maka itu tidak mungkin.

Logikanya di sini sederhana. Untuk berjaga-jaga, saya akan menjelaskan sekali lagi, jika Anda adalah orang yang sangat keren yang dapat membangun sistem penyimpanan jaringan terdistribusi yang cukup toleran terhadap kesalahan, pahami cara memasukkan database ke dalam kasus ini, cara kerja cloud native dalam container dalam database pada umumnya. Kemungkinan besar, Anda tidak memiliki pertanyaan tentang cara menjalankannya. Jika Anda memiliki pertanyaan seperti itu, dan Anda ingin memastikan bahwa semuanya terungkap dan bertahan sampai mati dalam produksi dan tidak pernah gagal, maka hal ini tidak akan terjadi. Anda dijamin akan menembak diri sendiri dengan pendekatan ini. Jadi lebih baik tidak melakukannya.

Apa yang harus kita lakukan dengan data yang ingin disimpan oleh aplikasi kita, beberapa gambar yang diunggah pengguna, beberapa hal yang dihasilkan aplikasi kita selama pengoperasiannya, saat startup, misalnya? Apa yang harus dilakukan dengan mereka di Kubernetes?

Secara umum, idealnya, ya, tentu saja, Kubernetes dirancang dengan sangat baik dan pada awalnya dirancang untuk aplikasi stateless. Artinya, untuk aplikasi yang tidak menyimpan informasi sama sekali. Ini idealnya.

Namun, tentu saja, pilihan ideal tidak selalu ada. Terus? Poin pertama dan paling sederhana adalah mengambil semacam S3, hanya saja bukan yang buatan sendiri, yang juga tidak jelas cara kerjanya, tetapi dari beberapa penyedia. Penyedia yang baik dan normal - dan ajarkan aplikasi Anda untuk menggunakan S3. Artinya, ketika pengguna Anda ingin mengunggah file, ucapkan “di sini, silakan unggah ke S3.” Ketika dia ingin menerimanya, katakan: “Ini tautan ke S3 kembali dan ambil dari sini.” Ini idealnya.

Jika tiba-tiba karena alasan tertentu opsi ideal ini tidak cocok, Anda memiliki aplikasi yang tidak Anda tulis, tidak Anda kembangkan, atau itu semacam warisan yang buruk, tidak dapat menggunakan protokol S3, tetapi harus bekerja dengan direktori lokal di folder lokal. Ambil sesuatu yang lebih atau kurang sederhana, terapkan Kubernetes. Artinya, segera memagari Ceph untuk beberapa tugas minimal, menurut saya, adalah ide yang buruk. Karena Ceph tentunya bagus dan modis. Tetapi jika Anda tidak benar-benar memahami apa yang Anda lakukan, maka setelah Anda memasukkan sesuatu ke Ceph, Anda dapat dengan mudah dan tidak akan pernah mengeluarkannya lagi. Sebab, seperti yang Anda ketahui, Ceph menyimpan data di clusternya dalam bentuk biner, bukan dalam bentuk file sederhana. Oleh karena itu, jika tiba-tiba cluster Ceph rusak, kemungkinan besar Anda tidak akan pernah mendapatkan data dari sana lagi.

Kami akan mengadakan kursus tentang Ceph, Anda bisa biasakan diri Anda dengan program ini dan kirimkan aplikasi.

Oleh karena itu, lebih baik melakukan sesuatu yang sederhana seperti server NFS. Kubernetes dapat bekerja dengannya, Anda dapat memasang direktori di bawah server NFS - aplikasi Anda seperti direktori lokal. Pada saat yang sama, tentu saja, Anda perlu memahami bahwa, sekali lagi, Anda perlu melakukan sesuatu dengan NFS Anda, Anda perlu memahami bahwa terkadang NFS menjadi tidak dapat diakses dan mempertimbangkan pertanyaan tentang apa yang akan Anda lakukan dalam kasus ini. Mungkin itu harus dicadangkan di suatu tempat di mesin terpisah.

Poin berikutnya yang saya bicarakan adalah apa yang harus dilakukan jika aplikasi Anda menghasilkan beberapa file selama pengoperasian. Misalnya, saat dijalankan, ia menghasilkan beberapa file statis, yang didasarkan pada beberapa informasi yang hanya diterima aplikasi pada saat peluncuran. Momen yang luar biasa. Jika data seperti itu tidak banyak, maka Anda tidak perlu repot sama sekali, cukup instal aplikasi ini untuk Anda sendiri dan bekerja. Satu-satunya pertanyaan di sini adalah apa, lihat. Seringkali, semua jenis sistem lama, seperti WordPress dan sebagainya, terutama dengan memodifikasi beberapa jenis plugin pintar, pengembang PHP yang pintar, mereka sering kali tahu cara membuatnya sehingga mereka menghasilkan beberapa jenis file untuk diri mereka sendiri. Oleh karena itu, yang satu menghasilkan satu file, yang kedua menghasilkan file kedua. Mereka berbeda. Penyeimbangan terjadi di cluster Kubernetes klien secara kebetulan. Oleh karena itu, ternyata mereka tidak tahu cara bekerja sama. Yang satu memberikan satu informasi, yang lain memberikan informasi lain kepada pengguna. Ini adalah sesuatu yang harus Anda hindari. Artinya, di Kubernetes, semua yang Anda luncurkan dijamin dapat berfungsi di banyak instance. Karena Kubernetes adalah sesuatu yang mengharukan. Oleh karena itu, dia dapat memindahkan apa pun, kapan pun dia mau, tanpa meminta siapa pun sama sekali. Oleh karena itu, Anda perlu mengandalkan hal ini. Segala sesuatu yang diluncurkan dalam satu contoh cepat atau lambat akan gagal. Semakin banyak reservasi yang Anda miliki, semakin baik. Tapi sekali lagi, saya katakan, jika Anda memiliki beberapa file seperti itu, maka Anda dapat meletakkannya tepat di bawah Anda, beratnya sedikit. Jika jumlahnya lebih sedikit, sebaiknya Anda tidak memasukkannya ke dalam wadah.

Saya menyarankan bahwa ada hal yang luar biasa di Kubernetes, Anda dapat menggunakan volume. Khususnya, ada volume bertipe dir kosong. Artinya, hanya saja Kubernetes akan secara otomatis membuat direktori di direktori layanannya di server tempat Anda memulai. Dan dia akan memberikannya kepadamu agar kamu dapat menggunakannya. Hanya ada satu poin penting. Artinya, data Anda tidak akan disimpan di dalam container, melainkan di host yang Anda jalankan. Selain itu, Kubernetes dapat mengontrol direktori kosong tersebut dalam konfigurasi normal dan mampu mengontrol ukuran maksimumnya dan tidak membiarkannya terlampaui. Satu-satunya poin adalah apa yang Anda tulis di direktori kosong tidak hilang saat pod dimulai ulang. Artinya, jika pod Anda jatuh secara tidak sengaja dan naik lagi, informasi di direktori yang kosong tidak akan kemana-mana. Dia bisa menggunakannya lagi di awal yang baru - dan itu bagus. Jika pod Anda pergi ke suatu tempat, tentu saja dia akan pergi tanpa data. Artinya, segera setelah pod dari node tempat diluncurkannya dengan direktori kosong menghilang, direktori kosong akan dihapus.

Apa lagi yang bagus tentang direktori kosong? Misalnya, dapat digunakan sebagai cache. Bayangkan aplikasi kita menghasilkan sesuatu dengan cepat, memberikannya kepada pengguna, dan melakukannya untuk waktu yang lama. Oleh karena itu, aplikasi, misalnya, menghasilkan dan memberikannya kepada pengguna, dan pada saat yang sama menyimpannya di suatu tempat, sehingga pada saat pengguna datang untuk hal yang sama, akan lebih cepat untuk memberikannya segera. Dir kosong dapat diminta ke Kubernetes untuk dibuat di memori. Dan dengan demikian, cache Anda secara umum dapat bekerja secepat kilat - dalam hal kecepatan akses disk. Artinya, Anda memiliki direktori kosong di memori, di OS itu disimpan di memori, tetapi bagi Anda, untuk pengguna di dalam pod, sepertinya hanya direktori lokal. Anda tidak memerlukan aplikasi untuk secara khusus mengajarkan sihir apa pun. Anda cukup langsung mengambil dan meletakkan file Anda di sebuah direktori, namun sebenarnya di memori OS. Ini juga merupakan fitur yang sangat berguna dalam hal Kubernetes.

Masalah apa yang dimiliki Minio? Masalah utama dengan Minio adalah agar hal ini dapat berfungsi, ia harus dijalankan di suatu tempat, dan harus ada semacam sistem file, yaitu penyimpanan. Dan di sini kita menghadapi masalah yang sama dengan Ceph. Artinya, Minio harus menyimpan filenya di suatu tempat. Ini hanyalah antarmuka HTTP ke file Anda. Selain itu, fungsinya jelas lebih buruk dibandingkan S3 Amazon. Sebelumnya, ia tidak dapat mengotorisasi pengguna dengan benar. Sekarang, sejauh yang saya tahu, ia sudah dapat membuat keranjang dengan otorisasi berbeda, tetapi sekali lagi, menurut saya masalah utamanya, bisa dikatakan, adalah sistem penyimpanan yang mendasarinya.

Bagaimana direktori kosong di memori mempengaruhi batas? Tidak mempengaruhi batasan dengan cara apa pun. Itu terletak di memori host, dan bukan di memori wadah Anda. Artinya, container Anda tidak melihat direktori kosong di memori sebagai bagian dari memori yang ditempati. Tuan rumah melihat ini. Oleh karena itu, ya, dari sudut pandang kubernetes, ketika Anda mulai menggunakan ini, sebaiknya dipahami bahwa Anda mencurahkan sebagian memori Anda untuk mengosongkan direktori. Oleh karena itu, pahamilah bahwa memori dapat habis bukan hanya karena aplikasi, tetapi juga karena seseorang menulis ke direktori kosong ini.

keaslian awan

Dan subtopik terakhir adalah apa itu Cloudnative. Mengapa itu diperlukan? Cloudnativeness dan sebagainya.

Artinya, aplikasi-aplikasi yang mampu dan ditulis agar dapat bekerja di infrastruktur cloud modern. Namun nyatanya, Cloudnative memiliki aspek lain yang serupa. Bahwa ini bukan hanya aplikasi yang memperhitungkan semua persyaratan infrastruktur cloud modern, tetapi juga mengetahui cara bekerja dengan infrastruktur cloud modern ini, memanfaatkan kelebihan dan kekurangan dari fakta bahwa ia bekerja di cloud ini. Jangan berlebihan dan bekerja di cloud, namun manfaatkan manfaat bekerja di cloud.

Persyaratan untuk mengembangkan aplikasi di Kubernetes

Ambil saja Kubernetes sebagai contoh. Aplikasi Anda berjalan di Kubernetes. Aplikasi Anda selalu bisa, atau lebih tepatnya admin aplikasi Anda, selalu bisa membuat akun layanan. Artinya, akun untuk otorisasi di Kubernetes itu sendiri di servernya. Tambahkan beberapa hak yang kita butuhkan di sana. Dan Anda dapat mengakses Kubernetes dari dalam aplikasi Anda. Apa yang bisa kamu lakukan dengan cara ini? Misalnya, dari sebuah aplikasi, terima data tentang di mana aplikasi Anda yang lain, instance serupa lainnya berada, dan entah bagaimana mengelompokkannya di atas Kubernetes, jika diperlukan.

Sekali lagi, kami punya kasus baru-baru ini. Kami memiliki satu pengontrol yang memantau antrian. Dan ketika beberapa tugas baru muncul di antrean ini, tugas tersebut masuk ke Kubernetes - dan di dalam Kubernetes, tugas tersebut membuat pod baru. Memberi pod ini beberapa tugas baru dan dalam kerangka pod ini, pod melakukan tugas tersebut, mengirimkan respons ke pengontrol itu sendiri, dan pengontrol kemudian melakukan sesuatu dengan informasi ini. Misalnya, ia menambahkan database. Sekali lagi, ini merupakan nilai tambah dari fakta bahwa aplikasi kita berjalan di Kubernetes. Kita dapat menggunakan fungsionalitas bawaan Kubernetes itu sendiri untuk memperluas dan membuat fungsionalitas aplikasi kita lebih nyaman. Artinya, jangan sembunyikan semacam keajaiban tentang cara meluncurkan aplikasi, cara meluncurkan pekerja. Di Kubernetes, Anda cukup mengirimkan permintaan di aplikasi jika aplikasi tersebut ditulis dengan Python.

Hal yang sama juga berlaku jika kita melampaui Kubernetes. Kami menjalankan Kubernet di suatu tempat - ada baiknya jika Kubernet berada di cloud. Sekali lagi, kita dapat menggunakan, dan bahkan saya yakin, kita harus menggunakan kemampuan cloud itu sendiri di tempat kita menjalankannya. Dari hal-hal dasar yang diberikan cloud kepada kita. Menyeimbangkan, yaitu kita dapat membuat penyeimbang cloud dan menggunakannya. Ini adalah keuntungan langsung dari apa yang bisa kita gunakan. Karena penyeimbangan cloud, pertama-tama, dengan bodohnya menghilangkan tanggung jawab dari kami atas cara kerjanya, cara konfigurasinya. Ditambah lagi, ini sangat nyaman karena Kubernet biasa dapat berintegrasi dengan cloud.

Hal yang sama berlaku untuk penskalaan. Kubernetes reguler dapat berintegrasi dengan penyedia cloud. Tahu bagaimana memahami bahwa jika cluster kehabisan node, yaitu ruang node telah habis, maka Anda perlu menambahkan - Kubernetes sendiri akan menambahkan node baru ke cluster Anda dan mulai meluncurkan pod di dalamnya. Artinya, ketika beban Anda tiba, jumlah perapian mulai bertambah. Ketika node dalam cluster untuk pod ini habis, Kubernetes meluncurkan node baru dan, oleh karena itu, jumlah pod masih dapat bertambah. Dan itu sangat nyaman. Ini adalah peluang langsung untuk meningkatkan skala cluster dengan cepat. Tidak terlalu cepat, dalam artian bukan sedetik, lebih tepatnya satu menit untuk menambah node baru.

Tapi dari pengalaman saya, sekali lagi, ini adalah hal paling keren yang pernah saya lihat. Saat kluster Cloudnative diskalakan berdasarkan waktu. Itu adalah layanan backend yang digunakan oleh orang-orang di back office. Artinya, mereka mulai bekerja pada jam 9 pagi, mulai masuk ke sistem, dan karenanya, cluster Cloudnative, tempat semuanya berjalan, mulai membengkak, meluncurkan pod baru sehingga setiap orang yang datang bekerja dapat bekerja dengan aplikasi tersebut. Ketika mereka pulang kerja pada jam 8 malam atau 6 sore, cluster Kubernetes menyadari bahwa tidak ada lagi yang menggunakan aplikasi tersebut dan mulai menyusut. Penghematan hingga 30 persen dijamin. Hal ini berhasil di Amazon pada saat itu; pada saat itu, tidak ada seorang pun di Rusia yang dapat melakukannya dengan baik.

Jujur saja, penghematannya sebesar 30 persen hanya karena kami menggunakan Kubernetes dan memanfaatkan kemampuan cloud. Sekarang hal ini bisa dilakukan di Rusia. Saya tidak akan beriklan kepada siapa pun, tentu saja, tetapi anggap saja ada penyedia yang dapat melakukan ini, menyediakannya langsung dengan sebuah tombol.

Ada satu poin terakhir yang saya juga ingin menarik perhatian Anda. Agar aplikasi Anda, infrastruktur Anda menjadi Cloudnative, masuk akal untuk akhirnya mulai mengadaptasi pendekatan yang disebut Infrastruktur sebagai Kode Artinya, ini berarti bahwa aplikasi Anda, atau lebih tepatnya infrastruktur Anda, memerlukan hal yang sama persis dengan kode yang dijelaskan. aplikasi, logika bisnis Anda dalam bentuk kode. Dan bekerja dengannya sebagai kode, yaitu mengujinya, meluncurkannya, menyimpannya di git, menerapkan CICD padanya.

Dan inilah yang memungkinkan Anda, pertama, untuk selalu memiliki kendali atas infrastruktur Anda, untuk selalu memahami kondisinya. Kedua, hindari pengoperasian manual yang menyebabkan kesalahan. Ketiga, hindari apa yang disebut turnover, ketika Anda terus-menerus harus melakukan tugas manual yang sama. Keempat, ini memungkinkan Anda pulih lebih cepat jika terjadi kegagalan. Di Rusia, setiap kali saya membicarakan hal ini, selalu ada banyak orang yang berkata: “Ya, sudah jelas, tapi Anda punya pendekatan, singkatnya, tidak perlu memperbaiki apa pun.” Tapi itu benar. Jika ada yang rusak di infrastruktur Anda, maka dari sudut pandang pendekatan Cloudnative dan dari sudut pandang Infrastruktur sebagai Kode, daripada memperbaikinya, pergi ke server, mencari tahu apa yang rusak dan memperbaikinya, itu lebih mudah untuk menghapus server dan membuatnya lagi. Dan Aku akan memulihkan semua ini.

Semua masalah ini dibahas lebih rinci di Kursus video Kubernetes: Junior, Dasar, Mega. Dengan mengikuti tautan ini Anda dapat mengetahui program dan ketentuannya. Nyamannya, Anda bisa menguasai Kubernetes dengan belajar dari rumah atau bekerja selama 1-2 jam sehari.

Sumber: www.habr.com

Beli hosting yang andal untuk situs dengan perlindungan DDoS, server VPS VDS 🔥 Beli hosting website andal dengan perlindungan DDoS, server VPS VDS | ProHoster