Cara membangun pengembangan inhouse penuh menggunakan DevOps - pengalaman VTB

Praktik DevOps berhasil. Kami sendiri yakin akan hal ini ketika kami mengurangi waktu instalasi rilis sebanyak 10 kali lipat. Dalam sistem Profil FIS, yang kami gunakan di VTB, instalasi sekarang memerlukan waktu 90 menit, bukan 10 menit. Waktu pembuatan rilis telah berkurang dari dua minggu menjadi dua hari. Jumlah cacat implementasi yang terus-menerus telah menurun hingga hampir mencapai titik minimum. Untuk melepaskan diri dari “pekerjaan manual” dan menghilangkan ketergantungan pada vendor, kami harus bekerja dengan kruk dan menemukan solusi yang tidak terduga. Di bawah ini adalah cerita mendetail tentang bagaimana kami membangun pengembangan internal secara penuh.

Cara membangun pengembangan inhouse penuh menggunakan DevOps - pengalaman VTB
 

Prolog: DevOps adalah sebuah filosofi

Selama setahun terakhir, kami telah melakukan banyak pekerjaan untuk mengatur pengembangan internal dan implementasi praktik DevOps di VTB:

  • Kami membangun proses pengembangan internal untuk 12 sistem;
  • Kami meluncurkan 15 jaringan pipa, empat di antaranya telah memasuki tahap produksi;
  • Skenario pengujian 1445 otomatis;
  • Kami berhasil mengimplementasikan sejumlah rilis yang disiapkan oleh tim internal.

Salah satu pengembangan internal dan implementasi praktik DevSecOps yang paling sulit diatur adalah sistem Profil FIS - pemroses produk ritel pada DBMS non-relasional. Namun demikian, kami dapat membangun pengembangan, meluncurkan pipeline, menginstal paket non-rilis individual pada produk, dan mempelajari cara merakit rilis. Tugasnya tidak mudah, tetapi menarik dan tanpa batasan yang jelas dalam implementasinya: inilah sistemnya - Anda perlu membangun pengembangan internal. Satu-satunya syarat adalah menggunakan CD sebelum lingkungan produktif.

Pada awalnya, algoritma implementasi tampak sederhana dan jelas:

  • Kami mengembangkan keahlian pengembangan awal dan mencapai tingkat kualitas yang dapat diterima dari tim kode tanpa cacat besar;
  • Kami mengintegrasikan sebanyak mungkin ke dalam proses yang ada;
  • Untuk mentransfer kode di antara tahapan yang jelas, kami memotong jalur pipa dan mendorong salah satu ujungnya ke kelanjutan.

Selama waktu ini, tim pengembangan dengan jumlah yang dibutuhkan harus mengembangkan keterampilan dan meningkatkan kontribusinya terhadap rilis ke tingkat yang dapat diterima. Dan itu saja, kita dapat menganggap tugas tersebut selesai.

Tampaknya ini adalah jalur yang benar-benar hemat energi menuju hasil yang diperlukan: inilah DevOps, inilah metrik kinerja tim, inilah akumulasi keahlian... Namun dalam praktiknya, kami menerima konfirmasi lain bahwa DevOps masih tentang filosofi , dan tidak “melekat pada proses gitlab, ansible, nexus, dan selanjutnya dalam daftar.”

Setelah menganalisis rencana aksi sekali lagi, kami menyadari bahwa kami sedang membangun semacam vendor outsourcing di dalam diri kami. Oleh karena itu, rekayasa ulang proses ditambahkan ke algoritma yang dijelaskan di atas, serta pengembangan keahlian di sepanjang jalur pengembangan untuk mencapai peran utama dalam proses ini. Bukan pilihan termudah, tetapi ini adalah jalan pembangunan yang benar secara ideologis.
 

Di mana pengembangan internal dimulai? 

Itu bukanlah sistem yang paling ramah untuk digunakan. Secara arsitektural, ini adalah satu DBMS non-relasional besar, terdiri dari banyak objek terpisah yang dapat dieksekusi (skrip, prosedur, batch, dll.), yang dipanggil sesuai kebutuhan, dan bekerja berdasarkan prinsip kotak hitam: ia menerima permintaan dan mengeluarkan sebuah tanggapan. Kesulitan lain yang perlu diperhatikan meliputi:

  • Bahasa eksotik (MUMPS);
  • Antarmuka konsol;
  • Kurangnya integrasi dengan alat dan kerangka otomatisasi populer;
  • Volume data dalam puluhan terabyte;
  • Memuat lebih dari 2 juta operasi per jam;
  • Signifikansi - Penting bagi Bisnis.

