Kami mengembangkan DevOps semampu kami. Ada 8 dari kita, dan Vasya adalah yang paling keren di Windows. Tiba-tiba, Vasya pergi, dan aku punya tugas untuk mengeluarkan proyek baru yang memasok pengembangan Windows. Ketika saya menuangkan seluruh tumpukan pengembangan Windows ke atas meja, saya menyadari bahwa situasinya menyakitkan ...
Maka mulailah kisah
Alexander Sinchinov di
DevOpsConf . Ketika spesialis Windows terkemuka meninggalkan perusahaan, Alexander bertanya-tanya apa yang harus dilakukan sekarang. Beralih ke Linux, tentu saja! Alexander akan memberi tahu bagaimana ia mengatur preseden dan mentransfer bagian dari pengembangan Windows ke Linux menggunakan contoh proyek yang telah selesai untuk 100.000 pengguna akhir.

Bagaimana dengan mudah dan mudah mengirimkan proyek ke RPM menggunakan TFS, Puppet, Linux .NET core? Bagaimana mempertahankan versi database proyek jika pengembangan pertama kali mendengar kata-kata Postgres dan Flyway, dan batas waktu lusa? Bagaimana cara mengintegrasikan dengan Docker? Bagaimana memotivasi pengembang .NET untuk meninggalkan Windows dan smoothie demi Puppet dan Linux? Bagaimana mengatasi konflik ideologis, jika tidak ada kekuatan, tidak ada keinginan, tidak ada sumber daya untuk melayani Windows dalam produksi? Tentang ini, serta tentang Penyebaran Web, pengujian, CI, tentang praktik menggunakan TFS dalam proyek yang ada, dan, tentu saja, tentang kruk yang rusak dan solusi kerja, dalam memecahkan kode laporan Alexander.
Jadi, Vasya pergi, tugasnya untuk saya, para pengembang menantikan
dengan garpu rumput . Ketika saya akhirnya menyadari bahwa Vasya tidak dapat dikembalikan, saya mulai berbisnis. Untuk mulai dengan, saya memperkirakan persentase Win VM di taman kami. Skor itu tidak mendukung Windows.

Karena kami secara aktif mengembangkan DevOps, saya menyadari bahwa ada sesuatu yang perlu diubah dalam pendekatan mengambil aplikasi baru. Solusinya adalah satu - jika mungkin, transfer semuanya ke Linux. Google membantu saya - pada waktu itu. Net sudah porting ke Linux, dan saya menyadari bahwa solusi ini!
Mengapa .NET core dibundel dengan Linux?
Ada beberapa alasan untuk ini. Antara "bayar uang" dan "jangan bayar", mayoritas akan memilih yang kedua - seperti saya. Lisensi untuk MSDB harganya sekitar $ 1.000, pemeliharaan armada mesin virtual Windows harganya ratusan dolar. Untuk perusahaan besar itu adalah pengeluaran besar. Karena itu,
menabung adalah
alasan pertama . Bukan yang paling penting, tetapi salah satu yang paling penting.
Mesin virtual Windows membutuhkan lebih banyak sumber daya daripada saudara-saudara Linux
mereka -
mereka berat . Mengingat skala perusahaan besar, kami memilih Linux.
Sistem ini hanya diintegrasikan ke dalam CI yang ada . Kami menganggap diri kami sebagai DevOps progresif, kami menggunakan Bamboo, Jenkins dan GitLab CI, sehingga sebagian besar pekerjaan kami adalah di Linux.
Alasan terakhir adalah
pengawalan yang nyaman. Kami harus menurunkan ambang masuk untuk "pengawalan" - orang yang memahami bagian teknis, memastikan operasi dan layanan layanan tanpa gangguan dari baris kedua. Mereka sudah terbiasa dengan tumpukan Linux, sehingga jauh lebih mudah bagi mereka untuk memahami produk baru, memelihara dan memelihara, daripada menghabiskan sumber daya tambahan untuk menangani fungsionalitas yang sama dari perangkat lunak untuk platform Windows.
Persyaratan
Pertama dan terpenting,
kenyamanan solusi baru untuk pengembang . Tidak semua dari mereka siap untuk berubah, terutama setelah kata yang diucapkan Linux. Pengembang menginginkan Visual Studio tercinta mereka, TFS dengan tes build dan smoothie. Bagaimana pengiriman terjadi dalam produksi - mereka tidak peduli. Oleh karena itu, kami memutuskan untuk tidak mengubah proses yang biasa dan membiarkan semuanya tidak berubah untuk pengembangan Windows.
Proyek baru perlu
tertanam dalam CI yang ada . Rel sudah ada di sana dan semua pekerjaan harus dilakukan dengan mempertimbangkan parameter sistem manajemen konfigurasi, standar pengiriman yang diterima, dan sistem pemantauan.
Kesederhanaan dalam dukungan dan operasi , sebagai syarat untuk ambang masuk minimum untuk semua peserta baru dari berbagai departemen dan departemen dukungan.
Batas waktu - kemarin .
Menangkan Kelompok Pengembangan
Apa yang bekerja dengan tim Windows saat itu?

