Log masuk Kubernetes (dan bukan sahaja) hari ini: jangkaan dan realiti

Log masuk Kubernetes (dan bukan sahaja) hari ini: jangkaan dan realiti

Sekarang tahun 2019, dan kami masih tidak mempunyai penyelesaian standard untuk pengagregatan log dalam Kubernetes. Dalam artikel ini, kami ingin, menggunakan contoh daripada amalan sebenar, untuk berkongsi carian kami, masalah yang dihadapi dan penyelesaiannya.

Walau bagaimanapun, pertama, saya akan membuat tempahan yang pelanggan berbeza memahami perkara yang sangat berbeza dengan mengumpul log:

  • seseorang mahu melihat log keselamatan dan audit;
  • seseorang - pembalakan berpusat bagi keseluruhan infrastruktur;
  • dan bagi sesetengah orang, cukup untuk mengumpul log aplikasi sahaja, tidak termasuk, sebagai contoh, pengimbang.

Di bawah ialah potongan di bawah tentang cara kami melaksanakan pelbagai "senarai keinginan" dan kesukaran yang kami hadapi.

Teori: tentang alat pembalakan

Latar belakang mengenai komponen sistem pembalakan

Pembalakan telah berjalan jauh, akibatnya metodologi untuk mengumpul dan menganalisis log telah dibangunkan, yang mana kita gunakan hari ini. Kembali pada tahun 1950-an, Fortran memperkenalkan analog aliran input/output standard, yang membantu pengaturcara menyahpepijat programnya. Ini adalah log komputer pertama yang menjadikan hidup lebih mudah untuk pengaturcara pada masa itu. Hari ini kita melihat di dalamnya komponen pertama sistem pembalakan - sumber atau "pengeluar" balak.

Sains komputer tidak berhenti: rangkaian komputer muncul, kelompok pertama... Sistem kompleks yang terdiri daripada beberapa komputer mula berfungsi. Kini pentadbir sistem terpaksa mengumpul log daripada beberapa mesin, dan dalam kes khas mereka boleh menambah mesej kernel OS sekiranya mereka perlu menyiasat kegagalan sistem. Untuk menerangkan sistem pengumpulan log berpusat, pada awal 2000-an ia diterbitkan RFC 3164, yang menyeragamkan remote_syslog. Ini adalah bagaimana komponen penting lain muncul: pengumpul balak dan simpanan mereka.

Dengan peningkatan dalam jumlah log dan pengenalan meluas teknologi web, timbul persoalan tentang log apa yang perlu ditunjukkan dengan mudah kepada pengguna. Alat konsol ringkas (awk/sed/grep) telah digantikan dengan yang lebih maju pemapar log - komponen ketiga.

Oleh kerana peningkatan dalam jumlah log, sesuatu yang lain menjadi jelas: log diperlukan, tetapi tidak semuanya. Dan log yang berbeza memerlukan tahap pemeliharaan yang berbeza: sesetengahnya boleh hilang dalam sehari, manakala yang lain perlu disimpan selama 5 tahun. Jadi, komponen untuk menapis dan menghala aliran data telah ditambahkan pada sistem pengelogan - sebut saja penapis.

Storan juga telah membuat lonjakan besar: daripada fail biasa kepada pangkalan data hubungan, dan kemudian kepada storan berorientasikan dokumen (contohnya, Elasticsearch). Jadi simpanan dipisahkan daripada pengumpul.

Akhirnya, konsep log telah berkembang kepada sejenis aliran abstrak peristiwa yang ingin kita simpan untuk sejarah. Atau sebaliknya, sekiranya anda perlu menjalankan penyiasatan atau membuat laporan analisis...

Akibatnya, dalam tempoh masa yang agak singkat, pengumpulan log telah berkembang menjadi subsistem penting, yang boleh dipanggil salah satu subseksyen dalam Big Data.

Log masuk Kubernetes (dan bukan sahaja) hari ini: jangkaan dan realiti
Jika suatu masa dahulu cetakan biasa boleh mencukupi untuk "sistem pembalakan," kini keadaan telah banyak berubah.

Kubernetes dan log

