Mikro hizmetler için CI/CD

Daha hızlı sürüm döngüleri, mikro hizmet mimarilerinin önemli bir avantajıdır. Güvenilir bir sürekli tümleştirme ve sürekli teslim (CI/CD) işlemi olmadan mikro hizmetlerin sağladığı çevikliği kaybedersiniz. Bu makalede mikro hizmet mimarilerindeki yaygın CI/CD zorlukları özetlenmektedir ve hizmetleri bağımsız olarak derleme, doğrulama, güvenlik altına almak ve dağıtmak için yaklaşımlar önerilir.

CI/CD nedir?

CI/CD çeşitli ilgili işlemleri ifade eder: sürekli tümleştirme, sürekli teslim ve sürekli dağıtım.

  • Sürekli tümleştirme (CI): Kod değişiklikleri genellikle ana dalda birleştirilir. Otomatik derleme ve test işlemleri, ana daldaki kodun her zaman üretim kalitesi olmasını sağlar.

  • Sürekli teslim (CD): CI işlemini geçiren kod değişiklikleri otomatik olarak üretim benzeri bir ortama yayımlanır. Canlı üretim ortamına dağıtım için el ile onay gerekebilir, ancak aksi takdirde otomatikleştirilmiştir. Amaç, kodunuzun her zaman üretime dağıtıma hazır olmasıdır.

  • Sürekli dağıtım: Önceki iki adımı geçen kod değişiklikleri otomatik olarak üretime dağıtılır.

Bir mikro hizmet mimarisi için sağlam bir CI/CD işleminin aşağıdaki hedeflerini göz önünde bulundurun:

  • Her ekip, sahip olduğu hizmetleri diğer ekipleri etkilemeden veya kesintiye uğratmadan bağımsız olarak derleyebilir ve dağıtabilir.

  • Hizmetin yeni bir sürümü üretime dağıtılmadan önce doğrulama için geliştirme/test ve Soru-Cevap ortamlarına dağıtılır. Kalite kontrol kapıları her aşamada uygulanır.

  • Hizmetin yeni bir sürümü, önceki sürümle yan yana dağıtılabilir.

  • Yeterli erişim denetimi ilkeleri var. İşlem hatları, uzun ömürlü gizli anahtarlar yerine federe, kısa ömürlü kimlik bilgileri kullanarak Azure’da kimlik doğrulaması yaparlar.

  • Kapsayıcılı iş yükleri için üretime dağıtılan kapsayıcı görüntülerine güvenebilirsiniz. Bu güven, imzalı görüntüler, yazılım malzeme listesi (SBOM) kanıtlamaları ve işlem hattında zorunlu kılınan güvenlik açığı taraması aracılığıyla oluşturulur.

Güçlü bir CI/CD işlem hattı neden önemlidir?

Geleneksel monolitik bir uygulamada, tek bir derleme işlem hattı uygulamanın çalıştırılabilir dosyasını üretir. Tüm geliştirme iş akışları bu işlem hattına aktarılır. Ekip yüksek öncelikli bir hata bulursa, düzeltmenin tümleştirilmesi, test edilmesi ve yayımlanması gerekir ve bu da yeni özelliklerin yayımlanmasını geciktirebilir. Kod değişikliklerinin etkisini sınırlamak için iyi yapılandırılmış modüller ve özellik dalları kullanarak bu sorunları azaltabilirsiniz. Ancak uygulama daha karmaşık hale geldikçe ve daha fazla özellik eklendikçe, monolit için yayın süreci daha karmaşık hale gelir ve başarısız olma olasılığı artar.

Mikro hizmetler felsefesine göre, her ekibin sıraya girmek zorunda olduğu uzun bir sürüm süreci asla olmamalıdır. A hizmetini geliştiren ekip, istediği zaman bir güncelleme yayımlayabilir ve B hizmetindeki değişikliklerin birleştirilmesini, test edilmesini ve dağıtıma alınmasını beklemek zorunda değildir.

Monolith ile mikro hizmet mimarileri için CI/CD karşılaştırması sağlayan diyagram.