Sekarang saya dapat dengan yakin mengatakan bahwa
IdentityServer4 adalah alternatif bebas keren untuk ADFS dengan kemampuan serupa, atau bahwa
Entity Framework Core adalah surga pengembang di mana Anda tidak dapat repot menulis skrip SQL, tetapi jelaskan kueri dalam database dalam istilah OOP. Tapi kemudian, ketika membahas rencana aksi, saya melihat tumpukan ini sebagai tulisan rune Sumeria yang hanya mengenali PostgreSQL dan Git.
Pada saat itu, kami secara aktif menggunakan
Puppet sebagai sistem manajemen konfigurasi. Dalam sebagian besar proyek kami, kami menggunakan
GitLab CI ,
Elastis , layanan seimbang yang sangat dimuat menggunakan
HAProxy, memantau semuanya dengan
Zabbix , sekelompok
Grafana dan
Prometheus ,
Jaeger , dan semua ini berputar pada perangkat keras
HP dengan
ESXi pada
VMware . Semua orang tahu - klasik genre.

Mari kita lihat dan coba pahami apa yang terjadi sebelum kita memulai semua intervensi ini.
Apa itu
TFS adalah sistem yang cukup kuat yang tidak hanya mengirimkan kode dari pengembang ke mesin produksi akhir, tetapi juga memiliki satu set untuk integrasi yang sangat fleksibel dengan berbagai layanan - untuk memberikan CI pada level lintas platform.

Sebelumnya, ini adalah jendela padat. TFS menggunakan beberapa agen Build, yang mengumpulkan banyak proyek. Setiap agen memiliki 3-4 pekerja-a untuk memparalelkan tugas dan mengoptimalkan proses. Selanjutnya, sesuai dengan rencana rilis, TFS mengirimkan Build yang baru dipanggang ke server aplikasi Windows.
Apa yang kami inginkan
Untuk pengiriman dan pengembangan, kami menggunakan TFS, dan kami meluncurkan aplikasi pada server Aplikasi Linux, dan ada beberapa jenis keajaiban di antara mereka.
Kotak Ajaib ini adalah garam dari pekerjaan yang akan datang. Sebelum membongkar sebagian, saya akan mengambil langkah ke samping dan mengatakan dua kata tentang aplikasi.
Proyek
Aplikasi ini menyediakan fungsionalitas untuk menangani kartu prabayar.

