GNU/Linux >> Belajar Linux >  >> Linux

Pemecahan masalah Linux:Menavigasi dalam badai yang sempurna

Di DevOps, salah satu masalah yang paling sulit adalah mereka yang secara aktif memblokir penyelidikan mereka sendiri. Dalam perebutan gelar juara, jenis masalah terburuk kedua adalah masalah yang terjadi sebentar-sebentar. Artikel ini adalah kisah petualangan saat sistem Continuous Integration/Continuous Deployment (CI/CD) hulu Podman mengalami keduanya secara bersamaan.

Badai yang sempurna

Sekali waktu, otomatisasi pengujian Podman mulai melampaui celana "anak besar". Ini terjadi bertahun-tahun yang lalu, ketika hampir semua sistem CI/CD berbasis container. Podman, sebagai alat manajemen container (dan pod) (dan debugging), tidak dapat sepenuhnya dijalankan di dalam sebuah container. Mungkin lebih buruk, sebagian besar layanan otomasi komoditas hanya mendukung Ubuntu. Ini dengan cepat menjadi non-starter mutlak, karena Podman perlu dijalankan di mesin virtual (VM). Itu juga perlu dijalankan melawan beberapa distribusi, termasuk distribusi hulu Red Hat, Fedora.

Memiliki pengalaman dengan alur kerja CI/CD yang dicangkokkan di bawah penyiapan cloud-sdk + SSH (dan/atau Ansible) untuk akses cloud, peningkatan kompleksitas sepertinya selalu menimbulkan masalah. Kemudian suatu hari, saya menemukan Cirrus-CI. Cirrus-CI adalah alat otomatisasi Git-centric yang mampu mengatur container dan VM, menggunakan banyak penyedia cloud. Ini memungkinkan tim Podman membayar dan mengelola layanan cloud secara independen dari orkestrasinya. Kami dapat mempertahankan kontrol penuh atas VM dan data log, dengan Cirrus-CI hanya mengelola orkestrasi.

Alur kerja keseluruhan berjalan seperti ini:

  1. Pengembang mengirimkan perubahan kode yang diusulkan ke hulu ke dalam repositori Git Podman.
  2. Cirrus-CI memberi tahu, membaca file konfigurasi, lalu menjalankan VM yang diperlukan di cloud kami.
  3. Layanan metadata cloud asli mengelola eksekusi skrip dan masuk kembali ke Cirrus-CI.
  4. Cirrus-CI menghapus VM dan memberikan umpan balik lulus/gagal kepada pengembang.
  5. Perubahan dilakukan, dan siklus berulang hingga kode diterima.

Selama bertahun-tahun, alur kerja ini telah beroperasi hampir tanpa cacat, dengan sebagian besar masalah berpusat di sekitar pengujian dan skrip—kesalahan yang mudah dikelola oleh tim Podman. Jarang, masalah dalam Cirrus-CI, Internet, dan/atau penyedia cloud kami mengakibatkan VM yatim piatu (gagal menghapus). Jika tidak, staf pendukung di Cirrus Labs sangat luar biasa, sangat mudah didekati, dengan responsivitas dan akuntabilitas kelas atas.

Kemudian suatu hari di bulan Oktober 2020, setelah merotasi satu set image VM yang baru diperbarui (yaitu, image disk yang disalin untuk setiap instance VM baru), pekerjaan yang tampaknya acak mulai gagal. Penyelidikan awal keluaran skrip tidak memberikan informasi. Secara harfiah, semua output akan tiba-tiba berhenti, tanpa pola yang terlihat relatif terhadap kegagalan lainnya. Seperti yang diharapkan, Cirrus-CI akan rajin membersihkan VM dan menyajikan kegagalan yang dihasilkan kembali ke pengembang untuk mencari tahu. Seringkali setelah menjalankan kembali pekerjaan yang gagal, itu akan berhasil tanpa insiden.