Yüksek bir yayın hızı elde etmek için, riski en aza indirmek için yayın işlem hattınızın otomatik ve son derece güvenilir olması gerekir. Günde bir veya daha fazla kez üretime yayın yapıyorsanız, regresyonlar veya hizmet kesintileri nadir olmalıdır. Aynı zamanda, hatalı bir güncelleştirme dağıtırsanız, hizmetin önceki bir sürümüne hızlı bir şekilde geri dönmek veya ileri gitmek için güvenilir bir yönteme sahip olmanız gerekir.

Challenges

  • Birçok küçük bağımsız kod temeli: Her ekip kendi derleme işlem hattı ile kendi hizmetini oluşturmakla sorumludur. Bazı kuruluşlarda ekipler ayrı kod depoları kullanabilir. Ayrı depolar, sistemin nasıl oluşturulacağına dair bilginin ekipler arasında dağılmasına neden olabilir. Sonuç olarak, kuruluştaki hiç kimse uygulamanın tamamının nasıl dağıtılacağı hakkında bilgi edinmez.

    Önlem: Bu bilginin her ekibin içinde gizli kalmaması için, hizmetleri derlemek ve dağıtmak üzere birleşik ve otomatik bir işlem hattına veya en azından ortak bir işlem hattı altyapısına sahip olun. GitHub Actions yeniden kullanılabilir iş akışları veya Azure Pipelines şablonları gibi yeniden kullanılabilir işlem hattı şablonları derleme, test, tarama ve dağıtma adımlarının her hizmette standartlaştırılmasına yardımcı olur.

  • Birden çok dil ve çerçeve: Her ekip kendi teknoloji karışımını kullandığından, iş yükünde çalışan tek bir derleme işlemi oluşturmak zor olabilir. Derleme süreci, her ekibin bunu seçtikleri dil veya çerçeve için uyarlayabilecek kadar esnek olmalıdır.

    Önlem: Derleme sisteminin yalnızca kapsayıcıları çalıştırması yeterli olacak şekilde, her hizmet için derleme sürecini kapsayıcılaştırın. GitHub Actions, Azure Pipelines ve Azure Container Registry görevleri gibi platformlar, kaynak dilden bağımsız olarak kapsayıcı görüntülerini tutarlı bir şekilde derleyebilir ve yayımlayabilir.

  • Tümleştirme ve yük testi: Teams güncelleştirmeleri kendi hızlarında yayımladığından, özellikle hizmetlerin diğer hizmetlere bağımlılıkları olduğunda güçlü uçtan uca test tasarlamanız zor olabilir. Tam bir üretim kümesi çalıştırmak maliyetli olabilir, bu nedenle her ekibin yalnızca test için üretim ölçeğinde kendi tam kümesini çalıştırması olası değildir.

    Mitigation: Kubernetes veya Azure Container Apps ortamlarındaki çekme isteği başına ad alanları gibi kısa ömürlü önizleme ortamları kullanın isteğe bağlı olarak oluşturulur. Sözleşme testlerini kullanarak tümleştirme sorunlarını üretimin tam ölçekli bir kopyasını gerektirmeden erken ortaya çıkarabilirsiniz.

  • Sürüm yönetimi: Her ekip üretime bir güncelleştirme dağıtabilmelidir. Bu gereksinim, her ekip üyesinin dağıtım iznine sahip olduğu anlamına gelmez. Merkezi sürüm yöneticisi rolü dağıtım hızını azaltabilir.

    Önlem: CI/CD süreciniz ne kadar otomatik ve güvenilir olursa, merkezi bir otoriteye duyduğunuz ihtiyaç da o kadar azalır. Ana özellik güncelleştirmelerini yayımlamak için küçük hata düzeltmelerine karşı farklı ilkeleriniz olabilir. Merkezi olmayan bir yaklaşım sıfır idare anlamına gelmez. Azure Pipelines ortamlarını ve onaylarını veya GitHub Actions dağıtım ortamlarını ve zorunlu gözden geçirenleri kullanarak onayları zorunlu kılın ve küme tarafı ilkesini Azure İlkesi for Azure Kubernetes Service (AKS) veya OPA Gatekeeper kullanarak tanımlayın.

  • Hizmet güncelleştirmeleri: Bir hizmeti yeni bir sürüme güncelleştirdiğinizde güncelleştirme, hizmete bağımlı olan diğer hizmetlerin başarısız olmasına neden olmamalıdır.

    Risk azaltma: Geriye dönük uyumluluğu bozmayan değişiklikler için mavi-yeşil veya kanarya dağıtımları gibi dağıtım tekniklerini kullanın. Hataya neden olan API değişiklikleri için yeni sürümü önceki sürümle yan yana dağıtın. Bu yaklaşımla, önceki API'yi kullanan hizmetler güncelleştirilebilir ve yeni API için test edilebilir. Daha fazla bilgi için Güncelleştirme hizmetleri bölümüne bakın.

  • İşlem hattı kimliği ve gizli bilgi yönetimi: İşlem hatlarında depolanan uzun ömürlü hizmet sorumlusu gizli bilgileri, güvenlik ihlallerinin ve operasyonel ek yükün sık karşılaşılan bir kaynağıdır. Hizmet sorumlusu gizli dizilerinin süresi dolar, sızıntı yapabilir ve birçok bağımsız mikro hizmet işlem hattında döndürme gerektirebilir.

    Mitigation: OpenID Connect (OIDC) kullanan iş yükü kimlik federasyonuyla Azure için işlem hatlarının kimliğini doğrulayın, böylece işlem hattında hiçbir istemci gizli dizisi depolanmaz. Daha fazla bilgi için bkz. Azure Pipelines için iş yükü kimlikleri ve GitHub Actions için Azure’da OpenID Connect’i yapılandırma. Kalan tüm gizli anahtarları Azure Key Vault içinde depolayın ve çalışma zamanında bunlara başvurun.

  • Tedarik zinciri güvenliği: Üretime sevk ettiğiniz her şey, oluşturulduğu koda ve bağımlılıklara göre izlenebilir olmalıdır. Mikro hizmetler görüntü, kayıt defteri ve işlem hattı sayısını artırarak tedarik zinciri saldırı yüzeyinizi artırır.

    Mitigation: Notation ve Key Vault, ve AKS görüntü bütünlüğü veya Ratify kullanarak erişim zamanında imzaları doğrulayın. Bir SBOM’u derleme çıktısı olarak oluşturun. Microsoft Defender for Cloud DevOps güvenliği ve GitHub Gelişmiş Güvenlik kullanarak kodu, bağımlılıkları ve işlem hatlarını tarayın. Kapsayıcılar için Microsoft Defender kullanarak çalışma zamanı görüntülerini tarayın. Bir sürümün devam edebilmesi için tüm taramaların başarılı olması zorunludur.