Klien
Ada dua jenis pengguna.
Yang pertama mendapat akses dengan masuk dengan sertifikat SSL SHA-2. Yang
kedua memiliki akses dengan login dan kata sandi.
HAProxy
Selanjutnya, permintaan klien jatuh ke dalam HAProxy, yang menyelesaikan tugas-tugas berikut:
- otorisasi utama;
- Pengakhiran SSL
- pencarian permintaan HTTP;
- permintaan siaran.
Verifikasi sertifikat klien melewati rantai. Kami adalah
otoritas dan kami mampu membelinya, karena kami sendiri mengeluarkan sertifikat untuk melayani pelanggan.
Perhatikan poin ketiga, sebentar lagi kita akan kembali ke sana.
Backend
Mereka berencana membuat backend di Linux. Backend berinteraksi dengan database, memuat daftar hak istimewa yang diperlukan dan kemudian, tergantung pada hak istimewa apa yang dimiliki oleh pengguna yang berwenang, menyediakan akses untuk menandatangani dokumen keuangan dan mengirimkannya untuk dieksekusi, atau menghasilkan semacam laporan.
Menyimpan dengan HAProxy
Selain dua konteks yang digunakan oleh setiap klien, ada juga konteks identitas.
IdentityServer4 hanya memungkinkan Anda untuk masuk, ini adalah analog yang kuat dan gratis untuk
ADFS -
Active Directory Federation Services .
Permintaan identitas diproses dalam beberapa langkah. Langkah pertama -
klien jatuh ke backend , yang bertukar data dengan server ini dan memeriksa keberadaan token untuk klien. Jika saya tidak menemukannya, permintaan kembali ke konteks dari mana asalnya, tetapi dengan pengalihan, dan dengan pengalihan pergi ke identitas.
Langkah kedua - permintaan pergi
ke halaman otentikasi di IdentityServer, tempat klien terdaftar, dan token yang sangat lama ditunggu-tunggu muncul di database IdentityServer.
Langkah ketiga -
klien diarahkan kembali ke konteks dari mana dia datang.

IdentityServer4 memiliki kekhasan:
mengembalikan respons terhadap permintaan pengembalian melalui HTTP . Tidak peduli bagaimana kami berjuang dengan pengaturan server, tidak peduli bagaimana kami menjadi tercerahkan dengan dokumentasi, setiap kali kami menerima permintaan klien awal dengan URL yang datang melalui HTTPS, dan IdentityServer mengembalikan konteks yang sama, tetapi dengan HTTP. Kami kaget! Dan semua ini ditransfer melalui konteks identitas ke HAProxy, dan di header kami harus memodifikasi protokol HTTP ke HTTPS.
Apa perbaikannya dan di mana mereka menyimpan?
Kami menghemat uang dengan menggunakan solusi gratis untuk mengotorisasi sekelompok pengguna, sumber daya, karena kami tidak menggunakan IdentityServer4 sebagai catatan terpisah di segmen terpisah, tetapi menggunakannya bersama dengan backend di server yang sama di mana aplikasi backend berputar.
Bagaimana cara kerjanya
Jadi, seperti yang saya janjikan - Kotak Ajaib. Kami sudah mengerti bahwa kami dijamin akan pindah ke Linux. Mari kita merumuskan tugas-tugas spesifik yang membutuhkan solusi.
Manifestasi wayang. Untuk mengirim dan mengelola konfigurasi layanan dan aplikasi, Anda harus menulis resep keren. Gulungan pensil dengan fasih menunjukkan seberapa cepat dan efisien hal ini dilakukan.
Metode pengiriman. Standarnya adalah RPM. Semua orang mengerti bahwa di Linux tidak ada jalan tanpa itu, tetapi proyek itu sendiri setelah perakitan adalah satu set file DLL yang dapat dieksekusi. Ada sekitar 150 di antaranya, proyeknya cukup sulit. Satu-satunya solusi harmonis adalah mengemas binari ini ke dalam RPM dan menyebarkan aplikasi darinya.
Versi Kami harus merilis sangat sering, dan kami harus memutuskan bagaimana membentuk nama paket. Ini adalah masalah tingkat integrasi TFS. Kami memiliki agen pembangun di Linux. Ketika TFS mengirimkan tugas ke pawang - pekerja - ke agen Bangun, itu juga mengirimkan sekelompok variabel yang jatuh ke lingkungan proses pawang. Variabel lingkungan ini meneruskan nama Build, nama versi, dan variabel lainnya. Baca lebih lanjut tentang ini di bagian "Merakit Paket RPM".
Menyiapkan TFS datang untuk mengatur Pipeline. Sebelumnya, kami mengumpulkan semua proyek Windows pada agen Windows, dan sekarang ada agen Linux - agen Build yang perlu dimasukkan dalam kelompok perakitan, diperkaya dengan beberapa artefak, memberi tahu jenis proyek apa yang akan dibangun pada agen Build ini, dan entah bagaimana memodifikasi Pipeline.
IdentityServer. ADFS bukan jalan kami, kami tenggelam untuk Open Source.
Mari kita lihat komponen-komponennya.
Kotak ajaib
Terdiri dari empat bagian.
Linux build agent. Linux, karena kami mengompilasinya, adalah logis. Bagian ini dilakukan dalam tiga langkah.
- Konfigurasikan pekerja dan lebih dari satu, karena diasumsikan didistribusikan pekerjaan pada proyek.
- Instal .NET Core 1.x. Mengapa 1.x ketika 2.0 sudah tersedia di repositori standar? Karena ketika kami memulai pengembangan, versi stabil adalah 1.09, dan diputuskan untuk melakukan proyek untuk itu.
- Git 2.x.
Repositori RPM. Paket RPM perlu disimpan di suatu tempat. Diasumsikan bahwa kita akan menggunakan repositori RPM korporat yang sama yang tersedia untuk semua host Linux. Dan begitulah yang mereka lakukan. Sebuah
webhook dikonfigurasi pada server repositori yang mengunduh paket RPM yang diperlukan dari lokasi yang ditentukan. Versi paket dilaporkan ke webhook oleh agen Build.
Gitlab Perhatian! GitLab digunakan di sini bukan oleh pengembang, tetapi oleh departemen operasi untuk mengontrol versi aplikasi, versi paket, memantau status semua mesin Linux dan menyimpan resep - semua manifes wayang.
Wayang - menyelesaikan semua masalah kontroversial dan memberikan konfigurasi persis seperti yang kita inginkan dari Gitlab.
Kami mulai menyelam. Bagaimana DLL disampaikan dalam RPM?
Pengiriman DDL ke RPM
Katakanlah kita memiliki bintang rock untuk pengembangan .NET. Ini menggunakan Visual Studio dan membuat cabang rilis. Setelah itu memuatnya ke Git, dan Git di sini adalah entitas TFS, yaitu, repositori aplikasi tempat pengembang bekerja.

