Log in Kubernetes (dan tidak hanya) hari ini: ekspektasi dan kenyataan

Log in Kubernetes (dan tidak hanya) hari ini: ekspektasi dan kenyataan

Ini tahun 2019, dan kami masih belum memiliki solusi standar untuk agregasi log di Kubernetes. Dalam artikel ini, kami ingin, dengan menggunakan contoh dari praktik nyata, untuk berbagi pencarian kami, masalah yang dihadapi dan solusinya.

Namun, pertama-tama, saya akan membuat reservasi agar pelanggan yang berbeda memahami hal yang sangat berbeda dengan mengumpulkan log:

  • seseorang ingin melihat log keamanan dan audit;
  • seseorang - penebangan terpusat dari seluruh infrastruktur;
  • dan bagi sebagian orang, cukup mengumpulkan log aplikasi saja, tidak termasuk, misalnya, penyeimbang.

О том, как мы реализовывали различные «хотелки» и с какими трудностями столкнулись, — под катом.

Теория: об инструментах для логов

Latar belakang komponen sistem logging

Penebangan kayu telah berkembang pesat, sebagai hasilnya metodologi untuk mengumpulkan dan menganalisis kayu telah dikembangkan, dan itulah yang kami gunakan saat ini. Pada tahun 1950-an, Fortran memperkenalkan analogi aliran input/output standar, yang membantu programmer melakukan debug pada programnya. Ini adalah log komputer pertama yang membuat hidup lebih mudah bagi para programmer pada masa itu. Hari ini kita melihat di dalamnya komponen pertama dari sistem logging - источник или «производитель» (producer) логов.

Ilmu komputer tidak tinggal diam: jaringan komputer muncul, cluster pertama... Sistem kompleks yang terdiri dari beberapa komputer mulai bekerja. Sekarang administrator sistem terpaksa mengumpulkan log dari beberapa mesin, dan dalam kasus khusus mereka dapat menambahkan pesan kernel OS jika mereka perlu menyelidiki kegagalan sistem. Untuk menggambarkan sistem pengumpulan kayu terpusat, sistem ini diterbitkan pada awal tahun 2000an RFC 3164, yang menstandarkan remote_syslog. Ini adalah bagaimana komponen penting lainnya muncul: pengumpul log dan penyimpanannya.

Dengan meningkatnya volume log dan meluasnya pengenalan teknologi web, muncul pertanyaan tentang log apa yang perlu ditampilkan dengan mudah kepada pengguna. Alat konsol sederhana (awk/sed/grep) telah digantikan oleh alat yang lebih canggih просмотрщики логов — третий компонент.

В связи с увеличением объема логов стало ясно и другое: логи нужны, но не все. А ещё разные логи требуют разного уровня сохранности: одни можно потерять через день, а другие — надо хранить 5 лет. Так в систему логирования добавился компонент фильтрации и маршрутизации потоков данных — назовём его фильтром.

Penyimpanan juga mengalami lompatan besar: dari file biasa ke database relasional, dan kemudian ke penyimpanan berorientasi dokumen (misalnya, Elasticsearch). Jadi tempat penyimpanannya terpisah dari pengumpul.

Pada akhirnya, konsep log telah berkembang menjadi semacam aliran peristiwa abstrak yang ingin kita simpan untuk sejarah. Atau lebih tepatnya, jika Anda perlu melakukan penyelidikan atau menyusun laporan analitis...

В итоге, за сравнительно небольшой промежуток времени, сбор логов развился в важную подсистему, которую по праву можно назвать одним из подразделов в Big Data.

Log in Kubernetes (dan tidak hanya) hari ini: ekspektasi dan kenyataan
Jika dulu cetakan biasa saja sudah cukup untuk “sistem pencatatan”, kini situasinya telah banyak berubah.

Kubernet dan log

Ketika Kubernetes hadir dalam infrastruktur tersebut, masalah pengumpulan log yang sudah ada juga tidak dapat diabaikan. Dalam beberapa hal, hal ini menjadi lebih menyakitkan: pengelolaan platform infrastruktur tidak hanya disederhanakan, tetapi juga rumit pada saat yang bersamaan. Banyak layanan lama mulai bermigrasi ke layanan mikro. Dalam konteks log, hal ini tercermin dalam semakin banyaknya sumber log, siklus hidup khususnya, dan kebutuhan untuk melacak hubungan semua komponen sistem melalui log...