Monorepo ve çoklu depo karşılaştırması

CI/CD iş akışı oluşturmadan önce kod tabanının nasıl yapılandırıldığını ve yönetildiğini bilmeniz gerekir; örneğin:

  • Ekiplerin ayrı depolarda mı yoksa bir monorepoda mı çalıştığı.
  • Dallanma stratejiniz.
  • Kim üretime kod gönderebilir ve bir yayın yöneticisi olup olmadığı.

Ekipler üretimde her iki yaklaşımı da yaygın olarak kullanır. Seçiminiz ekip topolojisi, araç olgunluğu ve hizmetler arasında ne kadar kodun paylaşılmış olduğuna bağlıdır.

  Monorepo Birden çok depo
Avantajlar - Kod paylaşımı

- Kodu ve araçları standart hale getirmek daha kolay

- Kodu yeniden düzenlemek daha kolay

- Bulunabilirlik (kodun tek bir görünümü)
- Her ekip için net sorumluluk

- Potansiyel olarak daha az birleştirme çakışması

- Mikro hizmet ayrıştırmasını zorunlu kılmaya yardımcı olur
Zorluklar - Paylaşılan kodda yapılan değişiklikler birden çok mikro hizmeti etkileyebilir

- Birleştirme çakışmaları için daha fazla potansiyel