Pada saat yang sama, tidak ada repositori kode sumber di pihak kami. Sama sekali. Terdapat dokumentasi, namun semua pengetahuan dan kompetensi utama berada di pihak organisasi eksternal.
Kami mulai menguasai pengembangan sistem hampir dari awal, dengan mempertimbangkan fitur-fiturnya dan distribusinya yang rendah. Dimulai pada Oktober 2018:

  • Mempelajari dokumentasi dan dasar-dasar pembuatan kode;
  • Kami mempelajari kursus singkat tentang pengembangan yang diterima dari vendor;
  • Menguasai keterampilan pengembangan awal;
  • Kami menyusun manual pelatihan untuk anggota tim baru;
  • Kami sepakat untuk memasukkan tim dalam mode “pertempuran”;
  • Menyelesaikan masalah kontrol kualitas kode;
  • Kami mengorganisir pendirian untuk pembangunan.

Kami menghabiskan waktu tiga bulan untuk mengembangkan keahlian dan membenamkan diri dalam sistem, dan sejak awal tahun 2019, pengembangan internal mulai bergerak menuju masa depan yang cerah, terkadang dengan susah payah, namun dengan percaya diri dan penuh tujuan.

Migrasi repositori dan pengujian otomatis

Tugas DevOps yang pertama adalah repositori. Kami segera menyetujui penyediaan akses, tetapi kami perlu bermigrasi dari SVN saat ini dengan satu cabang utama ke Git target kami dengan transisi ke model beberapa cabang dan pengembangan Git Flow. Kami juga memiliki 2 tim dengan infrastrukturnya sendiri, ditambah sebagian tim vendor di luar negeri. Saya harus hidup dengan dua Git dan memastikan sinkronisasi. Dalam situasi seperti ini, itu adalah hal yang lebih ringan dari dua kejahatan.

Migrasi repositori berulang kali ditunda; baru selesai pada bulan April, dengan bantuan rekan-rekan dari garis depan. Dengan Git Flow, kami memutuskan untuk menjaga semuanya tetap sederhana sebagai permulaan dan memilih skema klasik dengan perbaikan terbaru, pengembangan, dan rilis. Mereka memutuskan untuk meninggalkan master (alias prod-like). Di bawah ini kami akan menjelaskan mengapa opsi ini optimal bagi kami. Repositori eksternal milik vendor, yang umum untuk dua tim, digunakan sebagai pekerja. Itu disinkronkan dengan repositori internal sesuai jadwal. Sekarang dengan Git dan Gitlab, proses dapat diotomatisasi.

Masalah tes otomatis diselesaikan dengan sangat mudah - kami diberikan kerangka kerja yang sudah jadi. Dengan mempertimbangkan kekhasan sistem, pemanggilan operasi terpisah merupakan bagian proses bisnis yang dapat dimengerti dan pada saat yang sama berfungsi sebagai pengujian unit. Yang tersisa hanyalah menyiapkan data pengujian dan mengatur urutan pemanggilan skrip yang diinginkan dan mengevaluasi hasilnya. Saat daftar skenario, yang dibentuk berdasarkan statistik operasi, kekritisan proses dan metodologi regresi yang ada, terisi, pengujian otomatis mulai muncul. Sekarang kita bisa mulai membangun jalur pipa.

Bagaimana keadaannya: model sebelum otomatisasi

Model proses implementasi yang ada adalah cerita tersendiri. Setiap modifikasi ditransfer secara manual sebagai paket instalasi tambahan yang terpisah. Berikutnya adalah registrasi manual di Jira dan instalasi manual di lingkungan. Untuk paket individual, semuanya tampak jelas, tetapi dengan persiapan rilis, segalanya menjadi lebih rumit.

Perakitan dilakukan pada tingkat pengiriman individu, yang merupakan objek independen. Setiap perubahan adalah penyampaian baru. Antara lain, 60–70 versi teknis ditambahkan ke paket 10-15 dari komposisi rilis utama - versi yang diperoleh dengan menambahkan atau mengecualikan sesuatu dari rilis dan mencerminkan perubahan penjualan di luar rilis.

Objek dalam pengiriman saling tumpang tindih, terutama dalam kode yang dapat dieksekusi, yang kurang dari setengah uniknya. Ada banyak ketergantungan baik pada kode yang sudah diinstal maupun pada kode yang baru saja direncanakan instalasinya. 

Untuk mendapatkan versi kode yang diperlukan, urutan instalasi harus diikuti dengan ketat, di mana objek ditulis ulang secara fisik berkali-kali, sekitar 10–12 kali.

Setelah menginstal sejumlah paket, saya harus mengikuti instruksi secara manual untuk menginisialisasi pengaturan. Rilis ini dirakit dan dipasang oleh vendor. Komposisi rilis ini diklarifikasi hampir sebelum momen implementasi, yang memerlukan pembuatan paket “decoupling”. Akibatnya, sebagian besar pasokan berpindah dari satu pelepasan ke pelepasan lainnya dengan akibat “decoupling” sendiri.