Situasi ini berlangsung selama beberapa minggu tanpa masalah-korespondensi dengan pemadaman infrastruktur apa pun di cloud, GitHub, atau Cirrus kami. Masalahnya agak jarang, mungkin beberapa kegagalan per hari, dari ratusan pekerjaan yang berhasil. Menemukan kesalahan itu sulit, dan terus-menerus menjalankan kembali pekerjaan tidak bisa menjadi solusi jangka panjang. Selain laporan insiden reguler dari tim saya, saya tidak dapat melihat pola tingkat tinggi dari kegagalan. Karena image VM baru memberikan manfaat yang signifikan, biaya untuk melakukan roll back juga akan tinggi.

Untuk hampir semua masalah sistemik seperti ini, menemukan pola perilaku adalah elemen kunci untuk pemecahan masalah yang berhasil. Karena kesuksesan pekerjaan yang andal adalah keadaan yang diinginkan, memiliki setidaknya beberapa gagasan, atau petunjuk, adalah persyaratan yang sulit. Sayangnya, dalam kasus ini, kemampuan kami untuk mengamati pola sangat dibatasi oleh kegagalan acak dan fitur yang sangat diinginkan:Membersihkan VM cloud yang tidak digunakan, yang menghabiskan uang sungguhan.

Eksekusi pengujian manual yang sederhana, berulang, tidak mereproduksi masalah sama sekali. Melempar lebih banyak sumber daya CPU dan memori juga tidak memengaruhi perilaku. Saya menghabiskan waktu berhari-hari untuk merenungkan dan melakukan brainstorming opsi untuk mengumpulkan data tambahan yang terkait dengan kegagalan. Akhirnya, saya tersadar bahwa saya memerlukan cara untuk secara selektif menginterupsi pembersihan VM, tetapi hanya dalam kasus di mana pengujian gagal selesai berjalan.

[ Anda mungkin juga menyukai: Dari sysadmin hingga DevOps ]

Dengan kata lain, saya perlu mengaitkan penyelesaian tes yang berhasil (bukan hanya lulus/gagal) dengan mengizinkan pembersihan terjadi. Saat itulah saya ingat kotak centang kecil yang pernah saya lihat saat melihat-lihat WebUI cloud kami:Deletion Protection . Saat tanda ini disetel, Cirrus-CI akan mengeluh keras karena diblokir untuk menghapus VM, tetapi sebaliknya, hal itu tidak akan terganggu.

Saya perlu melengkapi alur kerja kami sehingga VM itu sendiri dapat mengatur dan menghapus tanda perlindungan penghapusan mereka sendiri. Sesuatu seperti ini:

  1. VM mengaktifkan perlindungan penghapusan sendiri.
  2. Jalankan pengujian.
  3. VM menonaktifkan perlindungan penghapusannya sendiri.
  4. Cirrus-CI membersihkan atau gagal membersihkan VM dan membuatnya bau.

Dengan cara ini, ketika tes selesai, Cirrus-CI akan dengan senang hati menghapus VM seperti biasa. Namun, jika masalah terjadi, pengujian tidak akan selesai, dan Cirrus-CI akan menjalankan perlindungan penghapusan yang diaktifkan (masih). Untungnya, alur kerja ini sepenuhnya mungkin diwujudkan melalui opsi baris perintah sederhana ke program utilitas manajemen cloud yang dapat saya instal di VM.

Dengan instrumentasi alur kerja ini, yang perlu saya lakukan hanyalah memicu matriks pengujian berulang kali dan menunggu VM yatim piatu muncul. Nasib tersenyum pada saya hari itu karena masalah muncul kembali hampir seketika. Namun, saya menjalankannya beberapa kali lagi, jadi saya harus memeriksa lebih dari beberapa VM yatim piatu.

Tanpa diduga, inilah saatnya situasi menjadi lebih menarik:Saya tidak bisa SSH ke VM yatim piatu. Bahkan, mereka bahkan tidak menanggapi ping dari dalam atau luar cloud kami. Saya melakukan hard-reset pada satu VM dan memeriksa log sistem setelah boot. Tidak ada apa-apa. Zip. Nada. Tidak ada satu petunjuk pun selain yang sudah kita ketahui:Tes berhenti begitu saja, mati, bersama dengan sisa sistem.