Apabila Kubernetes datang ke infrastruktur, masalah yang sedia ada untuk mengumpul balak juga tidak memintasnya. Dalam beberapa cara, ia menjadi lebih menyakitkan: mengurus platform infrastruktur bukan sahaja dipermudahkan, tetapi juga rumit pada masa yang sama. Banyak perkhidmatan lama telah mula berhijrah ke perkhidmatan mikro. Dalam konteks log, ini dicerminkan dalam peningkatan jumlah sumber log, kitaran hayat khas mereka, dan keperluan untuk menjejaki hubungan semua komponen sistem melalui log...

Melihat ke hadapan, saya boleh menyatakan bahawa sekarang, malangnya, tiada pilihan pengelogan piawai untuk Kubernetes yang akan dibandingkan dengan semua yang lain. Skim yang paling popular dalam komuniti adalah seperti berikut:

  • seseorang membuka gulungan EFK (Elasticsearch, Fluentd, Kibana);
  • seseorang sedang mencuba yang dikeluarkan baru-baru ini Loki atau kegunaan Operator pembalakan;
  • kami (dan mungkin bukan sahaja kita?..) Saya sebahagian besarnya berpuas hati dengan perkembangan saya sendiri - rumah balak...

Sebagai peraturan, kami menggunakan himpunan berikut dalam kelompok K8s (untuk penyelesaian yang dihoskan sendiri):

Walau bagaimanapun, saya tidak akan memikirkan arahan untuk pemasangan dan konfigurasi mereka. Sebaliknya, saya akan memberi tumpuan kepada kekurangan mereka dan lebih banyak kesimpulan global tentang keadaan dengan log secara umum.

Berlatih dengan log dalam K8s

Log masuk Kubernetes (dan bukan sahaja) hari ini: jangkaan dan realiti

"Log setiap hari", berapa ramai daripada anda di sana?..

Pengumpulan log berpusat daripada infrastruktur yang agak besar memerlukan sumber yang besar, yang akan dibelanjakan untuk mengumpul, menyimpan dan memproses log. Semasa operasi pelbagai projek, kami berhadapan dengan pelbagai keperluan dan masalah operasi yang timbul daripadanya.

Jom cuba ClickHouse

Mari lihat storan berpusat pada projek dengan aplikasi yang menjana log dengan agak aktif: lebih daripada 5000 baris sesaat. Mari kita mula bekerja dengan lognya, menambahkannya pada ClickHouse.

Sebaik sahaja masa nyata maksimum diperlukan, pelayan 4-teras dengan ClickHouse sudah terlebih beban pada subsistem cakera:

Log masuk Kubernetes (dan bukan sahaja) hari ini: jangkaan dan realiti

Jenis pemuatan ini disebabkan oleh fakta bahawa kami cuba menulis dalam ClickHouse secepat mungkin. Dan pangkalan data bertindak balas terhadap ini dengan peningkatan beban cakera, yang boleh menyebabkan ralat berikut:

DB::Exception: Too many parts (300). Merges are processing significantly slower than inserts

Fakta adalah bahawa Jadual MergeTree dalam ClickHouse (ia mengandungi data log) mempunyai kesukaran mereka sendiri semasa operasi tulis. Data yang dimasukkan ke dalamnya menghasilkan partition sementara, yang kemudiannya digabungkan dengan jadual utama. Akibatnya, rakaman ternyata sangat menuntut pada cakera, dan ia juga tertakluk kepada had yang kami terima notis di atas: tidak lebih daripada 1 subpartition boleh digabungkan dalam 300 saat (sebenarnya, ini adalah 300 sisipan sesaat).

Untuk mengelakkan tingkah laku ini, harus menulis kepada ClickHouse dalam kepingan sebesar mungkin dan tidak lebih daripada 1 kali setiap 2 saat. Walau bagaimanapun, menulis dalam pecahan besar mencadangkan bahawa kita harus menulis kurang kerap dalam ClickHouse. Ini, seterusnya, boleh menyebabkan limpahan penimbal dan kehilangan balak. Penyelesaiannya adalah untuk meningkatkan penimbal Fluentd, tetapi penggunaan memori juga akan meningkat.