Sekarang jelas bahwa dengan pendekatan ini - merakit puzzle rilis pada tingkat paket - satu cabang master tidak memiliki arti praktis. Pemasangan pada produksi memakan waktu satu setengah hingga dua jam kerja manual. Ada baiknya bahwa setidaknya pada tingkat penginstal, urutan pemrosesan objek telah ditentukan: bidang dan struktur dimasukkan sebelum data dan prosedurnya. Namun, ini hanya berfungsi dalam paket terpisah.

Hasil logis dari pendekatan ini adalah cacat instalasi wajib dalam bentuk versi objek yang bengkok, kode yang tidak perlu, instruksi yang hilang, dan pengaruh timbal balik objek yang tidak terhitung, yang dengan tergesa-gesa dihilangkan setelah dirilis. 

Pembaruan pertama: melakukan perakitan dan pengiriman

Otomatisasi dimulai dengan mengirimkan kode melalui pipa di sepanjang rute ini:

  • Ambil kiriman yang sudah jadi dari penyimpanan;
  • Instal di lingkungan khusus;
  • Jalankan tes otomatis;
  • Evaluasi hasil instalasi;
  • Panggil alur berikut di samping perintah pengujian.

Pipeline berikutnya harus mendaftarkan tugas di Jira dan menunggu perintah didistribusikan ke loop pengujian yang dipilih, yang bergantung pada waktu implementasi tugas. Pemicu - surat kesiapan pengiriman ke alamat tertentu. Ini, tentu saja, merupakan penopang yang jelas, tetapi saya harus memulainya dari suatu tempat. Pada bulan Mei 2019, transfer kode dimulai dengan pemeriksaan di lingkungan kami. Prosesnya telah dimulai, yang tersisa hanyalah membawanya ke bentuk yang layak:

  • Setiap modifikasi dilakukan di cabang terpisah, yang sesuai dengan paket instalasi dan digabungkan ke dalam cabang master target;
  • Pemicu peluncuran pipeline adalah munculnya komit baru di cabang master melalui permintaan penggabungan, yang ditutup oleh pengelola dari tim internal;
  • Repositori disinkronkan setiap lima menit sekali;
  • Perakitan paket instalasi dimulai - menggunakan assembler yang diterima dari vendor.

Setelah ini, sudah ada langkah-langkah untuk memeriksa dan mentransfer kode, meluncurkan pipa dan merakit di pihak kami.

Opsi ini diluncurkan pada bulan Juli. Kesulitan transisi mengakibatkan ketidakpuasan di antara vendor dan lini depan, namun pada bulan berikutnya kami berhasil menghilangkan semua sisi kasar dan membangun proses di antara tim. Kami sekarang memiliki perakitan dengan komitmen dan pengiriman.
Pada bulan Agustus, kami berhasil menyelesaikan instalasi pertama dari paket terpisah pada produksi menggunakan pipeline kami, dan sejak September, tanpa kecuali, semua instalasi paket non-rilis individual dilakukan melalui alat CD kami. Selain itu, kami berhasil mencapai pembagian tugas internal dalam 40% komposisi rilis dengan tim yang lebih kecil dibandingkan vendor - ini merupakan kesuksesan yang pasti. Tugas paling serius yang tersisa - merakit dan menginstal rilisnya.

Solusi terakhir: paket instalasi kumulatif 

Kami memahami betul bahwa pembuatan skrip instruksi vendor adalah otomatisasi yang biasa-biasa saja; kami harus memikirkan kembali prosesnya sendiri. Solusinya jelas - untuk mengumpulkan pasokan kumulatif dari cabang rilis dengan semua objek dari versi yang diperlukan.

Kami memulai dengan bukti konsep: kami merakit sendiri paket rilis sesuai dengan konten implementasi sebelumnya dan menginstalnya di lingkungan kami. Semuanya berhasil, konsepnya ternyata bisa dijalankan. Selanjutnya, kami menyelesaikan masalah pembuatan skrip pengaturan inisialisasi dan memasukkannya ke dalam penerapan. Kami menyiapkan paket baru dan mengujinya di lingkungan pengujian sebagai bagian dari pembaruan kontur. Instalasi berhasil, meskipun mendapat banyak komentar dari tim implementasi. Namun yang terpenting adalah kami diberi izin untuk mulai berproduksi pada rilis November dengan perakitan kami.

