Bagikan melalui


CI/CD untuk arsitektur layanan mikro

Azure

Siklus rilis yang lebih cepat adalah salah satu keuntungan utama arsitektur layanan mikro. Tetapi tanpa proses CI/CD yang baik, Anda tidak akan mencapai kelincahan yang dijanjikan layanan mikro. Artikel ini menjelaskan tantangan dan merekomendasikan beberapa pendekatan untuk masalah tersebut.

Apa itu CI/CD?

Ketika kita berbicara tentang CI/CD, kita benar-benar berbicara tentang beberapa proses terkait: Integrasi berkelanjutan, pengiriman berkelanjutan, dan penyebaran berkelanjutan.

  • Integrasi berkelanjutan. Perubahan kode sering digabungkan ke cabang utama. Proses build dan pengujian otomatis memastikan bahwa kode di cabang utama selalu berkualitas produksi.

  • Pengiriman berkelanjutan . Setiap perubahan kode yang melewati proses CI secara otomatis diterbitkan ke lingkungan seperti produksi. Penyebaran ke lingkungan produksi langsung mungkin memerlukan persetujuan manual, tetapi sebaliknya otomatis. Tujuannya adalah bahwa kode Anda harus selalu siap untuk disebarkan ke dalam produksi.

  • Penyebaran berkelanjutan. Perubahan kode yang melewati dua langkah sebelumnya secara otomatis disebarkan ke dalamproduksi .

Berikut adalah beberapa tujuan dari proses CI/CD yang kuat untuk arsitektur layanan mikro:

  • Setiap tim dapat membangun dan menyebarkan layanan yang dimilikinya secara independen, tanpa memengaruhi atau mengganggu tim lain.

  • Sebelum versi baru layanan disebarkan ke produksi, layanan akan disebarkan ke lingkungan dev/test/QA untuk validasi. Gerbang kualitas diberlakukan pada setiap tahap.

  • Versi baru layanan dapat disebarkan berdampingan dengan versi sebelumnya.

  • Kebijakan kontrol akses yang memadai sudah ada.

  • Untuk beban kerja kontainer, Anda dapat mempercayai gambar kontainer yang disebarkan ke produksi.

Mengapa alur CI/CD yang kuat penting

Dalam aplikasi monolitik tradisional, ada satu alur build yang outputnya adalah aplikasi yang dapat dieksekusi. Semua pekerjaan pengembangan disalurkan ke dalam alur ini. Jika bug berprioritas tinggi ditemukan, perbaikan harus diintegrasikan, diuji, dan diterbitkan, yang dapat menunda rilis fitur baru. Anda dapat mengurangi masalah ini dengan memiliki modul yang diperhitungkan dengan baik dan menggunakan cabang fitur untuk meminimalkan dampak perubahan kode. Tetapi ketika aplikasi tumbuh lebih kompleks, dan lebih banyak fitur ditambahkan, proses rilis untuk monolit cenderung menjadi lebih rapuh dan cenderung rusak.

Mengikuti filosofi layanan mikro, seharusnya tidak ada kereta rilis panjang di mana setiap tim harus mengantri. Tim yang membangun layanan "A" dapat merilis pembaruan kapan saja, tanpa menunggu perubahan layanan "B" untuk digabungkan, diuji, dan disebarkan.

Diagram monolit CI/CD

Untuk mencapai kecepatan rilis yang tinggi, alur rilis Anda harus otomatis dan sangat dapat diandalkan untuk meminimalkan risiko. Jika Anda merilis ke produksi satu atau beberapa kali setiap hari, regresi atau gangguan layanan harus jarang terjadi. Pada saat yang sama, jika pembaruan buruk disebarkan, Anda harus memiliki cara yang dapat diandalkan untuk dengan cepat mengembalikan atau meneruskan ke versi layanan sebelumnya.