Nota: Satu lagi aspek bermasalah penyelesaian kami dengan ClickHouse adalah berkaitan dengan fakta bahawa pembahagian dalam kes kami (rumah kayu) dilaksanakan melalui jadual luaran yang disambungkan Cantumkan jadual. Ini membawa kepada fakta bahawa apabila pensampelan selang masa yang besar, RAM yang berlebihan diperlukan, memandangkan metatable bergerak melalui semua partition - walaupun yang jelas tidak mengandungi data yang diperlukan. Walau bagaimanapun, kini pendekatan ini boleh diisytiharkan dengan selamat sebagai usang untuk versi semasa ClickHouse (c 18.16).

Akibatnya, menjadi jelas bahawa tidak setiap projek mempunyai sumber yang mencukupi untuk mengumpul log dalam masa nyata dalam ClickHouse (lebih tepat lagi, pengedarannya tidak sesuai). Di samping itu, anda perlu menggunakan аккумулятор, yang kami akan kembali kemudian. Kes yang diterangkan di atas adalah benar. Dan pada masa itu kami tidak dapat menawarkan penyelesaian yang boleh dipercayai dan stabil yang sesuai dengan pelanggan dan membolehkan kami mengumpul log dengan kelewatan yang minimum...

Bagaimana pula dengan Elasticsearch?

Elasticsearch dikenali untuk mengendalikan beban kerja yang berat. Mari cuba dalam projek yang sama. Sekarang beban kelihatan seperti ini:

Log masuk Kubernetes (dan bukan sahaja) hari ini: jangkaan dan realiti

Elasticsearch dapat mencerna aliran data, walau bagaimanapun, menulis volum sedemikian padanya sangat menggunakan CPU. Ini diputuskan dengan menganjurkan kluster. Secara teknikal, ini bukan masalah, tetapi ternyata hanya untuk mengendalikan sistem pengumpulan log kami sudah menggunakan kira-kira 8 teras dan mempunyai komponen tambahan yang sangat dimuatkan dalam sistem...

Intinya: pilihan ini boleh dibenarkan, tetapi hanya jika projek itu besar dan pengurusannya bersedia untuk membelanjakan sumber yang besar pada sistem pembalakan berpusat.

Kemudian timbul persoalan semula jadi:

Apakah log yang benar-benar diperlukan?

Log masuk Kubernetes (dan bukan sahaja) hari ini: jangkaan dan realiti Mari cuba ubah pendekatan itu sendiri: log hendaklah pada masa yang sama bermaklumat dan tidak meliputi setiap peristiwa dalam sistem.

Katakan kita mempunyai kedai dalam talian yang berjaya. Apakah log yang penting? Mengumpul sebanyak mungkin maklumat, contohnya, daripada gerbang pembayaran, adalah idea yang bagus. Tetapi tidak semua log daripada perkhidmatan penghirisan imej dalam katalog produk adalah penting bagi kami: hanya ralat dan pemantauan lanjutan sudah mencukupi (contohnya, peratusan 500 ralat yang dihasilkan oleh komponen ini).

Jadi kami telah membuat kesimpulan bahawa pembalakan berpusat tidak selalu wajar. Selalunya pelanggan ingin mengumpulkan semua log di satu tempat, walaupun sebenarnya, daripada keseluruhan log, hanya 5% mesej bersyarat yang penting untuk perniagaan diperlukan:

  • Kadang-kadang cukup untuk mengkonfigurasi, katakan, hanya saiz log kontena dan pengumpul ralat (contohnya, Sentry).
  • Pemberitahuan ralat dan log tempatan yang besar itu sendiri selalunya cukup untuk menyiasat insiden.
  • Kami mempunyai projek yang dibuat dengan ujian berfungsi secara eksklusif dan sistem pengumpulan ralat. Pembangun tidak memerlukan log seperti itu - mereka melihat segala-galanya daripada kesan ralat.

Ilustrasi dari kehidupan

Satu lagi cerita boleh dijadikan contoh yang baik. Kami menerima permintaan daripada pasukan keselamatan salah seorang pelanggan kami yang telah menggunakan penyelesaian komersial yang telah dibangunkan lama sebelum pengenalan Kubernetes.