- Araçlar büyük bir kod tabanını destekleyecek şekilde ölçeklenebilmelidir

- Erişim denetimi

- Daha karmaşık dağıtım işlemi
- Kodu paylaşmak daha zor

- Kodlama standartlarını zorunlu kılmak daha zor

- Bağımlılık yönetimi

- Kod tabanını dağıtma, zayıf bulunabilirlik

- Paylaşılan altyapı eksikliği

Seçtiğiniz model ne olursa olsun, işlem hatlarınızda GitHub Actions’taki yol filtreleri veya Azure Pipelines’taki tetikleme yolları gibi yol kapsamlı tetikleyiciler kullanın. Yol kapsamlı tetikleyiciler, yalnızca etkilenen mikro hizmetlerin her işlemede yeniden oluşturulmasını ve yeniden dağıtılmasını sağlamaya yardımcı olur.

Hizmetleri güncelleştirme

Zaten üretimde olan bir hizmeti güncelleştirmek için sıralı güncelleştirme, mavi-yeşil dağıtım ve kanarya sürümü gibi çeşitli stratejiler vardır. Bu desenler genellikle gitOps iş akışı aracılığıyla koordine edilir. Daha fazla bilgi için bkz. GitOps ve aşamalı teslim.

Sıralı güncelleştirmeler

Sıralı bir güncelleştirmede, bir hizmetin yeni örneklerini dağıtırsınız ve yeni örnekler istekleri hemen almaya başlar. Yeni örnekler hazır hale geldikçe, önceki örnekler kaldırılır.

Kubernetes örneği: Kubernetes'te dağıtım için pod belirtimini güncelleştirdiğinizde varsayılan davranış sıralı güncelleştirmelerdir. Dağıtım denetleyicisi güncelleştirilmiş podlar için yeni bir ReplicaSet oluşturur. Ardından, istenen replika sayısını korumak için önceki ReplicaSet'in ölçeğini azaltırken yeni ReplicaSet'in ölçeğini artırır. Yeni podlar hazır olana kadar önceki podları silmez. Kubernetes güncelleştirmenin geçmişini tutar, böylece gerekirse güncelleştirmeyi geri alabilirsiniz.

Container Apps örneği: Container Apps, sıralı güncelleştirmeleri yönetmek için düzeltmeleri kullanır. Yeni bir düzeltme dağıttığınızda, Container Apps trafik bölme kurallarını kullanarak trafiği önceki düzeltmeden yeni düzeltmeye aşamalı olarak kaydırabilir. Yeni düzeltme sorunlarla karşılaşırsa, trafiği önceki düzeltmeye yeniden yönlendirerek geri alabilirsiniz. Aynı anda birden çok etkin düzeltme yapılandırabilir ve her düzeltmenin aldığı trafik yüzdesini denetleyebilirsiniz.

Güncelleştirmelerin sıralı olmasındaki zorluklardan biri, güncelleştirme işlemi sırasında önceki ve yeni sürümlerin bir karışımının çalıştırılması ve trafiği almasıdır. Bu süre boyunca sistem herhangi bir isteği her iki sürüme de yönlendirebilir.

Hataya neden olan API değişiklikleri için, önceki sürümün tüm istemcileri güncelleştirilene kadar her iki sürümü de yan yana desteklemek iyi bir uygulamadır. Daha fazla bilgi için bkz. API sürümü oluşturma.

Mavi-yeşil dağıtım stratejisi

Mavi-yeşil dağıtımda, yeni sürümü önceki sürümle birlikte dağıtırsınız. Yeni sürümü doğruladıktan sonra, tüm trafiği bir kerede önceki sürümden yeni sürüme geçirebilirsiniz. Değişimden sonra, herhangi bir sorun için uygulamayı izlersiniz. Bir sorun varsa trafiği önceki sürüme geri döndürebilirsiniz. Sorun yoksa önceki sürümü silebilirsiniz.