Ke depan, saya dapat menyatakan bahwa saat ini, sayangnya, tidak ada opsi logging standar untuk Kubernetes yang dapat dibandingkan dengan opsi logging lainnya. Skema yang paling populer di masyarakat adalah sebagai berikut:

  • seseorang membuka gulungan tumpukan itu EFK (Elasticsearch, Lancar, Kibana);
  • кто-то — пробует недавно выпущенный Loki atau kegunaan Operator pencatatan;
  • kita (dan mungkin bukan hanya kita?..) Saya sangat puas dengan perkembangan saya sendiri - rumah kayu...

Как правило, мы используем такие связки в K8s-кластерах (для self-hosted-решений):

Однако не буду останавливаться на инструкциях по их установке и конфигурации. Вместо этого, сфокусируюсь на их недостатках и более глобальных выводах по ситуации с логами в целом.

Berlatih dengan log di K8s

Log in Kubernetes (dan tidak hanya) hari ini: ekspektasi dan kenyataan

“Log harian”, berapa banyak dari Anda yang ada di sana?..

Pengumpulan kayu bulat secara terpusat dari infrastruktur yang cukup besar memerlukan sumber daya yang besar, yang akan dihabiskan untuk pengumpulan, penyimpanan dan pengolahan kayu bulat. Selama pengoperasian berbagai proyek, kami dihadapkan pada berbagai persyaratan dan permasalahan operasional yang timbul darinya.

Попробуем ClickHouse

Mari kita lihat penyimpanan terpusat pada sebuah proyek dengan aplikasi yang menghasilkan log dengan cukup aktif: lebih dari 5000 baris per detik. Mari kita mulai mengerjakan lognya, menambahkannya ke ClickHouse.

Как только потребуется максимальный realtime, 4-ядерный сервер с ClickHouse уже будет перегружен по дисковой подсистеме:

Log in Kubernetes (dan tidak hanya) hari ini: ekspektasi dan kenyataan

Jenis pemuatan ini disebabkan oleh fakta bahwa kami mencoba menulis di ClickHouse secepat mungkin. Dan database bereaksi terhadap hal ini dengan peningkatan beban disk, yang dapat menyebabkan kesalahan berikut:

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

Fakta adalah bahwa Tabel GabungTree di ClickHouse (berisi data log) memiliki kesulitannya sendiri selama operasi penulisan. Data yang dimasukkan ke dalamnya menghasilkan partisi sementara, yang kemudian digabungkan dengan tabel utama. Akibatnya, perekaman menjadi sangat menuntut pada disk, dan juga tunduk pada batasan yang kami terima pemberitahuan di atas: tidak lebih dari 1 subpartisi dapat digabungkan dalam 300 detik (sebenarnya, ini adalah 300 sisipan per detik).

Untuk menghindari perilaku ini, следует писать в ClickHouse dalam potongan sebesar mungkin dan tidak lebih dari 1 kali setiap 2 detik. Namun, menulis dalam jumlah besar menyarankan agar kita lebih jarang menulis di ClickHouse. Hal ini, pada gilirannya, dapat menyebabkan buffer overflow dan hilangnya log. Solusinya adalah dengan meningkatkan buffer Fluentd, tetapi konsumsi memori juga akan meningkat.

Catatan: Другая проблемная сторона нашего решения с ClickHouse была связана с тем, что партицирование в нашем случае (loghouse) реализовано через внешние таблицы, связанные Gabungkan tabel. Hal ini mengarah pada fakta bahwa ketika mengambil sampel interval waktu yang besar, diperlukan RAM yang berlebihan, karena metatabel melakukan iterasi melalui semua partisi - bahkan partisi yang jelas-jelas tidak berisi data yang diperlukan. Namun, sekarang pendekatan ini dapat dengan aman dinyatakan usang untuk versi ClickHouse saat ini (c 18.16).

Akibatnya, menjadi jelas bahwa tidak setiap proyek memiliki sumber daya yang cukup untuk mengumpulkan log secara real time di ClickHouse (lebih tepatnya, distribusinya tidak sesuai). Selain itu, Anda perlu menggunakannya akumulator, yang akan kita kembalikan nanti. Kasus yang dijelaskan di atas adalah nyata. Dan pada saat itu kami tidak dapat menawarkan solusi yang andal dan stabil yang sesuai dengan pelanggan dan memungkinkan kami mengumpulkan log dengan penundaan minimal...

