Mikro hizmetler mimarileri için CI/CD

Azure

Daha hızlı yayın döngüleri, mikro hizmet mimarilerinin başlıca avantajlarından biridir. Ancak iyi bir CI/CD işlemi olmadan mikro hizmetlerin söz verdiği çevikliği elde etmezsiniz. Bu makalede zorluklar açıklanır ve soruna yönelik bazı yaklaşımlar önerilir.

CI/CD nedir?

CI/CD'den bahsederken, gerçekten ilgili birkaç işlemden bahsediyoruz: Sürekli tümleştirme, sürekli teslim ve sürekli dağıtım.

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

  • Sürekli teslim. CI işlemini geçen tüm 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ılmaya 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.

Mikro hizmet mimarisi için sağlam bir CI/CD işleminin bazı hedefleri şunlardır:

  • 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/QA ortamlarına dağıtılır. Kalite kapıları her aşamada zorunlu kılınmaktadır.

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

  • Yeterli erişim denetimi ilkeleri var.

  • Kapsayıcılı iş yükleri için üretime dağıtılan kapsayıcı görüntülerine güvenebilirsiniz.

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

Geleneksel monolitik bir uygulamada, çıkışı uygulama yürütülebilir dosyası olan tek bir derleme işlem hattı vardır. Tüm geliştirme iş akışları bu işlem hattına aktarılır. Yüksek öncelikli bir hata bulunursa, yeni özelliklerin yayınlanmasını geciktirebilecek bir düzeltmenin tümleştirilmesi, test edilmesi ve yayımlanması gerekir. İyi factored modüllerine sahip olarak ve kod değişikliklerinin etkisini en aza indirmek için özellik dallarını kullanarak bu sorunları azaltabilirsiniz. Ancak uygulama daha karmaşık hale geldikçe ve daha fazla özellik eklendikçe, monolith için yayın süreci daha kırılgan hale gelir ve kırılma olasılığı artar.

Mikro hizmetler felsefesine göre, her ekibin sıraya girmek zorunda olduğu uzun bir yayın treni asla olmamalıdır. "A" hizmetini oluşturan ekip, "B" hizmetindeki değişikliklerin birleştirilmesini, test edilip dağıtılmasını beklemeden istediği zaman bir güncelleştirme yayınlayabilir.

CI/CD monolith diyagramı

Yüksek 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. Üretime günde bir veya daha fazla kez yayın yaparsanız, regresyonlar veya hizmet kesintileri nadir olmalıdır. Aynı zamanda, hatalı bir güncelleştirme dağıtılırsa, 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.

Zorluklar

  • Birçok küçük bağımsız kod tabanı. Her ekip kendi derleme işlem hattıyla kendi hizmetini oluşturmakla sorumludur. Bazı kuruluşlarda ekipler ayrı kod depoları kullanabilir. Ayrı depolar, sistemin nasıl derlendiği bilgisinin ekipler arasında yayılmasına ve kuruluştaki kimsenin uygulamanın tamamının nasıl dağıtıldığını bilmediği bir duruma yol açabilir. Örneğin, yeni bir kümeye hızla dağıtmanız gerekiyorsa olağanüstü durum kurtarma senaryosunda ne olur?

    Azaltma: Bu bilginin her ekipte "gizli" olmaması için hizmetleri derlemek ve dağıtmak için birleştirilmiş ve otomatikleştirilmiş bir işlem hattına sahip olun.

  • Birden çok dil ve çerçeve. Her ekip kendi teknoloji karışımını kullandığından, kuruluş genelinde çalışan tek bir derleme süreci oluşturmak zor olabilir. Derleme süreci, her ekibin dile veya çerçeveye göre uyarlayabilecek kadar esnek olması gerekir.

    Azaltma: Her hizmet için derleme işlemini kapsayıcılı hale koyun. Bu şekilde derleme sisteminin kapsayıcıları çalıştırabilmesi gerekir.

  • Tümleştirme ve yük testi. Ekipler güncelleştirmeleri kendi hızına göre yayınladığında, özellikle hizmetlerin diğer hizmetlere bağımlılıkları olduğunda güçlü uçtan uca testler tasarlamak zor olabilir. Ayrıca, tam bir üretim kümesi çalıştırmak pahalı olabilir, bu nedenle her ekibin yalnızca test için üretim ölçeklerinde kendi tam kümesini çalıştırması pek olası değildir.

  • Sürüm yönetimi. Her ekip üretime bir güncelleştirme dağıtabilmelidir. Bu, her ekip üyesinin bunu yapma izni olduğu anlamına gelmez. Ancak merkezi bir Release Manager rolüne sahip olmak dağıtımların hızını azaltabilir.

    Azaltma: CI/CD işleminiz ne kadar otomatik ve güvenilir olursa merkezi bir yetkiliye o kadar az ihtiyaç duyulmalıdır. Ancak, önemli özellik güncelleştirmelerini yayınlamak için küçük hata düzeltmelerine karşı farklı ilkeleriniz olabilir. Merkezi olmayan olmak, idarenin sıfır olduğu anlamına gelmez.

  • Hizmet güncelleştirmeleri. Bir hizmeti yeni bir sürüme güncelleştirdiğinizde, buna bağlı olan diğer hizmetleri bozmamalıdır.

    Azaltma: Hataya neden olmayan değişiklikler için mavi-yeşil veya kanarya sürümü 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 şekilde, önceki API'yi kullanan hizmetler güncelleştirilebilir ve yeni API için test edilebilir. Aşağıdaki Hizmetleri güncelleştirme bölümüne bakın.

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

