Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Siklus rilis yang lebih cepat adalah keuntungan utama dari arsitektur layanan mikro. Tanpa integrasi berkelanjutan yang andal dan proses pengiriman berkelanjutan (CI/CD), Anda kehilangan kelincahan yang disediakan layanan mikro. Artikel ini menguraikan tantangan CI/CD umum dalam arsitektur layanan mikro dan merekomendasikan pendekatan untuk membangun, memvalidasi, mengamankan, dan menyebarkan layanan secara independen.
Apa itu CI/CD?
CI/CD mengacu pada beberapa proses terkait: integrasi berkelanjutan, pengiriman berkelanjutan, dan penyebaran berkelanjutan.
Integrasi berkelanjutan (CI): Perubahan kode sering digabungkan ke cabang utama. Proses build dan pengujian otomatis memastikan bahwa kode di cabang utama selalu berkualitas produksi.
Pengiriman berkelanjutan (CD): 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 selalu siap untuk disebarkan ke produksi.
Penyebaran berkelanjutan: Perubahan kode yang melewati dua langkah sebelumnya secara otomatis disebarkan ke dalam produksi.
Pertimbangkan tujuan berikut dari proses CI/CD yang kuat untuk arsitektur layanan mikro:
Setiap tim dapat membuat dan menyebarkan layanan yang dimilikinya secara independen, tanpa memengaruhi atau mengganggu tim lain.
Sebelum versi baru layanan disebarkan ke produksi, layanan disebarkan ke lingkungan dev/test dan QA untuk validasi. Gerbang kualitas ditegakkan pada setiap tahap.
Versi baru layanan dapat disebarkan berdampingan dengan versi sebelumnya.
Kebijakan kontrol akses yang memadai sudah ada. Pipeline melakukan autentikasi ke Azure menggunakan kredensial federatif berumur pendek, alih-alih rahasia berumur panjang.
Untuk beban kerja tercontainerisasi, Anda dapat mempercayai citra kontainer yang digunakan di lingkungan produksi. Kepercayaan tersebut dibangun melalui image yang ditandatangani, atestasi software bill of materials (SBOM), dan pemindaian kerentanan yang diterapkan di dalam pipeline.
Mengapa alur CI/CD yang kuat itu penting
Dalam aplikasi monolitik tradisional, satu alur build menghasilkan aplikasi yang dapat dieksekusi. Semua pekerjaan pengembangan disalurkan ke dalam alur ini. Jika tim menemukan bug berprioritas tinggi, perbaikan harus diintegrasikan, diuji, dan diterbitkan, yang dapat menunda rilis fitur baru. Anda dapat mengurangi masalah ini dengan menggunakan modul dan cabang fitur yang diperhitungkan dengan baik untuk membatasi efek perubahan kode. Tetapi ketika aplikasi tumbuh lebih kompleks dan lebih banyak fitur ditambahkan, proses rilis untuk monolit cenderung menjadi lebih rumit dan cenderung gagal.
Menurut filosofi mikrolayanan, seharusnya tidak pernah ada proses rilis panjang yang mengharuskan setiap tim mengantre giliran. Tim yang membangun layanan A dapat merilis pembaruan saat memilih dan tidak perlu menunggu perubahan dalam layanan B untuk menggabungkan, menguji, dan menyebarkan.
Untuk mencapai kecepatan rilis yang tinggi, alur rilis Anda harus otomatis dan sangat dapat diandalkan untuk meminimalkan risiko. Jika Anda merilis ke lingkungan produksi satu atau beberapa kali setiap hari, regresi atau gangguan layanan seharusnya jarang terjadi. Pada saat yang sama, jika Anda menyebarkan pembaruan yang buruk, Anda harus memiliki cara yang dapat diandalkan untuk dengan cepat mengembalikan atau meneruskan ke versi layanan sebelumnya.
Challenges
Banyak basis kode independen kecil: Setiap tim bertanggung jawab untuk membangun layanannya sendiri, dengan alur buildnya sendiri. Di beberapa organisasi, tim mungkin menggunakan repositori kode terpisah. Repositori terpisah dapat menyebarkan pengetahuan tentang cara membangun sistem di seluruh tim. Akibatnya, tidak ada orang di organisasi yang tahu cara menyebarkan seluruh aplikasi.
Mitigasi: Memiliki alur terpadu dan otomatis atau setidaknya infrastruktur alur umum untuk membangun dan menyebarkan layanan sehingga pengetahuan ini tidak disembunyikan dalam setiap tim. Templat alur yang dapat digunakan kembali, seperti GitHub Actions alur kerja yang dapat digunakan kembali atau templat Azure Pipelines, membantu menstandarkan langkah-langkah build, pengujian, pemindaian, dan penyebaran di setiap layanan.
Beberapa bahasa dan kerangka kerja: Setiap tim menggunakan campuran teknologinya sendiri, sehingga mungkin sulit untuk membuat satu proses build yang berfungsi di seluruh beban kerja. Proses build harus cukup fleksibel sehingga setiap tim dapat menyesuaikannya untuk bahasa atau kerangka kerja yang mereka pilih.
Mitigasi: Kontainerisasi proses build untuk setiap layanan sehingga sistem build hanya perlu menjalankan kontainer. Platform seperti tugas GitHub Actions, Azure Pipelines, dan Azure Container Registry dapat membangun dan menerbitkan gambar kontainer secara konsisten terlepas dari bahasa sumbernya.
Integrasi dan pengujian beban: Teams merilis pembaruan dengan kecepatan mereka sendiri, sehingga dapat menantang untuk merancang pengujian end-to-end yang kuat, terutama ketika layanan memiliki dependensi pada layanan lain. Menjalankan kluster produksi penuh bisa mahal, jadi tidak mungkin setiap tim menjalankan kluster penuhnya sendiri pada skala produksi hanya untuk pengujian.
Mitigation: Gunakan lingkungan pratinjau ephemeral, seperti namespace per-pull-request di Kubernetes atau lingkungan Azure Container Apps yang dibuat sesuai permintaan. Gunakan pengujian kontrak sehingga Anda memunculkan masalah integrasi lebih awal tanpa memerlukan duplikat produksi skala penuh.
Manajemen rilis: Setiap tim harus dapat menyebarkan pembaruan ke produksi. Persyaratan tersebut tidak berarti bahwa setiap anggota tim memiliki izin untuk melakukan deployment. Peran manajer rilis terpusat dapat mengurangi kecepatan penyebaran.
Mitigasi: Semakin banyak proses CI/CD Anda otomatis dan dapat diandalkan, semakin sedikit Anda membutuhkan otoritas pusat. Anda mungkin masih memiliki kebijakan yang berbeda untuk merilis pembaruan fitur utama versus perbaikan bug minor. Pendekatan terdesentralisasi tidak berarti tata kelola nol. Terapkan persetujuan dengan menggunakan lingkungan dan persetujuan Azure Pipelines atau GitHub Actions dan peninjau yang diperlukan, dan mengkodifikasi kebijakan sisi kluster dengan menggunakan Azure Policy untuk Azure Kubernetes Service (AKS) atau OPA Gatekeeper.
Pembaruan layanan: Saat Anda memperbarui layanan ke versi baru, pembaruan tidak boleh menyebabkan layanan lain yang bergantung padanya gagal.
Mitigasi: Gunakan teknik penyebaran seperti rilis biru-hijau atau kenari untuk perubahan yang tidak pecah. Untuk perubahan API yang signifikan, luncurkan versi baru berdampingan dengan versi sebelumnya. Dengan pendekatan ini, layanan yang menggunakan API sebelumnya dapat diperbarui dan diuji untuk API baru. Untuk informasi selengkapnya, lihat Memperbarui layanan.
Identitas pipeline dan pengelolaan rahasia: Rahasia service principal berjangka panjang yang disimpan dalam pipeline sering menjadi sumber kompromi keamanan dan beban operasional. Rahasia perwakilan layanan kedaluwarsa, dapat bocor, dan memerlukan rotasi di banyak alur layanan mikro independen.
Mitigasi: Autentikasi pipeline ke Azure dengan federasi identitas beban kerja, yang menggunakan OpenID Connect (OIDC), sehingga tidak ada client secret yang disimpan di pipeline. Untuk informasi selengkapnya, lihat identitas Workload untuk Azure Pipelines dan Konfigurasi OpenID Connect di Azure untuk GitHub Actions. Simpan rahasia yang tersisa di Azure Key Vault dan referensikan pada waktu proses.
Keamanan rantai pasokan: Semua yang Anda kirim ke produksi harus dapat ditelusuri kembali ke kode dan dependensi yang menjadi dasar pembangunannya. Layanan mikro meningkatkan jumlah gambar, registri, dan alur, yang meningkatkan permukaan serangan rantai pasokan Anda.
Mitigation: Menandatangani gambar kontainer dengan menggunakan Notation dan Key Vault, dan verifikasi tanda tangan pada waktu penerimaan dengan menggunakan integritas gambar AKS atau Ratify. Buat SBOM sebagai artefak hasil build. Pindai kode, dependensi, dan alur dengan menggunakan keamanan Microsoft Defender untuk Cloud DevOps dan GitHub Advanced Security. Pindai gambar runtime dengan menggunakan Microsoft Defender untuk Kontainer. Wajibkan semua pemindaian lulus sebelum rilis dapat dilanjutkan.
Monorepo vs. multirepo
Sebelum membuat alur kerja CI/CD, Anda harus tahu bagaimana basis kode terstruktur dan dikelola, termasuk:
- Apakah tim bekerja di repositori terpisah atau monorepo.
- Strategi percabangan Anda.
- Siapa yang dapat mendorong kode ke produksi dan apakah ada manajer rilis.
Tim secara luas menggunakan kedua pendekatan dalam produksi. Pilihan Anda tergantung pada topologi tim, kematangan alat, dan berapa banyak kode yang dibagikan di seluruh layanan.
| Monorepo | Beberapa repositori | |
|---|---|---|
| Kelebihan | - Berbagi kode - Lebih mudah untuk menstandarkan kode dan alat - Lebih mudah untuk merefaktor kode - Kemudahan ditemukan (satu tampilan untuk 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 konflik penggabungan yang lebih besar - Perkakas harus dapat menangani basis kode yang besar - Kontrol akses - Proses penyebaran yang lebih kompleks |
- Lebih sulit untuk berbagi kode - Lebih sulit untuk menerapkan standar pengkodean - Manajemen dependensi - Basis kode difus, penemuan yang buruk - Kurangnya infrastruktur bersama |
Terlepas dari model yang Anda pilih, gunakan pemicu berbasis jalur dalam pipeline Anda, seperti filter jalur di GitHub Actions atau jalur pemicu di Azure Pipelines. Pemicu berbasis jalur membantu memastikan bahwa hanya layanan mikro yang terdampak yang dibangun ulang dan diterapkan ulang pada setiap commit.
Memperbarui layanan
Ada berbagai strategi untuk memperbarui layanan yang sudah berjalan di lingkungan produksi, termasuk rolling update, blue-green deployment, dan canary release. Pola-pola ini sering dikoordinasikan melalui alur kerja GitOps. Untuk informasi selengkapnya, lihat GitOps dan pengiriman progresif.
Pembaruan bergulir
Dalam pembaruan bergulir, Anda menyebarkan instans layanan baru, dan instans baru mulai segera menerima permintaan. Saat instans baru siap, instans sebelumnya dihapus.
Contoh di Kubernetes: Di Kubernetes, pembaruan bergulir adalah perilaku default saat Anda memperbarui spesifikasi pod untuk penyebaran. Pengontrol penyebaran membuat ReplicaSet baru untuk pod yang diperbarui. Kemudian, sistem tersebut meningkatkan skala ReplicaSet baru sambil menurunkan skala ReplicaSet sebelumnya untuk mempertahankan jumlah replika yang diinginkan. Ini tidak menghapus pod sebelumnya sampai pod baru siap. Kubernetes menyimpan riwayat pembaruan, sehingga Anda dapat mengembalikan pembaruan jika diperlukan.
Contoh di Aplikasi Kontainer: Container Apps menggunakan revisi untuk mengelola pembaruan bergulir. Saat Anda menyebarkan revisi baru, Container Apps dapat secara bertahap mengalihkan lalu lintas dari revisi sebelumnya ke revisi baru dengan menggunakan aturan pemisahan lalu lintas. Jika revisi baru mengalami masalah, Anda dapat kembali dengan mengalihkan lalu lintas ke revisi sebelumnya. Anda dapat mengonfigurasi beberapa revisi aktif secara bersamaan dan mengontrol persentase lalu lintas yang diterima setiap revisi.
Salah satu tantangan dari pembaruan bergulir adalah, selama proses pembaruan, versi lama dan versi baru berjalan secara bersamaan dan menerima trafik. Selama periode ini, sistem dapat merutekan permintaan apa pun ke salah satu versi.
Untuk perubahan API yang bersifat memutus kompatibilitas, praktik yang baik adalah mendukung kedua versi secara bersamaan, sampai semua pengguna versi sebelumnya diperbarui. Untuk informasi selengkapnya, lihat Penerapan 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 peralihan, Anda memantau aplikasi apakah ada masalah. Jika ada masalah, Anda dapat mengalihkan lalu lintas kembali ke versi sebelumnya. Jika tidak ada masalah, Anda dapat menghapus versi sebelumnya.
Dengan aplikasi monolitik atau N-tingkat yang lebih tradisional, penyebaran biru-hijau umumnya berarti Anda membuat dua lingkungan yang identik. Anda menyebarkan versi baru ke lingkungan penahapan lalu mengalihkan lalu lintas klien ke lingkungan tersebut, seperti dengan menukar alamat IP virtual. Dalam arsitektur layanan mikro, pembaruan terjadi pada tingkat layanan mikro, sehingga Anda biasanya menyebarkan pembaruan ke lingkungan yang sama dan menggunakan mekanisme penemuan layanan untuk mengalihkan lalu lintas.
Contoh di Kubernetes: Di Kubernetes, Anda tidak perlu membuat kluster terpisah untuk melakukan penyebaran biru-hijau. Sebagai gantinya, Anda dapat memanfaatkan pemilih. Buat sumber daya penyebaran baru dengan spesifikasi pod baru dan serangkaian label yang berbeda. Buat penyebaran ini, tetapi jangan hapus penyebaran sebelumnya atau ubah layanan yang menunjuk ke penyebaran tersebut. Setelah pod baru berjalan, Anda dapat memperbarui pemilih layanan agar sesuai dengan penyebaran baru.
Salah satu kelemahan dari penyebaran biru-hijau adalah selama pembaruan, Anda menjalankan jumlah Pod dua kali lipat untuk layanan (saat ini dan berikutnya). Jika pod menggunakan sumber daya CPU atau memori yang substansial, Anda mungkin perlu menskalakan kluster untuk sementara untuk memenuhi permintaan sumber daya yang lebih tinggi.
Rilis kenari
Dalam rilis canary, Anda menerapkan versi yang diperbarui ke sebagian kecil klien, lalu memantau perilaku layanan baru tersebut sebelum menerapkannya ke semua klien. Dengan pendekatan ini, Anda dapat meluncurkan secara bertahap dengan cara yang terkontrol, memantau data nyata, dan mengidentifikasi masalah sebelum memengaruhi semua pelanggan.
Rilis canary lebih kompleks untuk dikelola daripada pembaruan blue-green atau rolling update karena Anda harus mengarahkan permintaan secara dinamis ke berbagai versi layanan.
Contoh di Kubernetes: Di Kubernetes, Anda dapat mengonfigurasi layanan untuk menjangkau dua set replika (satu untuk setiap versi) dan menyesuaikan jumlah replika secara manual. Namun, pendekatan ini bersifat umum karena cara Kubernetes mendistribusikan beban ke seluruh pod. Misalnya, jika Anda memiliki total 10 replika, Anda hanya dapat mengalihkan lalu lintas dengan peningkatan 10%. Jika Anda menggunakan jala layanan, Anda dapat menggunakan aturan perutean jala layanan untuk menerapkan strategi rilis kenari yang lebih canggih.
Contoh di Container Apps: Di Container Apps, Anda dapat menggunakan pembagian lalu lintas untuk mengarahkan persentase lalu lintas tertentu ke revisi baru (misalnya 10% ke v2 sementara 90% tetap diarahkan ke v1) dan menyesuaikan bobotnya seiring meningkatnya keyakinan, tanpa memerlukan service mesh eksternal.
Pengiriman progresif dan GitOps
Untuk tim yang mengoperasikan banyak layanan mikro di Kubernetes, model berbasis penarikan GitOps melengkapi contoh berbasis push sebelumnya. Status kluster yang diinginkan berada di Git, dan operator dalam kluster mendamaikan kluster dengan status tersebut. CI membangun, menguji, memindai, menandatangani, dan mengirim image. CD menyelaraskan kluster dengan manifest. Pemisahan ini memberi Anda jejak audit dan pemulihan bencana (DR) yang lebih mudah. Ini juga menghilangkan kebutuhan agar runner CI menyimpan kredensial kluster secara langsung.
Langkah berikutnya
- Jalur pembelajaran: Tentukan dan terapkan CI
- Pelatihan: Pengembangan untuk Enterprise DevOps
- arsitektur layanan mikro