Daha geleneksel monolitik veya N katmanlı bir uygulamayla, mavi-yeşil dağıtım genellikle iki özdeş ortam oluşturduğunuz anlamına gelir. Yeni sürümü bir hazırlama ortamına dağıtır ve ardından sanal IP adresini değiştirerek istemci trafiğini bu ortama yeniden yönlendirirsiniz. Mikro hizmetler mimarisinde güncelleştirmeler mikro hizmet düzeyinde gerçekleşir, bu nedenle genellikle güncelleştirmeyi aynı ortama dağıtırsınız ve trafiği değiştirmek için bir hizmet bulma mekanizması kullanırsınız.

Kubernetes örneği: Kubernetes'te mavi-yeşil dağıtımlar yapmak için ayrı bir küme oluşturmanız gerekmez. Bunun yerine seçicilerden yararlanabilirsiniz. Yeni bir pod belirtimi ve farklı bir etiket kümesiyle yeni bir dağıtım kaynağı oluşturun. Bu dağıtımı oluşturun, ancak önceki dağıtımı silmeyin veya ona işaret eden hizmeti değiştirmeyin. Yeni podlar çalıştırıldıktan sonra hizmetin seçicisini yeni dağıtımla eşleşecek şekilde güncelleştirebilirsiniz.

Mavi-yeşil dağıtımın bir dezavantajı, güncelleştirme sırasında hizmet için iki kat daha fazla pod çalıştırmanızdır (geçerli ve sonraki). Podlar önemli CPU veya bellek kaynakları kullanıyorsa, daha yüksek kaynak talebini karşılamak için kümenin ölçeğini geçici olarak genişletmeniz gerekebilir.

Kanarya sürümü

Kanarya sürümünde, güncelleştirilmiş bir sürümü istemcilerin küçük bir alt kümesine dağıtır ve ardından tüm istemcilere dağıtmadan önce yeni hizmetin davranışını izlersiniz. Bu yaklaşımla aşamalı olarak denetimli bir şekilde dağıtabilir, gerçek verileri izleyebilir ve tüm müşterileri etkilemeden önce sorunları belirleyebilirsiniz.

İstekleri hizmetin farklı sürümlerine dinamik olarak yönlendirmeniz gerektiğinden, bir kanarya sürümünün yönetilmesi mavi-yeşil veya sıralı güncelleştirmeden daha karmaşıktır.

Kubernetes örneği: Kubernetes'te bir hizmeti iki çoğaltma kümesine (her sürüm için bir tane) yayacak şekilde yapılandırabilir ve çoğaltma sayısını el ile ayarlayabilirsiniz. Ancak Kubernetes'in podlar arasında yük dengelemesi nedeniyle bu yaklaşım daha ayrıntılıdır. Örneğin, toplamda 10 çoğaltmanız varsa, trafiği yalnızca %10'luk dilimler halinde kaydırabilirsiniz. Bir hizmet ağı kullanıyorsanız, daha gelişmiş bir kanarya yayın stratejisi uygulamak için hizmet ağı yönlendirme kurallarını kullanabilirsiniz.

Container Apps örneği: Container Apps'te, trafik bölme özelliğini kullanarak trafiğin belirli bir yüzdesini yeni bir revizyona gönderebilirsiniz (örneğin, trafiğin %10'u v2 öğesine giderken %90'ı v1 üzerinde kalır) ve harici bir servis ağı gerekmeden, güven arttıkça bu ağırlıkları değiştirebilirsiniz.

Aşamalı teslim ve GitOps

Kubernetes'te birçok mikro hizmet çalıştıran ekipler için GitOps çekme tabanlı model, önceki gönderme tabanlı örnekleri tamamlar. İstenen küme durumu Git'te bulunur ve küme içi işleç kümeyi bu durumla mutabık tutar. CI, imajı derler, test eder, tarar, imzalar ve gönderir. CD, kümeyi manifest ile uyumlu hale getirir. Bu ayrım, denetim izleri ve daha kolay olağanüstü durum kurtarma (DR) sağlar. Ayrıca CI çalıştırıcısının doğrudan küme kimlik bilgilerini elinde bulundurma gereksinimini de ortadan kaldırır.

Sonraki Adımlar