CI/CD iş akışı oluşturmadan önce kod tabanının nasıl yapılandırılacağını ve yönetileceğini bilmeniz gerekir.

  • Ekipler ayrı depolarda mı yoksa tek depoda mı (tek depo) çalışıyor?
  • Dallanma stratejiniz nedir?
  • Kimler üretime kod gönderebiliyor? Yayın yöneticisi rolü var mı?

Monorepo yaklaşımı iyiye gitmekte ancak her ikisinin de avantajları ve dezavantajları vardı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 görünümü
Ekip başına sahipliği temizle
Daha az birleştirme çakışması olabilir
Mikro hizmetlerin 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ına ölçeklendirilmelidir
Erişim denetimi
Daha karmaşık dağıtım işlemi
Kodu paylaşmak zor
Kodlama standartlarını zorunlu kılmak zor
Bağımlılık yönetimi
Kod tabanını dağıtma, zayıf bulunabilirlik
Paylaşılan altyapı eksikliği

Hizmetler güncelleştiriliyor

Zaten üretimde olan bir hizmeti güncelleştirmek için çeşitli stratejiler vardır. Burada üç yaygın seçeneği ele alıyoruz: Sıralı güncelleştirme, mavi-yeşil dağıtım ve kanarya sürümü.

Sıralı güncelleştirmeler

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

Örnek. Kubernetes'te dağıtım için pod belirtimini güncelleştirdiğinizde sıralı güncelleştirmeler varsayılan davranıştır. Dağıtım denetleyicisi güncelleştirilmiş podlar için yeni bir ReplicaSet oluşturur. Ardından, istenen çoğaltma sayısını korumak için eski çoğaltmanın ölçeğini daraltırken yeni ReplicaSet'in ölçeğini büyütür. Yenileri hazır olana kadar eski podları silmez. Kubernetes güncelleştirmenin geçmişini tutar, böylece gerekirse bir güncelleştirmeyi geri alabilirsiniz.

Örnek. Azure Service Fabric varsayılan olarak sıralı güncelleştirme stratejisini kullanır. Bu strateji, mevcut API'leri değiştirmeden hizmetin bir sürümünü yeni özelliklerle dağıtmak için en uygun stratejidir. Service Fabric, uygulama türünü düğümlerin bir alt kümesine veya bir güncelleştirme etki alanına güncelleştirerek bir yükseltme dağıtımı başlatır. Ardından tüm etki alanları yükseltilene kadar sonraki güncelleştirme etki alanına iletilir. Bir yükseltme etki alanı güncelleştirilemezse, uygulama türü tüm etki alanlarında önceki sürüme geri döner. Birden çok hizmeti olan bir uygulama türünün (ve tüm hizmetlerin bir yükseltme dağıtımının parçası olarak güncelleştirilmesi durumunda) hataya açık olduğunu unutmayın. Bir hizmet güncelleştirilemezse, uygulamanın tamamı önceki sürüme geri alınır ve diğer hizmetler güncelleştirilmez.

Sıralı güncelleştirmelerin zorluklarından biri, güncelleştirme işlemi sırasında eski ve yeni sürümlerin bir karışımının çalışması ve trafiği almasıdır. Bu süre boyunca, herhangi bir istek iki sürümden birine yönlendirilmiş olabilir.

Hataya neden olan API değişiklikleri için iyi bir uygulama, önceki sürümün tüm istemcileri güncelleştirilene kadar her iki sürümü de yan yana desteklemektir. Bkz. API sürümü oluşturma.

Mavi-yeşil dağıtım

Mavi-yeşil bir 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 önceki sürümden yeni sürüme bir kerede değiştirirsiniz. Anahtardan sonra, uygulamayı herhangi bir sorun için izlersiniz. Bir sorun olursa eski sürüme geri dönebilirsiniz. Sorun olmadığını varsayarsak eski sürümü silebilirsiniz.

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

Örnek. 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 pod belirtimi ve farklı bir etiket kümesiyle yeni bir Dağıtım kaynağı oluşturun. Önceki dağıtımı silmeden veya ona işaret eden hizmeti değiştirmeden bu dağıtımı oluşturun. 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 fazla pod çalıştırmanızdır (geçerli ve sonraki). Podlar çok fazla CPU veya bellek kaynağı gerektiriyorsa, kaynak tüketimini işlemek için kümenin ölçeğini geçici olarak genişletmeniz gerekebilir.

Kanarya yayını

Kanarya sürümünde, güncelleştirilmiş bir sürümü az sayıda istemciye dağıtacaksınız. Ardından, tüm istemcilere dağıtmadan önce yeni hizmetin davranışını izlersiniz. Bu, denetimli bir şekilde yavaş dağıtım yapmanızı, gerçek verileri gözlemlemenizi ve tüm müşteriler etkilenmeden önce sorunları tespit etmenizi sağlar.

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

Örnek. Kubernetes'te bir Hizmeti iki çoğaltma kümesine (her sürüm için bir tane) yayılacak şekilde yapılandırabilir ve çoğaltma sayısını el ile ayarlayabilirsiniz. Ancak Kubernetes'in podlar arasında yük dengeleme yönteminden dolayı bu yaklaşım oldukça kaba bir yaklaşımdır. Örneğin, toplam 10 çoğaltmanız varsa trafiği yalnızca %10 artışla 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.

Sonraki adımlar