Bagaimana dengan Elasticsearch?

Известно, что Elasticsearch справляется с большими нагрузками. Попробуем его в том же проекте. Теперь нагрузка выглядит следующим образом:

Log in Kubernetes (dan tidak hanya) hari ini: ekspektasi dan kenyataan

Elasticsearch mampu mencerna aliran data, namun, menulis volume seperti itu ke dalamnya akan sangat memanfaatkan CPU. Hal ini diputuskan dengan mengorganisir sebuah cluster. Secara teknis hal ini tidak menjadi masalah, namun ternyata untuk mengoperasikan sistem pengumpulan log saja kita sudah menggunakan sekitar 8 core dan memiliki komponen tambahan yang sarat muatan di sistem...

Итог: такой вариант может быть оправдан, но только в том случае, если проект большой и его руководство готово потратить заметные ресурсы на систему централизованного логирования.

Kemudian muncul pertanyaan wajar:

Log apa yang benar-benar dibutuhkan?

Log in Kubernetes (dan tidak hanya) hari ini: ekspektasi dan kenyataan Mari kita coba mengubah pendekatan itu sendiri: log harus bersifat informatif dan tidak menutupi setiap peristiwa dalam sistem.

Katakanlah kita memiliki toko online yang sukses. Log apa yang penting? Mengumpulkan informasi sebanyak mungkin, misalnya dari gateway pembayaran, adalah ide bagus. Namun tidak semua log dari layanan pemotongan gambar di katalog produk penting bagi kami: hanya kesalahan dan pemantauan lanjutan yang cukup (misalnya, persentase 500 kesalahan yang dihasilkan komponen ini).

Jadi kami sampai pada kesimpulan itu централизованное логирование оправдано далеко не всегда. Seringkali klien ingin mengumpulkan semua log di satu tempat, meskipun pada kenyataannya, dari keseluruhan log, hanya diperlukan 5% pesan bersyarat yang penting untuk bisnis:

  • Иногда достаточно настроить, скажем, только размер лога контейнера и сборщик ошибок (например, Sentry).
  • Pemberitahuan kesalahan dan log lokal yang besar seringkali cukup untuk menyelidiki insiden.
  • Kami memiliki proyek yang hanya menggunakan pengujian fungsional dan sistem pengumpulan kesalahan. Pengembang tidak memerlukan log seperti itu - mereka melihat semuanya dari jejak kesalahan.

Ilustrasi dari kehidupan

Kisah lain bisa menjadi contoh yang baik. Kami menerima permintaan dari tim keamanan salah satu klien kami yang sudah menggunakan solusi komersial yang dikembangkan jauh sebelum diperkenalkannya Kubernetes.

Потребовалось «подружить» систему централизованного сбора логов с корпоративным сенсором обнаружения проблем — QRadar. Эта система умеет принимать логи по протоколу syslog, забирать c FTP. Однако интегрировать её с плагином remote_syslog для fluentd сразу не получилось (ternyata, kita tidak sendirian). Проблемы с настройкой QRadar оказались на стороне команды безопасников клиента.

В результате, часть логов, критичных для бизнеса, выгружалась на FTP QRadar, а другая часть — перенаправлялась через remote syslog напрямую с узлов. Для этого мы даже написали grafik sederhana - mungkin ini akan membantu seseorang memecahkan masalah serupa... Berkat skema yang dihasilkan, klien sendiri menerima dan menganalisis log penting (menggunakan alat favoritnya), dan kami dapat mengurangi biaya sistem logging, hanya menghemat biaya bulan lalu.

Ещё один пример довольно показателен в том, как делать не следует. Один из наших клиентов на обработку dari masing-masing acara yang datang dari pengguna, dibuat multiline keluaran tidak terstruktur информации в лог. Как легко догадаться, подобные логи было крайне неудобно и читать, и хранить.

Критерии для логов

Подобные примеры подводят к заключение, что кроме выбора системы сбора логов надо juga mendesain lognya sendiri! Apa saja persyaratannya di sini?

  • Log harus dalam format yang dapat dibaca mesin (misalnya JSON).
  • Log harus kompak dan memiliki kemampuan untuk mengubah tingkat logging untuk men-debug kemungkinan masalah. Pada saat yang sama, dalam lingkungan produksi Anda harus menjalankan sistem dengan tingkat logging seperti peringatan или error.
  • Log harus dinormalisasi, yaitu dalam objek log, semua baris harus memiliki tipe kolom yang sama.