Setelah itu TFS melihat bahwa komit baru telah tiba. Aplikasi yang mana? Dalam pengaturan TFS ada label tentang sumber daya apa yang dimiliki agen Build tertentu. Dalam hal ini, ia melihat bahwa kami sedang membangun proyek .NET Core dan memilih agen pembangun Linux dari kumpulan.
Agen build menerima sumber, mengunduh
dependensi yang diperlukan dari .NET, repositori npm, dll. dan setelah membangun aplikasi itu sendiri dan pengemasan selanjutnya, ia mengirimkan paket RPM ke repositori RPM.
Di sisi lain, berikut ini terjadi. Insinyur pemeliharaan terlibat langsung dalam meluncurkan proyek: ia mengubah versi paket di
Hiera di repositori tempat resep aplikasi disimpan, setelah itu Wayang memicu
Yum , mengambil paket baru dari repositori, dan versi baru aplikasi siap digunakan.

Dengan kata lain, semuanya sederhana, tetapi apa yang terjadi di dalam pada agen Build itu sendiri?
Pengemasan RPM DLL
Sumber proyek dan tugas pembangunan dari TFS diterima. Agen pembuat
mulai membangun proyek dari sumber . Proyek rakitan tersedia dalam bentuk banyak
file DLL yang dikemas dalam arsip zip untuk mengurangi beban pada sistem file.
Arsip ZIP dilemparkan
ke direktori build paket RPM. Selanjutnya, skrip Bash menginisialisasi variabel lingkungan, menemukan versi Build, versi proyek, path ke direktori build, dan meluncurkan RPM-build. Pada akhir perakitan, paket diterbitkan ke
repositori lokal , yang terletak di agen Build.
Selanjutnya,
permintaan JSON dikirim dari agen Build ke server di repositori RPM dengan nama versi dan build. Webhook, tentang yang saya bicarakan sebelumnya, mengunduh paket yang sama ini dari repositori lokal pada agen Build dan membuat perakitan baru tersedia untuk instalasi.