Karena itu sudah hari keberuntungan saya, saya memutuskan untuk mendorongnya dan kembali mengaduk-aduk WebUI cloud saya. Akhirnya, saya menemukan pengaturan kecil lain yang sangat berguna:Log keluaran konsol serial . Ini pada dasarnya adalah jalur komunikasi langsung tingkat rendah langsung ke kernel. Jika sesuatu terjadi cukup mengerikan untuk sistem-hang yang lengkap, pasti kernel akan berteriak keluar dari port serial virtualnya. Bingo, Yahtzee, dan huzzah!

[ 1203.905090] BUG: kernel NULL pointer dereference, address: 0000000000000000
[ 1203.912275] #PF: supervisor read access in kernel mode
[ 1203.917588] #PF: error_code(0x0000) - not-present page
[ 1203.922881] PGD 8000000124e2d067 P4D 8000000124e2d067 PUD 138d5e067 PMD 0
[ 1203.929939] Oops: 0000 [#1] SMP PTI
...blah...blah...blah
[ 1204.052766] Call Trace:
[ 1204.055440]  bfq_idle_extract+0x52/0xb0
[ 1204.059468]  bfq_put_idle_entity+0x12/0x60
[ 1204.063722]  bfq_bfqq_served+0xb0/0x190
[ 1204.067718]  bfq_dispatch_request+0x2c2/0x1070

Mengapa, halo, teman lama! Itu memang hari yang sangat beruntung!

Ini adalah kepanikan kernel yang saya lihat setahun sebelumnya dan telah bekerja tanpa lelah selama berbulan-bulan dengan perbaikan rekayasa kernel hulu. Itu adalah bug di subsistem penyimpanan kernel yang bertanggung jawab untuk meningkatkan efisiensi dan menjamin 0s dan 1s yang berharga ditulis ke disk. Dalam hal ini, daripada penyimpanan yang rusak, kernel mengeluarkan bendera putih dan menghentikan semua yang mati di jalurnya.

Setelah mengerjakan masalah yang hampir sama persis ini sebelumnya, saya sudah mengetahui solusi satu baris. Tidak perlu menyeret tim saya melalui debugging berbulan-bulan lagi. Saya dapat dengan mudah melaporkan pengulangan dan dengan percaya diri menerapkan solusinya, mengetahui bahwa itu akan 100% mengatasi masalah:

echo mq-deadline > /sys/block/sda/queue/scheduler

Sekarang, saya tidak merekomendasikan menjalankan perintah itu mau tak mau di setiap sistem Linux yang Anda miliki. Dalam kasus khusus ini, saya tahu dari pengalaman sebelumnya bahwa benar-benar aman untuk menukar algoritma buffering (juga disebut Lift I/O). Tidak ada pengembang Podman yang akan melihat perubahan dalam hasil pengujian apa pun.

[ Memulai container? Lihat kursus gratis ini. Menyebarkan aplikasi kemas:Tinjauan teknis. ]

Menutup

Jika Anda atau seseorang yang Anda cintai pernah mengalami kepanikan kernel sendiri, saya sarankan untuk melihat artikel terbaru tentang topik ini. Jika tidak, takeaway utama adalah ini:Saat memecahkan masalah buta, memecahkan aspek penyebab-kebingungan sangat penting. Kedua, bekerja dengan data untuk membuat masalah lebih dapat direproduksi. Anda akan mengalami kesulitan melakukan yang terakhir tanpa bantuan dari yang pertama.


Linux
  1. Memecahkan masalah perangkat keras di Linux

  2. Dasar-dasar sysadmin Linux:Pemecahan masalah kegagalan known_hosts

  3. 5 perintah pemecahan masalah jaringan Linux

  1. Memecahkan masalah server cloud Linux yang rusak

  2. Kali Linux di cloud AWS, lagi

  3. Kali Linux di DigitalOcean Cloud

  1. Memecahkan masalah WiFi lambat di Linux

  2. Pemecahan masalah Linux 101:Kinerja sistem

  3. Pemecahan Masalah Jaringan Linux Dan Debugging?