Log yang tidak terstruktur dapat menyebabkan masalah saat memuat log ke dalam penyimpanan dan penghentian total pemrosesannya. Sebagai ilustrasi, berikut adalah contoh error 400 yang pasti banyak ditemui di log fluentd:

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

Kesalahannya berarti Anda mengirimkan bidang yang tipenya tidak stabil ke indeks dengan pemetaan yang sudah jadi. Contoh paling sederhana adalah field di log nginx dengan variabel $upstream_status. В нём может быть как число, так и строка. Например:

{ "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 bahwa server 10.100.0.10 merespons dengan kesalahan 404 dan permintaan dikirim ke penyimpanan konten lain. Hasilnya, nilai di log menjadi seperti ini:

"upstream_response_time": "0.001, 0.007"

Situasi ini sangat umum sehingga layak untuk dipisahkan упоминания в документации.

А что с надёжностью?

Ada kalanya semua log tanpa kecuali sangat penting. Oleh karena itu, skema pengumpulan kayu untuk K8 yang diusulkan/dibahas di atas mempunyai permasalahan.

Misalnya, fluentd tidak dapat mengumpulkan kayu dari kontainer yang berumur pendek. Di salah satu proyek kami, wadah migrasi basis data hidup kurang dari 4 detik dan kemudian dihapus - sesuai dengan anotasi yang sesuai:

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

Oleh karena itu, log eksekusi migrasi tidak disertakan dalam penyimpanan. Politik dapat membantu dalam hal ini. before-hook-creation.

Contoh lainnya adalah rotasi log Docker. Katakanlah ada aplikasi yang aktif menulis ke log. Dalam kondisi normal, kami berhasil memproses semua log, tetapi segera setelah masalah muncul - misalnya, seperti dijelaskan di atas dengan format yang salah - pemrosesan berhenti, dan Docker memutar file. Dampaknya adalah log yang penting bagi bisnis mungkin hilang.

Itu sebabnya penting untuk memisahkan aliran log, menyematkan pengiriman barang-barang paling berharga langsung ke dalam aplikasi untuk memastikan keamanannya. Selain itu, tidak akan berlebihan untuk membuatnya «аккумулятора» логов, yang dapat bertahan dari ketidaktersediaan penyimpanan singkat sekaligus menyimpan pesan penting.

Terakhir, kita tidak boleh melupakan hal itu любую подсистему важно качественно мониторить. Jika tidak, akan mudah untuk mengalami situasi di mana fasih berada dalam kondisi tersebut CrashLoopBackOff и ничего не отправляет, а это сулит потерей важной информации.

Temuan

Pada artikel ini, kami tidak membahas solusi SaaS seperti Datadog. Banyak masalah yang dijelaskan di sini telah diselesaikan dengan satu atau lain cara oleh perusahaan komersial yang berspesialisasi dalam pengumpulan log, namun tidak semua orang dapat menggunakan SaaS karena berbagai alasan. (yang utama adalah biaya dan kepatuhan terhadap 152-FZ).

Pengumpulan log terpusat pada awalnya terlihat seperti tugas yang sederhana, namun sebenarnya tidak sama sekali. Penting untuk diingat bahwa:

  • Логировать подробно стоит только критичные компоненты, а для остальных систем можно настроить мониторинг и сбор ошибок.
  • Log dalam produksi harus dijaga seminimal mungkin agar tidak menambah beban yang tidak diperlukan.
  • Log harus dapat dibaca mesin, dinormalisasi, dan memiliki format yang ketat.
  • Действительно критичные логи стоит отправлять отдельным потоком, который должен быть отделён от основных.
  • Стоит продумать аккумулятор логов, который может спасти от всплесков высокой нагрузки и сделает нагрузку на хранилище более равномерной.

Log in Kubernetes (dan tidak hanya) hari ini: ekspektasi dan kenyataan
Aturan sederhana ini, jika diterapkan di mana pun, akan memungkinkan rangkaian yang dijelaskan di atas berfungsi - meskipun tidak ada komponen penting (baterai). Jika Anda tidak mematuhi prinsip-prinsip tersebut, tugas tersebut akan dengan mudah membawa Anda dan infrastruktur ke komponen sistem yang sarat muatan (dan pada saat yang sama tidak efektif).

PS

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komentar