Gambar siap produksi untuk k8s

Kisah ini tentang bagaimana kami menggunakan container di lingkungan produksi, khususnya Kubernetes. Artikel ini dikhususkan untuk mengumpulkan metrik dan log dari container, serta membuat gambar.

Gambar siap produksi untuk k8s

Kami dari perusahaan fintech Exness yang mengembangkan layanan perdagangan online dan produk fintech untuk B2B dan B2C. Litbang kami memiliki banyak tim berbeda, departemen pengembangan memiliki 100+ karyawan.

Kami mewakili tim yang bertanggung jawab atas platform bagi pengembang kami untuk mengumpulkan dan menjalankan kode. Secara khusus, kami bertanggung jawab untuk mengumpulkan, menyimpan, dan melaporkan metrik, log, dan peristiwa dari aplikasi. Saat ini kami mengoperasikan sekitar tiga ribu container Docker di lingkungan produksi, memelihara penyimpanan data besar sebesar 50 TB, dan menyediakan solusi arsitektur yang dibangun berdasarkan infrastruktur kami: Kubernetes, Rancher, dan berbagai penyedia cloud publik. 

Motivasi kami

Apa yang terbakar? Tidak ada yang bisa menjawab. Dimana perapiannya? Sulit untuk dipahami. Kapan itu terbakar? Anda bisa mengetahuinya, tetapi tidak segera. 

Gambar siap produksi untuk k8s

Mengapa beberapa kontainer berdiri sementara yang lain jatuh? Wadah mana yang harus disalahkan? Lagi pula, bagian luar wadahnya sama, tetapi di dalamnya masing-masing wadah memiliki Neo sendiri.

Gambar siap produksi untuk k8s

Pengembang kami adalah orang-orang yang kompeten. Mereka memberikan pelayanan yang baik sehingga mendatangkan keuntungan bagi perusahaan. Namun ada kegagalan ketika container dengan aplikasi tersesat. Satu kontainer menghabiskan terlalu banyak CPU, yang lain menghabiskan jaringan, yang ketiga menghabiskan operasi I/O, dan yang keempat sama sekali tidak jelas apa fungsinya dengan soket. Semuanya jatuh dan kapal tenggelam. 

Agen

Untuk memahami apa yang terjadi di dalam, kami memutuskan untuk menempatkan agen langsung di dalam wadah.

Gambar siap produksi untuk k8s

Agen-agen ini membatasi program yang menjaga kontainer dalam kondisi sedemikian rupa sehingga tidak saling menghancurkan. Agen terstandarisasi, dan ini memungkinkan adanya pendekatan standar dalam melayani kontainer. 

Dalam kasus kami, agen harus menyediakan log dalam format standar, diberi tag, dan dibatasi. Mereka juga harus memberi kita metrik terstandar yang dapat diperluas dari perspektif aplikasi bisnis.

Agen juga berarti utilitas untuk pengoperasian dan pemeliharaan yang dapat bekerja dalam sistem orkestrasi berbeda yang mendukung image berbeda (Debian, Alpine, Centos, dll.).

Terakhir, agen harus mendukung CI/CD sederhana yang menyertakan file Docker. Jika tidak, kapal akan hancur, karena kontainer akan mulai dikirim melalui rel yang “bengkok”.

Membangun proses dan menargetkan perangkat gambar

Untuk menjaga semuanya tetap terstandar dan dapat dikelola, beberapa jenis proses pembangunan standar perlu diikuti. Oleh karena itu, kami memutuskan untuk mengumpulkan kontainer demi kontainer - ini adalah rekursi.

Gambar siap produksi untuk k8s

Di sini wadah diwakili oleh garis padat. Pada saat yang sama, mereka memutuskan untuk memasukkan peralatan distribusi ke dalamnya sehingga “hidup tidak tampak seperti raspberry.” Mengapa hal ini dilakukan, akan kami jelaskan di bawah.
 
Hasilnya adalah alat pembangunan—wadah khusus versi yang mereferensikan versi distribusi dan versi skrip tertentu.

bagaimana kami menggunakannya? Kami memiliki Docker Hub yang berisi sebuah container. Kami mencerminkannya di dalam sistem kami untuk menghilangkan ketergantungan eksternal. Hasilnya adalah wadah bertanda kuning. Kami membuat template untuk menginstal semua distribusi dan skrip yang kami perlukan ke dalam wadah. Setelah itu, kami merakit gambar yang siap digunakan: pengembang memasukkan kode dan beberapa dependensi khusus mereka ke dalamnya. 