Ia adalah perlu untuk "berteman" sistem pengumpulan log berpusat dengan sensor pengesanan masalah korporat - QRadar. Sistem ini boleh menerima log melalui protokol syslog dan mendapatkannya daripada FTP. Walau bagaimanapun, ia tidak dapat disepadukan dengan serta-merta dengan pemalam remote_syslog untuk fluentd (ternyata, kita tidak keseorangan). Masalah dengan menyediakan QRadar ternyata berada di pihak pasukan keselamatan pelanggan.

Akibatnya, sebahagian daripada log kritikal perniagaan telah dimuat naik ke FTP QRadar, dan sebahagian lagi telah diubah hala melalui syslog jauh terus dari nod. Untuk ini kami juga menulis carta ringkas - mungkin ia akan membantu seseorang menyelesaikan masalah yang sama... Terima kasih kepada skema yang terhasil, pelanggan sendiri menerima dan menganalisis log kritikal (menggunakan alat kegemarannya), dan kami dapat mengurangkan kos sistem pembalakan, hanya menjimatkan bulan lepas.

Contoh lain agak menunjukkan apa yang tidak boleh dilakukan. Salah seorang pelanggan kami untuk pemprosesan masing-masing acara yang datang daripada pengguna, dibuat berbilang talian keluaran tidak berstruktur maklumat dalam log. Seperti yang anda fikirkan, log sedemikian amat menyusahkan untuk dibaca dan disimpan.

Kriteria untuk log

Contoh sedemikian membawa kepada kesimpulan bahawa selain memilih sistem pengumpulan log, anda perlu juga mereka bentuk log itu sendiri! Apakah syarat di sini?

  • Log mestilah dalam format yang boleh dibaca mesin (contohnya, JSON).
  • Log harus padat dan dengan keupayaan untuk mengubah tahap pembalakan untuk menyahpepijat kemungkinan masalah. Pada masa yang sama, dalam persekitaran pengeluaran anda harus menjalankan sistem dengan tahap pembalakan seperti Amaran atau ralat.
  • Log mesti dinormalisasi, iaitu, dalam objek log, semua baris mesti mempunyai jenis medan yang sama.

Log tidak berstruktur boleh membawa kepada masalah dengan memuatkan log ke dalam storan dan menghentikan sepenuhnya pemprosesannya. Sebagai ilustrasi, berikut ialah contoh dengan ralat 400, yang pasti ramai ditemui dalam log lancar:

2019-10-29 13:10:43 +0000 [warn]: dump an error event: error_class=Fluent::Plugin::ElasticsearchErrorHandler::ElasticsearchError error="400 - Rejected by Elasticsearch"

Ralat bermakna anda menghantar medan yang jenisnya tidak stabil kepada indeks dengan pemetaan sedia dibuat. Contoh paling mudah ialah medan dalam log nginx dengan pembolehubah $upstream_status. Ia boleh mengandungi sama ada nombor atau rentetan. Sebagai contoh:

{ "ip": "1.2.3.4", "http_user": "-", "request_id": "17ee8a579e833b5ab9843a0aca10b941", "time": "29/Oct/2019:16:18:57 +0300", "method": "GET", "uri": "/staffs/265.png", "protocol": "HTTP/1.1", "status": "200", "body_size": "906", "referrer": "https://example.com/staff", "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36", "request_time": "0.001", "cache_status": "-", "upstream_response_time": "0.001, 0.007", "upstream_addr": "127.0.0.1:9000", "upstream_status": "200", "upstream_response_length": "906", "location": "staff"}
{ "ip": "1.2.3.4", "http_user": "-", "request_id": "47fe42807f2a7d8d5467511d7d553a1b", "time": "29/Oct/2019:16:18:57 +0300", "method": "GET", "uri": "/staff", "protocol": "HTTP/1.1", "status": "200", "body_size": "2984", "referrer": "-", "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36", "request_time": "0.010", "cache_status": "-", "upstream_response_time": "0.001, 0.007", "upstream_addr": "10.100.0.10:9000, 10.100.0.11:9000", "upstream_status": "404, 200", "upstream_response_length": "0, 2984", "location": "staff"}