Tantangan

  • Banyak basis kode independen kecil. Setiap tim bertanggung jawab untuk membangun layanannya sendiri, dengan alur buildnya sendiri. Di beberapa organisasi, tim dapat menggunakan repositori kode terpisah. Repositori terpisah dapat menyebabkan situasi di mana pengetahuan tentang cara membangun sistem tersebar di seluruh tim, dan tidak ada di organisasi yang tahu cara menyebarkan seluruh aplikasi. Misalnya, apa yang terjadi dalam skenario pemulihan bencana, jika Anda perlu dengan cepat menyebarkan ke kluster baru?

    Mitigasi: Memiliki alur terpadu dan otomatis untuk membangun dan menyebarkan layanan, sehingga pengetahuan ini tidak "tersembunyi" dalam setiap tim.

  • Beberapa bahasa dan kerangka kerja. Dengan setiap tim menggunakan campuran teknologinya sendiri, mungkin sulit untuk membuat satu proses build yang berfungsi di seluruh organisasi. Proses build harus cukup fleksibel sehingga setiap tim dapat menyesuaikannya untuk pilihan bahasa atau kerangka kerja mereka.

    Mitigasi: Kontainerisasi proses build untuk setiap layanan. Dengan begitu, sistem build hanya perlu dapat menjalankan kontainer.

  • Integrasi dan pengujian beban. Dengan tim merilis pembaruan dengan kecepatan mereka sendiri, mungkin sulit untuk merancang pengujian end-to-end yang kuat, terutama ketika layanan memiliki dependensi pada layanan lain. Selain itu, menjalankan kluster produksi penuh bisa mahal, jadi tidak mungkin setiap tim akan menjalankan kluster penuhnya sendiri pada skala produksi, hanya untuk pengujian.

  • Manajemen rilis. Setiap tim harus dapat menyebarkan pembaruan ke produksi. Itu tidak berarti bahwa setiap anggota tim memiliki izin untuk melakukannya. Tetapi memiliki peran Release Manager terpusat dapat mengurangi kecepatan penyebaran.

    Mitigasi: Semakin banyak proses CI/CD Anda otomatis dan dapat diandalkan, semakin sedikit kebutuhan akan otoritas pusat. Meskipun demikian, Anda mungkin memiliki kebijakan yang berbeda untuk merilis pembaruan fitur utama versus perbaikan bug kecil. Terdesentralisasi bukan berarti tata kelola nol.

  • Pembaruan layanan. Saat Anda memperbarui layanan ke versi baru, layanan tersebut tidak boleh merusak layanan lain yang bergantung padanya.

    Mitigasi: Gunakan teknik penyebaran seperti biru-hijau atau rilis kenari untuk perubahan yang tidak melanggar. Untuk perubahan API yang melanggar, sebarkan versi baru berdampingan dengan versi sebelumnya. Dengan begitu, layanan yang menggunakan API sebelumnya dapat diperbarui dan diuji untuk API baru. Lihat Memperbarui layanan, di bawah ini.

Monorepo vs. multi-repo

Sebelum membuat alur kerja CI/CD, Anda harus tahu bagaimana basis kode akan disusun dan dikelola.

  • Apakah tim bekerja di repositori terpisah atau dalam monorepo (repositori tunggal)?
  • Apa strategi percabangan Anda?
  • Siapa yang dapat mendorong kode ke produksi? Apakah ada peran manajer rilis?

Pendekatan monorepo telah mendapatkan kebaikan tetapi ada keuntungan dan kerugian bagi keduanya.

  Monorepo Beberapa repositori
Keuntungan Berbagi kode
Lebih mudah untuk menstandarkan kode dan alat
Lebih mudah untuk merefaktor kode
Kemampuan ditemukan - tampilan tunggal kode
Menghapus kepemilikan per tim
Berpotensi lebih sedikit konflik penggabungan
Membantu memberlakukan pemisahan layanan mikro
Tantangan Perubahan pada kode bersama dapat memengaruhi beberapa layanan mikro
Potensi yang lebih besar untuk konflik penggabungan
Alat harus menskalakan ke basis kode besar
Kontrol akses
Proses penyebaran yang lebih kompleks
Lebih sulit untuk berbagi kode
Lebih sulit untuk menerapkan standar pengodean
Manajemen dependensi
Basis kode difus, penemuan yang buruk
Kurangnya infrastruktur bersama

Memperbarui layanan

Ada berbagai strategi untuk memperbarui layanan yang sudah dalam produksi. Di sini kita membahas tiga opsi umum: Pembaruan bergulir, penyebaran biru-hijau, dan rilis kenari.

Pembaruan bergulir

Dalam pembaruan bergulir, Anda menyebarkan instans layanan baru, dan instans baru mulai menerima permintaan segera. Saat instans baru muncul, instans sebelumnya dihapus.

Contoh. Di Kubernetes, pembaruan bergulir adalah perilaku default saat Anda memperbarui spesifikasi pod untuk penyebaran . Pengontrol Penyebaran membuat ReplicaSet baru untuk pod yang diperbarui. Kemudian meningkatkan ReplicaSet baru sambil menurunkan skala replika lama, untuk mempertahankan jumlah replika yang diinginkan. Ini tidak menghapus pod lama sampai pod baru siap. Kubernetes menyimpan riwayat pembaruan, sehingga Anda dapat mengembalikan pembaruan jika diperlukan.