Apa bagusnya pendekatan ini? 

  • Pertama, kontrol versi lengkap alat build - versi container build, skrip, dan distribusi. 
  • Kedua, kami telah mencapai standarisasi: kami membuat templat, gambar perantara, dan gambar siap pakai dengan cara yang sama. 
  • Ketiga, kontainer memberi kita portabilitas. Hari ini kami menggunakan Gitlab, dan besok kami akan beralih ke TeamCity atau Jenkins dan kami akan dapat menjalankan container kami dengan cara yang sama. 
  • Keempat, meminimalkan ketergantungan. Bukan suatu kebetulan jika kami memasukkan kit distribusi ke dalam wadah, karena hal ini memungkinkan kami menghindari pengunduhan dari Internet setiap saat. 
  • Kelima, kecepatan pembuatan meningkat - kehadiran salinan gambar lokal memungkinkan Anda tidak membuang waktu untuk mengunduh, karena ada gambar lokal. 

Dengan kata lain, kami telah mencapai proses perakitan yang terkendali dan fleksibel. Kami menggunakan alat yang sama untuk membuat container berversi lengkap. 

Cara kerja prosedur pembangunan kami

Gambar siap produksi untuk k8s

Perakitan diluncurkan dengan satu perintah, proses dijalankan pada gambar (disorot dengan warna merah). Pengembang memiliki file Docker (disorot dengan warna kuning), kami merendernya, mengganti variabel dengan nilai. Dan sepanjang jalan kami menambahkan header dan footer - ini adalah agen kami. 

Header menambahkan distribusi dari gambar yang sesuai. Dan footer menginstal layanan kami di dalamnya, mengonfigurasi peluncuran beban kerja, logging dan agen lainnya, menggantikan titik masuk, dll. 

Gambar siap produksi untuk k8s

Kami berpikir lama apakah akan memasang supervisor. Pada akhirnya, kami memutuskan bahwa kami membutuhkannya. Kami memilih S6. Supervisor menyediakan manajemen kontainer: memungkinkan Anda untuk menyambungkannya jika proses utama mogok dan menyediakan manajemen kontainer secara manual tanpa membuatnya ulang. Log dan metrik adalah proses yang berjalan di dalam container. Mereka juga perlu dikontrol, dan kami melakukan ini dengan bantuan seorang supervisor. Terakhir, S6 menangani pekerjaan rumah tangga, pemrosesan sinyal, dan tugas lainnya.

Karena kami menggunakan sistem orkestrasi yang berbeda, setelah dibuat dan dijalankan, container harus memahami lingkungannya dan bertindak sesuai dengan situasinya. Misalnya:
Hal ini memungkinkan kami membuat satu gambar dan menjalankannya dalam sistem orkestrasi yang berbeda, dan gambar tersebut akan diluncurkan dengan mempertimbangkan spesifikasi sistem orkestrasi ini.

 Gambar siap produksi untuk k8s

Untuk container yang sama kita mendapatkan pohon proses yang berbeda di Docker dan Kubernetes:

Gambar siap produksi untuk k8s

Payload dijalankan di bawah pengawasan S6. Perhatikan kolektor dan peristiwa - ini adalah agen kami yang bertanggung jawab atas log dan metrik. Kubernetes tidak memilikinya, tetapi Docker memilikinya. Mengapa? 

Jika kita melihat spesifikasi “pod” (selanjutnya – pod Kubernetes), kita akan melihat bahwa kontainer peristiwa dieksekusi dalam sebuah pod, yang memiliki wadah kolektor terpisah yang menjalankan fungsi mengumpulkan metrik dan log. Kita dapat menggunakan kemampuan Kubernetes: menjalankan container dalam satu pod, dalam satu proses dan/atau ruang jaringan. Sebenarnya perkenalkan agen Anda dan lakukan beberapa fungsi. Dan jika container yang sama diluncurkan di Docker, container tersebut akan menerima semua kemampuan yang sama seperti outputnya, yaitu, container tersebut akan dapat mengirimkan log dan metrik, karena agen akan diluncurkan secara internal. 

Metrik dan log

Menyampaikan metrik dan log adalah tugas yang kompleks. Ada beberapa aspek dalam keputusannya.
Infrastruktur dibuat untuk pelaksanaan muatan, dan bukan untuk pengiriman kayu secara massal. Artinya, proses ini harus dilakukan dengan kebutuhan sumber daya kontainer yang minimal. Kami berupaya membantu pengembang kami: “Dapatkan container Docker Hub, jalankan, dan kami dapat mengirimkan lognya.” 