Mengapa skema untuk mengirimkan paket ke repositori RPM? Mengapa saya tidak bisa langsung mengirim paket yang sudah dirakit ke repositori? Faktanya adalah ini adalah syarat untuk keamanan. Skenario ini membatasi kemungkinan pengunduhan paket RPM oleh orang luar ke server yang dapat diakses oleh semua mesin Linux.
Versi DB
Pada konsultasi dengan pengembangan, ternyata orang-orang lebih dekat dengan MS SQL, tetapi di sebagian besar proyek non-Windows kami sudah menggunakan PostgreSQL dengan kekuatan dan utama. Karena kami sudah memutuskan untuk meninggalkan semua yang dibayar, kami mulai menggunakan PostgreSQL di sini.

Pada bagian ini saya ingin berbicara tentang bagaimana kami mengimplementasikan versi database dan bagaimana memilih antara Flyway dan Entity Framework Core. Pertimbangkan pro dan kontra mereka.
Cons
Flyway hanya berjalan satu arah, kami
tidak dapat memutar kembali - ini adalah minus yang signifikan. Perbandingan dengan Entity Framework Core dapat dilakukan sesuai dengan parameter lain - dari sudut pandang kenyamanan pengembang. Anda ingat kami menempatkan ini sebagai yang terdepan, dan kriteria utama adalah tidak mengubah apa pun untuk pengembangan Windows.
Untuk Flyway, kami
membutuhkan semacam pembungkus sehingga orang-orang tidak menulis
pertanyaan SQL . Mereka jauh lebih dekat untuk beroperasi dalam hal OOP. Kami menulis instruksi untuk bekerja dengan objek database, membentuk kueri SQL dan dieksekusi. Versi baru dari database siap, digulung - semuanya baik-baik saja, semuanya berfungsi.
Entity Framework Core memiliki minus - di bawah beban berat itu
membangun query SQL tidak optimal , dan penarikan database bisa signifikan. Tetapi karena kami tidak memiliki layanan beban tinggi, kami tidak menghitung beban dengan ratusan RPS, kami mengambil risiko ini dan mendelegasikan masalah ke masa depan kami.
Pro
Entity Framework Core
bekerja di luar kotak dan mudah dikembangkan , dan Flyway
terintegrasi dengan mulus ke CI yang ada . Tapi kami melakukannya dengan nyaman untuk pengembang :)
Prosedur roll-up
Wayang melihat bahwa ada perubahan dalam versi paket di antaranya yang bertanggung jawab untuk migrasi. Pertama, ia menginstal paket yang berisi skrip migrasi dan fungsionalitas yang terkait dengan database. Setelah itu, aplikasi yang berfungsi dengan database di-restart. Selanjutnya adalah pemasangan komponen yang tersisa. Urutan paket yang diinstal dan aplikasi diluncurkan dijelaskan dalam manifes Wayang.
Aplikasi menggunakan data sensitif, seperti token, kata sandi ke database, semua ini ditarik ke dalam konfigurasi dengan master Wayang, di mana mereka disimpan dalam bentuk terenkripsi.
Masalah TFS
Setelah kami memutuskan dan menyadari bahwa semuanya benar-benar bekerja untuk kami, saya memutuskan untuk melihat apa yang terjadi dengan majelis di TFS secara keseluruhan untuk departemen Win-development untuk proyek-proyek lain - dengan cepat atau tidak, kami akan / melepaskan, dan menemukan masalah signifikan dengan kecepatan .
Salah satu proyek utama akan memakan waktu 12-15 menit - ini adalah waktu yang lama, Anda tidak bisa hidup seperti itu. Analisis cepat menunjukkan drawdown mengerikan pada I / O, dan ini pada array.
Setelah menganalisis secara komponen, saya mengidentifikasi tiga fokus. Yang pertama adalah
antivirus Kaspersky , yang memindai kode sumber pada semua agen Windows Build. Yang kedua adalah
Windows Indexer. Itu tidak terputus, dan pada agen Build secara real time semuanya diindeks selama proses penyebaran.
Yang ketiga adalah
instalasi Npm. Ternyata di sebagian besar Pipeline kami menggunakan skenario khusus ini. Kenapa dia jahat? Prosedur instalasi Npm dimulai ketika pohon dependensi dibentuk di
package-lock.json , di mana versi paket yang akan digunakan untuk membangun proyek diperbaiki. Yang minus adalah bahwa instalasi Npm menarik versi terbaru paket-paket dari Internet setiap kali, dan ini adalah waktu yang cukup besar dalam kasus proyek besar.
Pengembang kadang-kadang bereksperimen dengan mesin lokal untuk menguji operasi bagian individu atau proyek secara keseluruhan. Kadang-kadang ternyata secara lokal semuanya keren, tetapi berkumpul, diluncurkan - tidak ada yang berhasil. Kami mulai memahami apa masalahnya - ya, berbagai versi paket dependensi.
Solusi
- Sumber untuk pengecualian AV.
- Menonaktifkan pengindeksan.
- Beralih ke npm ci .
Keuntungan dari npm ci adalah bahwa kami
mengumpulkan pohon dependensi satu kali , dan mendapatkan kesempatan untuk menyediakan pengembang dengan
daftar paket terbaru yang ia dapat bereksperimen secara lokal sebanyak yang ia inginkan. Ini
menghemat waktu untuk pengembang yang menulis kode.
Konfigurasi
Sekarang sedikit tentang konfigurasi repositori. Secara historis, kami telah menggunakan
Nexus untuk mengelola repositori, termasuk
REPO Internal . Semua komponen yang kami gunakan untuk tujuan internal, misalnya, pemantauan yang ditulis sendiri, dikirimkan ke repositori internal ini.