Dengan sisa waktu satu bulan lebih, persediaan yang dipilih dengan jelas mengisyaratkan bahwa waktu hampir habis. Mereka memutuskan untuk membuat build dari cabang rilis, tapi kenapa harus dipisahkan? Kami tidak memiliki Prod, dan cabang yang ada tidak bagus - ada banyak kode yang tidak perlu. Kami harus segera mengurangi jumlah yang menyukai produk, dan ini berarti lebih dari tiga ribu komitmen. Merakit dengan tangan bukanlah suatu pilihan sama sekali. Kami membuat sketsa skrip yang dijalankan melalui log instalasi produk dan mengumpulkan komitmen ke cabang. Ketiga kalinya itu berfungsi dengan benar, dan setelah "menyelesaikan file" cabang sudah siap. 

Kami menulis pembuat kami sendiri untuk paket instalasi dan menyelesaikannya dalam seminggu. Kemudian kami harus memodifikasi penginstal dari fungsionalitas inti sistem, karena ini adalah sumber terbuka. Setelah dilakukan serangkaian pengecekan dan modifikasi, hasilnya dianggap berhasil. Sementara itu, komposisi rilis mulai terbentuk, untuk pemasangan yang benar perlu menyelaraskan sirkuit pengujian dengan sirkuit produksi, dan skrip terpisah ditulis untuk ini.

Tentu saja, ada banyak komentar tentang instalasi pertama, tetapi secara umum kodenya berfungsi. Dan setelah instalasi ketiga semuanya mulai terlihat baik. Kontrol komposisi dan kontrol versi objek dipantau secara terpisah dalam mode manual, yang pada tahap ini cukup beralasan.

Tantangan tambahannya adalah banyaknya jumlah non-rilis yang harus diperhitungkan. Namun dengan cabang mirip Prod dan Rebase, tugas menjadi transparan.

Pertama kali, dengan cepat dan tanpa kesalahan

Kami mendekati peluncuran ini dengan sikap optimis dan lebih dari selusin instalasi yang berhasil di sirkuit yang berbeda. Namun sehari sebelum batas waktu, ternyata vendor belum menyelesaikan pekerjaan mempersiapkan rilis untuk instalasi dengan cara yang dapat diterima. Jika karena alasan tertentu build kami tidak berfungsi, rilis akan terganggu. Terlebih lagi, melalui upaya kami, yang sangat tidak menyenangkan. Kami tidak punya cara untuk mundur. Oleh karena itu, kami memikirkan pilihan alternatif, menyiapkan rencana aksi dan memulai instalasi.

Anehnya, seluruh rilis, yang terdiri dari lebih dari 800 objek, dimulai dengan benar, pertama kali dan hanya dalam 10 menit. Kami menghabiskan satu jam memeriksa log untuk mencari kesalahan, tetapi tidak menemukan kesalahan apa pun.

Sepanjang hari berikutnya ada keheningan dalam obrolan rilis: tidak ada masalah implementasi, versi yang bengkok, atau kode yang “tidak pantas”. Bahkan terasa canggung. Belakangan, beberapa komentar muncul, namun dibandingkan dengan sistem lain dan pengalaman sebelumnya, jumlah dan prioritasnya jauh lebih rendah.

Efek tambahan dari efek kumulatif adalah peningkatan kualitas perakitan dan pengujian. Karena beberapa instalasi pada rilis lengkap, cacat build dan kesalahan penerapan diidentifikasi secara tepat waktu. Pengujian dalam konfigurasi rilis penuh memungkinkan untuk mengidentifikasi lebih lanjut cacat pada pengaruh timbal balik objek yang tidak muncul selama instalasi tambahan. Ini benar-benar sukses, terutama mengingat kontribusi kami sebesar 57% terhadap rilis ini.

Hasil dan kesimpulan

Dalam waktu kurang dari setahun kami berhasil:

  • Membangun pengembangan internal yang menyeluruh dengan menggunakan sistem eksotik;
  • Menghilangkan ketergantungan vendor yang penting;
  • Luncurkan CI/CD untuk warisan yang sangat tidak bersahabat;
  • Meningkatkan proses implementasi ke tingkat teknis yang baru;
  • Mengurangi waktu penerapan secara signifikan;
  • Mengurangi jumlah kesalahan implementasi secara signifikan;
  • Dengan percaya diri nyatakan diri Anda sebagai pakar pengembangan terkemuka.

Tentu saja, sebagian besar dari apa yang dijelaskan tampak seperti omong kosong, tetapi ini adalah fitur sistem dan keterbatasan proses yang ada di dalamnya. Saat ini, perubahan tersebut memengaruhi produk dan layanan Profil IS (rekening induk, kartu plastik, rekening tabungan, escrow, pinjaman tunai), namun berpotensi pendekatan ini dapat diterapkan pada IS mana pun yang tugas penerapan praktik DevOps ditetapkan. Model kumulatif dapat direplikasi dengan aman untuk implementasi selanjutnya (termasuk implementasi non-rilis) dari banyak pengiriman.

Sumber: www.habr.com

Tambah komentar