Aspek kedua adalah membatasi volume kayu gelondongan. Jika lonjakan volume log terjadi di beberapa kontainer (aplikasi mengeluarkan jejak tumpukan dalam satu lingkaran), beban pada CPU, saluran komunikasi, dan sistem pemrosesan log meningkat, dan ini memengaruhi pengoperasian host sebagai a keseluruhan dan container lainnya pada host, maka terkadang hal ini menyebabkan "jatuhnya" host. 

Aspek ketiga adalah perlunya mendukung sebanyak mungkin metode pengumpulan metrik. Dari membaca file dan melakukan polling titik akhir Prometheus hingga menggunakan protokol khusus aplikasi.

Dan aspek terakhir adalah meminimalkan konsumsi sumber daya.

Kami memilih solusi Go open-source yang disebut Telegraf. Ini adalah konektor universal yang mendukung lebih dari 140 jenis saluran masukan (plugin masukan) dan 30 jenis saluran keluaran (plugin keluaran). Kami telah menyelesaikannya dan sekarang kami akan memberi tahu Anda cara kami menggunakannya menggunakan Kubernetes sebagai contoh. 

Gambar siap produksi untuk k8s

Katakanlah seorang pengembang menyebarkan beban kerja dan Kubernetes menerima permintaan untuk membuat pod. Pada titik ini, sebuah container bernama Collector secara otomatis dibuat untuk setiap pod (kami menggunakan webhook mutasi). Kolektor adalah agen kami. Pada awalnya, kontainer ini mengonfigurasi dirinya sendiri agar berfungsi dengan Prometheus dan sistem pengumpulan log.

  • Untuk melakukan hal ini, ia menggunakan anotasi pod, dan bergantung pada kontennya, ia membuat, katakanlah, titik akhir Prometheus; 
  • Berdasarkan spesifikasi pod dan pengaturan kontainer tertentu, pod memutuskan cara mengirimkan log.

Kami mengumpulkan log melalui Docker API: pengembang hanya perlu memasukkannya ke dalam stdout atau stderr, dan Collector akan menyelesaikannya. Log dikumpulkan dalam beberapa bagian dengan beberapa penundaan untuk mencegah kemungkinan kelebihan host. 

Metrik dikumpulkan di seluruh instans beban kerja (proses) dalam kontainer. Semuanya diberi tag: namespace, under, dan seterusnya, lalu dikonversi ke format Prometheus - dan tersedia untuk koleksi (kecuali log). Kami juga mengirimkan log, metrik, dan peristiwa ke Kafka dan selanjutnya:

  • Log tersedia di Graylog (untuk analisis visual);
  • Log, metrik, peristiwa dikirim ke Clickhouse untuk penyimpanan jangka panjang.

Semuanya bekerja persis sama di AWS, hanya saja kami mengganti Graylog dengan Kafka dengan Cloudwatch. Kami mengirimkan log ke sana, dan semuanya menjadi sangat mudah: segera terlihat jelas di cluster dan container mana mereka berada. Hal yang sama berlaku untuk Google Stackdriver. Artinya, skema kami berfungsi baik di lokasi dengan Kafka maupun di cloud. 

Jika kita tidak memiliki Kubernetes dengan pod, skemanya akan sedikit lebih rumit, tetapi cara kerjanya menggunakan prinsip yang sama.

Gambar siap produksi untuk k8s

Proses yang sama dijalankan di dalam container, dan diatur menggunakan S6. Semua proses yang sama berjalan di dalam wadah yang sama.

Sebagai hasilnya,

Kami telah menciptakan solusi lengkap untuk membuat dan meluncurkan gambar, dengan opsi untuk mengumpulkan dan mengirimkan log dan metrik:

  • Kami mengembangkan pendekatan standar untuk merakit gambar, dan berdasarkan pendekatan tersebut kami mengembangkan templat CI;
  • Agen pengumpulan data adalah ekstensi Telegraf kami. Kami mengujinya dengan baik dalam produksi;
  • Kami menggunakan webhook mutasi untuk mengimplementasikan container dengan agen di pod; 
  • Terintegrasi ke dalam ekosistem Kubernetes/Rancher;
  • Kita dapat menjalankan container yang sama dalam sistem orkestrasi yang berbeda dan mendapatkan hasil yang kita harapkan;
  • Membuat konfigurasi manajemen kontainer yang sepenuhnya dinamis. 

Rekan penulis: Ilya Prudnikov

Sumber: www.habr.com

Tambah komentar