Log menunjukkan bahawa pelayan 10.100.0.10 bertindak balas dengan ralat 404 dan permintaan telah dihantar ke storan kandungan lain. Akibatnya, nilai dalam log menjadi seperti ini:

"upstream_response_time": "0.001, 0.007"

Keadaan ini adalah perkara biasa sehingga ia patut diasingkan rujukan dalam dokumentasi.

Bagaimana pula dengan kebolehpercayaan?

Ada kalanya semua log tanpa pengecualian adalah penting. Dan dengan ini, skim pengumpulan log biasa untuk K8 yang dicadangkan/dibincangkan di atas mempunyai masalah.

Sebagai contoh, fluentd tidak boleh mengumpul log daripada bekas jangka pendek. Dalam salah satu projek kami, bekas migrasi pangkalan data bertahan kurang daripada 4 saat dan kemudian dipadamkan - mengikut anotasi yang sepadan:

"helm.sh/hook-delete-policy": hook-succeeded

Oleh sebab itu, log pelaksanaan migrasi tidak disertakan dalam storan. Politik boleh membantu dalam kes ini. before-hook-creation.

Contoh lain ialah putaran log Docker. Katakan ada aplikasi yang aktif menulis pada log. Di bawah keadaan biasa, kami berjaya memproses semua log, tetapi sebaik sahaja masalah muncul - contohnya, seperti yang diterangkan di atas dengan format yang salah - pemprosesan berhenti, dan Docker memutar fail. Hasilnya ialah log kritikal perniagaan mungkin hilang.

Itulah sebabnya adalah penting untuk memisahkan aliran log, membenamkan menghantar yang paling berharga terus ke dalam aplikasi untuk memastikan keselamatan mereka. Di samping itu, ia tidak akan berlebihan untuk mencipta beberapa β€œpengumpul” kayu balak, yang boleh bertahan dengan ketiadaan storan ringkas sambil menyimpan mesej kritikal.

Akhirnya, kita tidak boleh melupakannya Adalah penting untuk memantau mana-mana subsistem dengan betul. Jika tidak, mudah untuk menghadapi situasi di mana fasih berada dalam keadaan CrashLoopBackOff dan tidak menghantar apa-apa, dan ini menjanjikan kehilangan maklumat penting.

Penemuan

Dalam artikel ini, kami tidak melihat penyelesaian SaaS seperti Datadog. Banyak masalah yang diterangkan di sini telah diselesaikan dalam satu cara atau yang lain oleh syarikat komersial yang pakar dalam mengumpul log, tetapi tidak semua orang boleh menggunakan SaaS atas pelbagai sebab (yang utama ialah kos dan pematuhan 152-FZ).

Pengumpulan log berpusat pada mulanya kelihatan seperti tugas yang mudah, tetapi ia tidak sama sekali. Adalah penting untuk diingat bahawa:

  • Hanya komponen kritikal perlu dilog secara terperinci, manakala pemantauan dan pengumpulan ralat boleh dikonfigurasikan untuk sistem lain.
  • Log dalam pengeluaran harus disimpan minimum supaya tidak menambah beban yang tidak perlu.
  • Log mesti boleh dibaca mesin, dinormalkan dan mempunyai format yang ketat.
  • Log yang benar-benar kritikal harus dihantar dalam aliran berasingan, yang harus dipisahkan daripada yang utama.
  • Perlu dipertimbangkan akumulator log, yang boleh menyelamatkan anda daripada letupan beban tinggi dan menjadikan beban pada storan lebih seragam.

Log masuk Kubernetes (dan bukan sahaja) hari ini: jangkaan dan realiti
Peraturan mudah ini, jika digunakan di mana-mana, akan membenarkan litar yang diterangkan di atas berfungsi - walaupun ia kehilangan komponen penting (bateri). Jika anda tidak mematuhi prinsip sedemikian, tugas itu akan membawa anda dan infrastruktur dengan mudah ke satu lagi komponen sistem yang sangat sarat (dan pada masa yang sama tidak berkesan).

PS

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komen