Contoh. Azure Service Fabric menggunakan strategi pembaruan bergulir secara default. Strategi ini paling cocok untuk menyebarkan versi layanan dengan fitur baru tanpa mengubah API yang ada. Service Fabric memulai penyebaran peningkatan dengan memperbarui jenis aplikasi ke subset simpul atau domain pembaruan. Kemudian digulirkan ke domain pembaruan berikutnya hingga semua domain ditingkatkan. Jika domain peningkatan gagal diperbarui, jenis aplikasi akan kembali ke versi sebelumnya di semua domain. Ketahuilah bahwa jenis aplikasi dengan beberapa layanan (dan jika semua layanan diperbarui sebagai bagian dari satu penyebaran peningkatan) rentan terhadap kegagalan. Jika satu layanan gagal diperbarui, seluruh aplikasi digulung balik ke versi sebelumnya dan layanan lain tidak diperbarui.

Salah satu tantangan pembaruan bergulir adalah bahwa selama proses pembaruan, campuran versi lama dan baru berjalan dan menerima lalu lintas. Selama periode ini, permintaan apa pun dapat dirutekan ke salah satu dari dua versi.

Untuk perubahan API yang melanggar, praktik yang baik adalah mendukung kedua versi secara berdampingan, sampai semua klien versi sebelumnya diperbarui. Lihatpenerapan versi API .

Penyebaran biru-hijau

Dalam penyebaran biru-hijau, Anda menyebarkan versi baru bersama versi sebelumnya. Setelah memvalidasi versi baru, Anda mengalihkan semua lalu lintas sekaligus dari versi sebelumnya ke versi baru. Setelah sakelar, Anda memantau aplikasi untuk masalah apa pun. Jika terjadi kesalahan, Anda dapat menukar kembali ke versi lama. Dengan asumsi tidak ada masalah, Anda dapat menghapus versi lama.

Dengan aplikasi monolitik atau N-tingkat yang lebih tradisional, penyebaran biru-hijau umumnya berarti menyediakan dua lingkungan yang identik. Anda akan menyebarkan versi baru ke lingkungan penahapan, lalu mengalihkan lalu lintas klien ke lingkungan penahapan — misalnya, dengan menukar alamat VIP. Dalam arsitektur layanan mikro, pembaruan terjadi pada tingkat layanan mikro, sehingga Anda biasanya akan menyebarkan pembaruan ke lingkungan yang sama dan menggunakan mekanisme penemuan layanan untuk bertukar.

Contoh. Di Kubernetes, Anda tidak perlu menyediakan kluster terpisah untuk melakukan penyebaran biru-hijau. Sebagai gantinya, Anda dapat memanfaatkan pemilih. Buat sumber daya Penyebaran baru dengan spesifikasi pod baru dan set label yang berbeda. Buat penyebaran ini, tanpa menghapus penyebaran sebelumnya atau memodifikasi layanan yang menunjuk ke penyebaran tersebut. Setelah pod baru berjalan, Anda dapat memperbarui pemilih layanan agar sesuai dengan penyebaran baru.

Salah satu kelemahan penyebaran biru-hijau adalah bahwa selama pembaruan, Anda menjalankan pod dua kali lebih banyak untuk layanan (saat ini dan berikutnya). Jika pod memerlukan banyak sumber daya CPU atau memori, Anda mungkin perlu meluaskan skala kluster untuk sementara waktu untuk menangani konsumsi sumber daya.

Rilis kenari

Dalam rilis kenari, Anda meluncurkan versi yang diperbarui ke sejumlah kecil klien. Kemudian Anda memantau perilaku layanan baru sebelum meluncurkannya ke semua klien. Ini memungkinkan Anda melakukan peluncuran lambat dengan cara yang terkontrol, mengamati data nyata, dan melihat masalah sebelum semua pelanggan terpengaruh.

Rilis kenari lebih kompleks untuk dikelola daripada pembaruan biru-hijau atau bergulir, karena Anda harus merutekan permintaan secara dinamis ke versi layanan yang berbeda.

Contoh. Di Kubernetes, Anda dapat mengonfigurasi Layanan untuk menjangkau dua set replika (satu untuk setiap versi) dan menyesuaikan jumlah replika secara manual. Namun, pendekatan ini agak kasar, karena cara Kubernetes memuat keseimbangan di seluruh pod. Misalnya, jika Anda memiliki total 10 replika, Anda hanya dapat mengalihkan lalu lintas dalam kenaikan 10%. Jika Anda menggunakan jala layanan, Anda dapat menggunakan aturan perutean jala layanan untuk menerapkan strategi rilis kenari yang lebih canggih.

Langkah berikutnya