Kami juga menggunakan
NuGet , karena cache lebih baik daripada manajer paket lainnya.
Hasil
Setelah kami mengoptimalkan agen Build, waktu rata-rata build berkurang dari 12 menit menjadi 7.
Jika kami menghitung semua mesin yang bisa kami gunakan untuk Windows, tetapi ditransfer ke Linux dalam proyek ini, kami menghemat sekitar $ 10.000. Dan ini hanya pada lisensi, dan jika Anda memperhitungkan konten - lebih banyak.
Paket
Kuartal berikutnya, rencana meletakkan bekerja pada mengoptimalkan pengiriman kode.
Transisi ke gambar Docker pra-bangun . TFS adalah hal yang keren dengan banyak plugin yang memungkinkan Anda untuk berintegrasi ke dalam Pipeline, termasuk perakitan sesuai dengan pemicunya, misalnya, gambar Docker. Kami ingin membuat pemicu ini pada
package-lock.json yang sama . Jika entah bagaimana komposisi komponen yang digunakan untuk membangun perubahan proyek, kita akan memiliki gambar Docker baru. Ini kemudian digunakan untuk menggunakan wadah dengan aplikasi yang dikompilasi. Sekarang ini bukan, tapi kami berencana untuk beralih ke arsitektur layanan-mikro di Kubernetes, yang secara aktif berkembang di perusahaan kami dan telah lama melayani solusi produksi.
Ringkasan
Saya mendesak semua orang untuk melempar Windows, tetapi ini bukan karena saya tidak tahu cara memasaknya. Alasannya adalah bahwa sebagian besar solusi opensource adalah
tumpukan Linux . Anda akan
menghemat sumber daya dengan baik . Menurut pendapat saya, masa depan terletak pada solusi Open Source Linux dengan komunitas yang kuat.
Profil pembicara Alexander Sinchinov di GitHub .DevOps Conf adalah konferensi tentang integrasi pengembangan, pengujian dan proses operasi untuk para profesional dari para profesional. Itu sebabnya proyek yang dibicarakan Alexander? diimplementasikan dan bekerja, dan pada hari kinerja dua rilis berhasil dibuat. Pada DevOps Conf on RIT ++ pada 27 dan 28 Mei akan ada lebih banyak lagi kasus dari para praktisi. Anda masih dapat melompat ke gerbong terakhir dan mengirimkan laporan, atau meluangkan waktu untuk memesan tiket. Temui aku di Skolkovo!