Yazar: Clare Liguori

Amazon’daki işim için mülakatta olduğum sırada mülakat görevlilerinden birine şu soruyu sordum: “Üretim için ne sıklıkta dağıtım yapıyorsunuz?” O sıralarda senede bir ya da iki kere kullanıma sunulan bir ürün üzerinde çalışıyordum ve önemli sunum tarihleri arasında bazen küçük düzeltmeler de yayımlamaya ihtiyacım oluyordu. Yayımladığım her bir düzeltme için saatlerce ve dikkatli şekilde piyasaya sunum çalışmaları yürütürdüm. Ardından, dağıtım sonrası herhangi bir sorun olup olmadığını görmek için kayıtlara ve ölçümlere hızlı şekilde bakar ve tekrar piyasaya sunma ihtiyacı duyardım.

Amazon’un sürekli dağıtım faaliyeti yürüttüğünü okudum. Bu nedenle, mülakat sırasında Amazon bünyesinde bir geliştirici olarak dağıtımları yönetmek ve takip etmek için ne kadar zamana ihtiyacım olduğunu öğrenmek istedim. Mülakat görevlisi bana değişikliklerin devamlı dağıtım işlem hatları vasıtasıyla üretim için günde pek çok kez otomatik olarak dağıtıldığını bildirdi. Mülakat görevlisine söz konusu dağıtımları dikkatlice takip etmek ve ben faaliyet gösterdiğim sırada kayıtları ve ölçümleri izlemek için bir gününün ne kadarını harcadığını sorduğumda bana genelde hiç vakit harcamadığını söyledi. İşlem hatları bu işi ekibi için zaten yaptığından dağıtım faaliyetlerinin çoğu aslında aktif olarak kimse tarafından izlenmiyordu. “Vay!” diye tepki verdim. Amazon’a katıldıktan sonra söz konusu otomatik dağıtımların “el değmeden” nasıl yapıldığını göreceğim için çok heyecanlıydım.

Amazon’da güvenli ve sürekli dağıtımlar

O tarihten itibaren Amazon’un hızlı ve güvenli şekilde dağıtım yapmamıza yardımcı olmak için sürekli dağıtım işlem hatlarını nasıl oluşturduğunu ilk elden gördüm. Sürekli dağıtım ve güvenlik uygulamalarımızın geliştiricilerimizi dağıtım konusunda vakit harcamaktan nasıl kurtardığına şahit oldum. Birimimin kaynak kodu deposunun ana şubesine üretim kodunu ilettiğimde genelde bu durumu unutuyor ve bir sonraki işe geçiyorum. Bu esnada ekibimin işlem hattını bu değişikliği üretime yansıtmakla meşgul oluyor. Kod değişikliğimin bir üretim birimine yansıtılması süreci işlem hattı tarafından tamamen otomatik yürütülüyor. Bu da ben ya da başka bir geliştiricinin bir kod unsuruna en son dokunduğu zamanın bu unsurun kaynak kodu deposuna girdiği tarih olduğu anlamına geliyor.
 
Ekibim her bir dağıtım faaliyetini takip etmek zorunda kalmamamız için değişikliklerimizi üretim faaliyetine güvenle dağıtan ve otomatik adımlardan oluşan bir işlem hattı oluşturdu. Bu işlem hattı bir dizi test ve dağıtım güvenlik kontrolleri yoluyla en güncel değişiklikleri hayata geçiriyor. Otomatikleştirilmiş bu adımlar müşterileri etkileyen kusurların üretim aşamasına ulaşmasını engelliyor ve bu kusurlar bu aşamaya ulaşsa bile müşteri üzerindeki olumsuz etkileri yine bu adımlar kısıtlıyor. Bir geliştirici olarak benim açımdan aktif şekilde süreci takip etme gerekliliği olmadan değişikliklerimin üretime dikkatli ve güvenli şekilde yansıtılması noktasında işlem hattı unsuruna güveniyorum.

Sürekli teslimata yolculuk

Amazon hayatına sürekli teslimat yaparak başlamadı. Buradaki geliştiriciler kodlarının üretim aşamasına dağıtılması sürecini yönetmek için saatler, hatta günler harcardı. Yazılımları dağıtma sürecimizi otomatik ve standart hâle getirmek ve değişikliklerin üretim aşamasına ulaşma süresini azaltmak için şirket genelinde sürekli teslimatı kullanmaya başladık. Yayımlama sürecimize yönelik gelişmeler zaman içerisinde kademe kademe çoğalmıştır. Dağıtım risklerini tespit ettik ve işlem hattı unsurları içerisinde yeni güvenlik otomasyonu yoluyla bu riskleri azaltmanın yollarını bulduk. Yeni riskleri ve dağıtım güvenliğini geliştirmenin yeni yollarını tanımlamak suretiyle yayımlama sürecini tekrarlamaya devam ediyoruz. Sürekli teslimata yolculuğumuz ve gelişmeye nasıl devam ettiğimiz hakkında daha fazla bilgi için şu Derleyici Kitaplığı makalesine göz atın: Sürekli teslimat ile daha hızlı ilerleme.

Dört işlem hattı aşaması

Bu makalede Amazon’daki bir işlem hattı vasıtasıyla bir kod değişikliğinin üretime kadar geçtiği aşamalardan bahsedeceğiz. Tipik bir devamlı teslimat işlem hattı dört temel aşamadan oluşmaktadır—kaynak, oluşturma, test ve üretim. Tipik bir AWS hizmetinin her bir işlem hattı aşamasında neler olduğuna dair detaylara inecek ve yine tipik bir AWS hizmeti ekibinin işlem hatlarından birini nasıl oluşturabileceğine dair bir örnek vereceğiz.

Kaynak ve oluşturma

Aşağıdaki diyagram tipik bir AWS hizmeti işlem hatları kapsamında bulabileceğiniz kaynaklar ve oluşturma adımlarına ilişkin genel bir görünüm sunmaktadır.

İşlem hattı kaynakları

Amazon bünyesindeki işlem hatları, yalnızca uygulama koduna yapılan değişiklikleri değil, herhangi bir kaynak değişikliğini güvenli şekilde doğrulamakta ve üretime aktarmaktadır. Bu unsurlar web sitesi statik değerleri, araçları, testleri, altyapısı, yapılandırması ve uygulamanın bağlı olduğu işletim sistemi (OS) gibi kaynaklara değişiklikleri doğrulayarak aktarabilmektedir. Bu değişikliklerin tümü bireysel kaynak kodu depolarında sürüm denetiminden geçmektedir. Kütüphaneleri, programlama dilleri ve AMI ya da ID gibi parametreleri içeren kaynak kodu bağımlılıkları haftada en az bir kere otomatik olarak en güncel sürüme yükseltilmektedir.

Kaynaklar uygulama kodunu dağıtmak için kullandığımız (otomatik geri alma unsurları gibi) güvenlik mekanizmalarını içeren bireysel işlem hatlarında dağıtılmaktadır. Örneğin, çalışma zamanlarında değişebilen (API oran sınırı artışları ve özellik bayrakları gibi) hizmet yapılandırma değerleri, tahsis edilmiş bir yapılandırma işlem hattında otomatik olarak dağıtılmaktadır. Kaynak değişiklikleri hizmet için üretim noktasında herhangi bir hata (yapılandırma dosyasını ayrıştırma hataları gibi) oluşması hâlinde otomatik olarak geri alınmaktadır.

Tipik bir mikro hizmet bir uygulama kodu işlem hattını, bir altyapı işlem hattını, bir işletim sistemi işlem hattını, bir yapılandırma/özellik bayrağı işlem hattını ve bir operatör aracı işlem hattını içerebilmektedir. Aynı mikro hizmet için birden fazla işlem hattına sahip olmak üretim aşamasına değişiklikleri daha hızlı dağıtmamıza yardımcı olmaktadır. Entegrasyon testlerinde sorun yaratan ve uygulama işlem hattını engelleyen uygulama kodu değişiklikleri diğer işlem hattı unsurlarını etkilememektedir. Örneğin, değişiklikler alt yapı kod değişikliklerinin alt yapı işlem hattı kapsamında üretime geçmesini engellemektedir. Aynı mikro hizmete ilişkin tüm işlem hatları birbirine oldukça benzer görünmektedir. Örneğin, bir özellik bayrağı işlem hattı uygulama kodu işlem hattı unsuru ile aynı güvenli dağıtım tekniklerini kullanmaktadır çünkü kötü bir özellik bayrak yapılandırması değişimi kötü bir uygulama kodu değişikliği gibi üretim üzerinde olumsuz bir etki bırakabilir.

Kod incelemesi

Üretime yansıyan tüm değişiklikler bir kod incelemesi ile başlar ve bu değişikliklerin ana şube süreçlerine (bizdeki ana ya da temel) dâhil olmadan önce bir ekip üyesi tarafından onaylanması gerekmektedir. Bu da otomatik olarak işlem hattını başlatmaktadır. İşlem hattı ana şubedeki tüm taahhütlerin o unsura yönelik bir hizmet ekibi üyesi tarafından kod kapsamında incelenmesi ve onaylanması gerektiğine dair gereksinimi pekiştirmektedir. İşlem hattı istenmeyen taahhütlerin dağıtılmasını engelleyecektir.

Tam otomatik işlem hatları ile birlikte kod incelemesi manuel olarak yapılan son inceleme ve üretime geçmeden önce bir mühendis tarafından onay verilen bir kod değişikliği sürecidir. Bu bakımdan, bu süreç çok kritiktir. Kod inceleme görevlileri kodun doğruluğunu değerlendirmekte ve değişikliğin üretime güvenle aktarılıp aktarılamayacağını da incelemektedir. Söz konusu görevliler kodun yeterince teste sahip olup olmadığını (birim testleri, entegrasyon testleri ve canary testleri), kodun dağıtım izleme faaliyeti için yeterli düzeyde düzenlenip düzenlenmediğini ve kodun güvenli şekilde geri alınıp alınamayacağını da değerlendirmektedirler. Bazı ekipler aşağıdaki örnekte olduğu gibi özel bir kontrol listesi kullanmaktadır. Bu liste dağıtım güvenlik hususlarını açıkça kontrol etmek üzere her bir ekip kodu incelemesine otomatik olarak eklenmektedir.

Örnek kod inceleme kontrol listesi

## Testing
[ ] Did you write new unit tests for this change?
[ ] Did you write new integration tests for this change?

Include the test commands you ran locally to test this change:
```
mvn test && mvn verify
```

## Monitoring
[ ] Will this change be covered by our existing monitoring?
 (no new canaries/metrics/dashboards/alarms are required)
[ ] Will this change have no (or positive) effect on resources and/or limits?
 (including CPU, memory, AWS resources, calls to other services)
[ ] Can this change be deployed to Prod without triggering any alarms?

## Rollout
[ ] Can this change be merged immediately into the pipeline upon approval?
[ ] Are all dependent changes already deployed to Prod?
[ ] Can this change be rolled back without any issues after deployment to Prod?

Oluşturma ve birim testleri

Oluşturma aşamasında kod derlenir ve birim testine tabi tutulur. Oluşturma araçları ve mantığı dilden dile ve ekipten ekibe değişebilmektedir. Örneğin, ekipler kendileri için en uygun olan birim testi çerçevelerini, benzer unsurları ve istatistiksel analiz araçlarını seçebilirler. Bununla beraber, ekipler kendi birim test çerçevelerindeki kabul edilebilen minimum kod kapsamı gibi araç yapılandırmasını da seçebilirler. Kullanılan araçlar ve testler de pipeline işlem hattı tarafından dağıtımı yapılan kod türüne bağlı olarak değişecektir. Örneğin, birim testleri uygulama kodu olarak kullanılırken ilişkili diğer uygulamalar kod şablonu olarak altyapı amacıyla kullanılmaktadır. Tüm oluşumlar izolasyona ağ erişimi olmadan çalışmakta ve bu noktada oluşum üretkenliğini teşvik etmektedir. Tipik olarak birim testleri, diğer AWS hizmetleri gibi bağımlılıklara API çağrıları simülasyonu yapmaktadır. Simülasyonu yapılmayan, “gerçek” bağımlılıklara yönelik etkileşimler entegrasyon testleri kapsamında işlem hattı unsurları kapsamında test edilmektedir. Entegrasyon testlerine kıyasla simülasyonu yapılan birim testleri, API çağrılarından dönen beklenmeyen hatalar gibi uç vakalarla ilgilenmekte ve kod içerisinde sorunsuz hata çözümü sağlamaktadır. Oluşum tamamlandığında derlenen kod paketlenir ve imzalanır. 

Üretim öncesi ortamlarda test dağıtımları

Üretime dağıtım aşamasından önce işlem hattı alfa, beta ya da gamma gibi çoklu üretim öncesi ortamlarındaki değişiklikleri dağıtmakta ve doğrulamaktadır. Alfa ve beta, en güncel kodun aktif işlevsel API testleri ve uçtan uca entegrasyon testleri ile beklendiği gibi işlev gösterdiğini doğrulamaktadır. Gamma kodun hem işlevsel olduğunu hem de hem de üretime güvenle aktarılabileceğini doğrulamaktadır. Gamma aynı dağıtım yapılandırması, aynı izleme ve alarmlar ve aynı sürekli canary testi dâhil olmak üzere olabildiğinde üretim sürecine benzer özellikler taşımaktadır. Gamma bölgesel farklılıklardan doğacak herhangi bir potansiyel etkiyi tespit etmek için çoklu AWS Bölgeleri’nde da dağıtılmaktadır. 

Entegrasyon testleri

Entegrasyon testleri, müşterilerin işlem hattı kapsamında yaptığı gibi bizim de otomatik olarak bir hizmet olarak kullanmamıza yardımcı olmaktadır. Bu testler, tüm anlamlı müşteri senaryoları için her bir üretim öncesi aşamada gerçek alt yapı üzerinde çalışan gerçek API’leri çağırmak suretiyle tam yığın ve uçtan uca faaliyetler yürütmektedir. Entegrasyon testinin amacı üretime dağıtım öncesi hizmette beklenmeyen ya da yanlış davranışları tespit etmektir.

Birim testleri simülasyonu yapılan bağımlılıklara yönelik olarak yapılırken entegrasyon testleri gerçek bağımlılıklara yönelik çağrıda bulunan üretim öncesi sisteme yönelik olarak faaliyet göstermektedir ve söz konusu bağımlılıkların davranışlarına yönelik simülasyonlara ilişkin varsayımları doğrulamaktadır. Entegrasyon testleri bireysel API’lerin farklı girdilerdeki davranışlarını doğrulamaktadır. Ek olarak birden çok API unsurunu birleştiren bu testler yeni bir kaynak yaratmak, hazır oluncaya kadar yeni kaynağı tanımlamak ve daha sonra kaynağı kullanmak gibi tam iş akışlarını da doğrulamaktadır.

Entegrasyon testleri bir API’ye geçersiz girdi sağlamak ya da “geçersiz girdi” hatasının beklendiği gibi geri dönüp dönmediğini kontrol etmek gibi olumlu ve olumsuz test vakalarını faaliyete geçirmektedir. Bazı işlem hatları olabildiğince fazla API girdisi oluşturmak için bir test yürütmekte ve bu girdilerin hizmet kapsamında dâhili bir hata oluşturmadıklarını doğrulamaktadır. Bununla beraber, bazı işlem hatları son değişikliklerin gerçek yükleme seviyelerinde herhangi bir gecikmeye ya da ürün gerilemelerine neden olmadıklarından emin olmak için üretim öncesi aşamada kısa bir yükleme testi de yürütmektedir.

Geriye dönük uyumluluk ve yerleşik test

Üretime aktarım faaliyetinden önce en güncel kodun geriye dönük olarak uyumlu olduğundan ve mevcut kodla beraber bu kodun güvenle aktarılabileceğinden emin olmamız gerekmektedir. Örneğin, en güncel kodun mevcut kod tarafından ayrıştırılamayan bir format ile veri yazıp yazmadığından emin olmamız gerekmektedir. Gamma bünyesindeki yerleşik aşama tekli sanal makine ya da tekli container gibi en küçük dağıtım birimine veya AWS Lambda işlev çağırım faaliyetlerin küçük bir yüzdesine en güncel kodu dağıtmaktadır. Bu yerleşik dağıtım faaliyeti geriye kalan gamma çevresinin 30 dakika ya da bir saat gibi bir süre için mevcut kod ile dağıtılmasını sağlamaktadır. Trafiğin yerleşik unsura özel olarak yönlendirilmesine gerek yoktur. Trafik aynı yük dengeleyicisine eklenebilir ya da gamma çevresinin kalanı ile aynı kuyrukta yer alabilir. Örneğin, bir yük dengeleyicisinin arkasında yer alan ve on container’den oluşan bir gamma ortamında, yerleşik unsur sürekli canary testlerinin oluşturduğu gamma trafiğinin yüzde onunu almaktadır. Yerleşik dağıtım faaliyeti, dağıtımdan ya da yan yana dağıtılmış “karmaşık” bir filodan kaynaklanan herhangi bir etkiyi tespit etmek için canary test başarısı oranlarını ve hizmet ölçümlerini görüntülemektedir.

Aşağıdaki diyagram, yeni bir kod yerleşik bir aşamaya dağıtıldıktan sonraki ancak söz konusu kodun henüz gama filosunun gerisine dağıtılmadan önceki gamma ortamının durumunu göstermektedir. 

En güncel kodun bağımlılıklarımızla birlikte geriye dönük olarak uyumlu olduğundan; örneğin bir değişikliğin özel bir sıra ile mikro hizmetlerde yapılmasının gerekip gerekmediğinden emin olmamız gerekmektedir. Üretim öncesi ortamlarda mikro hizmetler diğer bir ekibin sahip olduğu Amazon Simple Storage Service (S3) ya da Amazon DynamoDB gibi herhangi bir hizmetin üretim uç noktasını tipik olarak çağırmaktadır ancak hizmet ekibinin üretim öncesi uç noktasını diğer hizmet ekibinin mikro hizmetleri ile aynı aşamada çağırmaktadır. Örneğin, gamma içerisinde bir ekibe ait mikro hizmet A unsuru, yine gamma içerisinde aynı ekibe ait mikro hizmet B unsurunu çağırmaktadır. Bununla birlikte, Amazon S3’e yönelik üretim uç noktası da çağrılmaktadır.

Bazı işlem hatları, zeta adını verdiğimiz ayrı bir geriye dönük uyumluluk aşamasında da entegrasyon testleri yürütmektedir. Bu aşama her bir mikro hizmetin yalnızca üretim uç noktası çağırdığı ve çoklu mikro hizmetler kapsamında üretime yönelik değişikliklerin üretime dağıtılan kodla uyumlu olup olmadığını test ettiği ayrı bir ortamdır. Örneğin, zeta içerisindeki hizmet A unsuru, mikro hizmet B üretim uç noktasını ve Amazon S3’e yönelik üretim uç noktasını çağırmaktadır.

Geriye dönük uyumluluk değişikliklerini yazmaya ve dağıtmaya yönelik stratejilerin bir tanımı için şu Derleyici Kitaplığı makalesine göz atın: Dağıtım sırasında geri alma güvenliğini sağlama

Üretim dağıtımları

AWS’deki üretim dağıtımları için en birincil hedefimiz, aynı anda birden fazla Bölge’nin ve aynı Bölge’de bulunan birden fazla Erişilebilirlik Alanı’nın olumsuz şekilde etkilenmesini önlemektir. Her bireysel dağıtım kapsamını sınırlandırmak, başarısız üretim dağıtımlarının müşteriler üzerindeki olası etkilerini kısıtlar ve birden çok Erişilebilirlik Alanı veya multi-Bölge etkisini önler. Otomatik dağıtım kapsamını sınırlandırmak için işlem hattının üretim aşamasını birçok aşamaya ve bireysel Bölgelere gönderilmek üzere birçok dağıtıma böldük. Başarısız bir üretim dağıtımının olası etki kapsamını sınırlandırmak için ekipler, bölgesel dağıtımları bireysel Erişilebilirlik Alanlarına veya işlem hatlarında bulunan hizmetlerinin bireysel dâhili parçalarına (hücre olarak adlandırılır) dağıtarak daha az kapsamlı dağıtımlara böldüler.

Kademeli dağıtımlar

Bütün ekipler, daha az kapsamlı dağıtımların güvenliğini değişiklikleri bütün Bölgelerdeki müşterilere ulaştırabileceğimiz bir hızda dengelemelidir. Değişiklikleri 24 Bölgeye ve 76 Erişilebilirlik Alanına işlem hattı aracılığıyla birer birer dağıtmak kapsamlı bir etkiye sebep olmada en düşük riske sahiptir ancak işlem hattının bir değişikliği dünya çapındaki müşterilere ulaştırması haftalar alabilir. Bir önceki örnek üretim işlem hattında da görüldüğü üzere, dağıtımları, giderek büyüyen “dalgalar” şeklinde gruplamanın dağıtım riski ve hızı arasında iyi bir denge kurmamızda bize yardımcı olduğunu tespit ettik. İşlem hattındaki her dalga aşaması, dağıtımları dalgadan dalgaya yükseltilen değişikliklerle beraber bir grup Bölgeye göre düzenler. Yeni değişiklikler her zaman işlem hattının üretim aşamasına girebilir. İlk dalgadaki bir dizi değişiklik ilk basamaktan ikinci basamağa yükseltildikten sonra gammadaki bir sonraki değişiklikler dizisi ilk dalganın ilk basamağına yükseltilir. Böylece üretim için dağıtılmayı bekleyen büyük paketler elde etmeyiz.

İşlem hattındaki ilk iki dalga değişikliğe yönelik en büyük güven duygusunu oluşturur: İlk dalga, yeni değişikliğin ilk üretim dağıtımının olası etkilerini sınırlandırmak için daha az sayıda istekle bir Bölgeye dağıtır. Dalga, değişikliği Bölge üzerinde dikkatli şekilde dağıtmak için o Bölgede tek seferde yalnızca bir Erişilebilirlik Alanı (ya da hücre) dağıtır. Daha sonra ikinci dalga, müşterilerin tüm yeni kod yollarını uygulamalarının oldukça muhtemel olduğu ve bizim de değişikliklerin iyi bir şekilde doğrulanmasını sağladığımız çok sayıda istekle beraber bir Bölgede tek seferde bir Erişilebilirlik Alanı (ya da hücre) dağıtır.

İlk işlem hattı dalgalarının dağıtımındaki değişikliklerin güvenliğine yönelik daha büyük bir güvene sahip olduğumuzda gittikçe daha fazla Bölgeye aynı dalgada paralel şekilde dağıtım sağlayabiliriz. Örneğin, bir önceki örnek üretim işlem hattı üçüncü dalgada üç Bölgeye, dördüncü dalgada 12 Bölgeye kadar, beşinci dalgada ise kalan Bölgelere dağıtım yapar. Bu dalgaların her birindeki Bölgelerin tam sayısı ve seçimi ile bir hizmet ekibinin işlem hattındaki dalgaların sayısı, bireysel hizmet kullanım modellerine ve ölçeğine bağlıdır. İşlem hattındaki daha sonraki dalgalar, aynı Bölgedeki birden fazla Erişilebilirlik Alanının olumsuz şekilde etkilenmesini önleme amacımıza ulaşmada bize yine de yardımcı olur. Bir dalga, paralel şekilde birden fazla Bölgeye dağıtım yaptığında ilk baştaki dalgalarda kullanılan her Bölge için aynı temkinli dağıtım davranışını uygular. Dalgadaki her basamak, dalgada bulunan her Bölgedeki yalnızca tek bir Erişilebilirlik Alanına ya da hücreye dağıtım yapar.

Yerleşik ve aşamalı dağıtımlar

Her bir üretim dalgasına yapılan dağıtımlar yerleşik bir aşamayla başlar. Gamma yerleşik aşamasında olduğu gibi her üretim yerleşik aşaması, her bir dalga Bölgesi veya Erişilebilirlik Alanında bulunan yerleşik unsura (tekli sanal makine, tekli container veya Lambda işlev çağırım faaliyetlerin küçük bir yüzdesine) en güncel kodları dağıtır. Üretim yerleşik dağıtımı, dalgadaki yeni kod tarafından yanıtlanan istekleri en başta sınırlandırarak söz konusu dalgadaki değişiklerin olası etkisini en aza indirir. Genellikle yerleşik unsur, Bölge veya Erişilebilirlik Alanı için geçerli olan tüm isteklerin en fazla yüzde onunu yanıtlar. Değişiklik yerleşik unsuru olumsuz etkilediğinde işlem hattı değişikliği otomatik olarak geri alır ve bu değişikliği üretim aşamalarının geri kalanına yükseltmez.

Yerleşik aşamadan sonra çoğu ekip, dalganın ana üretim filosuna dağıtım yapmak için aşamalı dağıtımları kullanır. Aşamalı dağıtım, hizmetin üretim yükünü dağıtım boyunca sunmak için yeterli kapasiteye sahip olduğundan emin olur. Aynı zamanda, değişikliklerin etkisini sınırlandırmak için yeni kodun hizmete sunulma (bu, üretim trafiği sunmaya başladığı zaman anlamına gelir) oranını kontrol eder. Bir Bölgeye yapılan tipik bir aşamalı dağıtımda o Bölgedeki hizmet kutularının (container’lar, Lambda çağırmaları veya sanal makinelerde çalıştırılan yazılımlar) en fazla yüzde 33’ü yeni kodla değiştirilir.

Bir dağıtım sırasında dağıtım sistemi ilk önce yeni kodla değiştirilecek olan ilk toplu kutunun en fazla yüzde 33’ünü seçer. Değişim sırasında genel kapasitenin en az yüzde 66’sı sağlıklıdır ve istekleri yanıtlar. Tüm hizmetler, Bölgede bir Erişilebilirlik Alanı kaybına dayanacak şekilde ölçeklendirilir, böylece hizmetin üretim yükünü hâlâ bu kapasitede sunabileceğini biliriz. Dağıtımdan sonra sistem, durum denetiminden geçen ilk toplu kutuyu, kalan filoda yeni kodla değiştirilecek olan kutuyu vb. işlemleri belirler. Biz bu sırada isteklere her zaman en az yüzde 66’lık bir kapasiteyle yanıt vermeyi sürdürürüz. Değişiklerin etkisini sınırlandırmak için bazı ekiplerin işlem hatları, kutularının dağıtımını tek seferde yüzde 5’e kadar azaltabilir. Ancak daha sonra sistem, geri alımı hızlandırmak için tek seferde kutuların yüzde 33’ünü bir önceki kodla değiştirdiğinde işlem hatları hızlı geri alım yapar.

Aşağıdaki diyagram, bir üretim ortamının aşamalı geri alım sırasındaki durumunu gösterir. Yeni kod, yerleşik aşamaya ve ilk toplu ana üretim filosuna dağıtılmıştır. Bir başka grup, yük dengeleyiciden kaldırılmış ve değişim için kapatılmıştır.

Ölçümleri izleme ve otomatik geri alım

İşlem hattındaki otomatik geri alımların genellikle üretime yapılan her dağıtımı aktif şekilde izleyen, ölçümleri kontrol eden ve bir sorun gördüğünde manuel olarak geri alım yapan bir geliştiricisi yoktur. Bu dağıtımlar tamamen müdahale gerektirmeden yapılır. Dağıtım sistemi, bir dağıtımı otomatik olarak geri almaya ihtiyacı olup olmadığına kadar vermek için bir alarmı aktif şekilde izler. Bir geri alım, ortamı container görüntüsüne, AWS Lambda işlevi dağıtım paketine veya daha önce dağıtılan dâhili dağıtım paketine geri döndürür. Dâhili dağıtım paketlerimiz, paketler değiştirilemez olduğu ve bütünlüklerini doğrulamak üzere bir sağlama toplamı kullandıkları için container görüntüleriyle benzerdir.

Aşağıdaki örnekte de gösterildiği üzere her bölgedeki her bir mikro hizmet, genellikle, hizmetin müşterilerini etkileyen ölçüm eşiklerini (hatalı ücretler ve yüksek gecikme süresi gibi) ve sistem sağlık ölçümlerini (CPU kullanımı gibi) tetikleyen yüksek önem derecesine sahip bir alarma sahiptir. Yüksek önem derecesine sahip olan bu alarm, nöbetçi mühendise çağrıda bulunmak ve devam eden bir dağıtım olduğunda hizmeti otomatik olarak geri almak için kullanılır. Nöbetçi mühendise çağrıda bulunulduğunda ve nöbetçi mühendis etkileşim kurmaya başladığında geri alımlar, çoğunlukla hali hazırda devam ediyor olur.

Örnek yüksek öneme sahip mikro hizmet alarmı

ALARM("FrontEndApiService_High_Fault_Rate") OR
ALARM("FrontEndApiService_High_P50_Latency") OR
ALARM("FrontEndApiService_High_P90_Latency") OR
ALARM("FrontEndApiService_High_P99_Latency") OR
ALARM("FrontEndApiService_High_Cpu_Usage") OR
ALARM("FrontEndApiService_High_Memory_Usage") OR
ALARM("FrontEndApiService_High_Disk_Usage") OR
ALARM("FrontEndApiService_High_Errors_In_Logs") OR
ALARM("FrontEndApiService_High_Failing_Health_Checks")

Bir dağıtımdan kaynaklanan değişiklikler, aşağı akış ve yukarı akış mikro hizmetleri etkiler. Bu yüzden dağıtım sisteminin, dağıtım altındaki mikro hizmetin yüksek öneme sahip alarmını ve ne zaman geri alım yapacaklarını belirlemek için ekibin diğer mikro hizmetlerinin yüksek öneme sahip alarmlarını görüntülemesi gerekir. Dağıtılmış değişiklikler, sürekli canary testi ölçümlerini de etkiler, bu yüzden dağıtım sisteminin başarısız canary testlerini de ayrıca görüntülemesi gerekir. Bu olası etki alanlarını otomatik olarak geri almak için ekipler dağıtım sisteminin görüntülenmesi amacıyla yüksek öneme sahip toplama alarmları oluşturur. Aşağıdaki örnekte de görüldüğü üzere yüksek öneme sahip toplu alarmlar, bütün ekiplerin bireysel mikro hizmet yüksek öneme sahip alarmlarının ve canary alarmlarının durumunu tek bir toplu duruma dönüştürür. Ekibin mikro hizmetlerinin yüksek öneme sahip alarmlarının herhangi biri alarm durumuna geçtiğinde ekibin o Bölgedeki tüm mikro hizmetlerinde devam eden tüm dağıtımları otomatik olarak geri alınır.

Örnek yüksek öneme sahip toplu geri alım alarmı

ALARM("FrontEndApiService_High_Severity") OR
ALARM("BackendApiService_High_Severity") OR
ALARM("BackendWorkflows_High_Severity") OR
ALARM("Canaries_High_Severity")

Yerleşik bir aşama genel trafiğin küçük bir yüzdesine yanıt verdiği için yerleşik bir dağıtımdan kaynaklanan sorunlar, hizmetin yüksek öneme sahip geri alım alarmını tetiklemeyebilir. Geri kalan üretim aşamalarına ulaşmadan önce yerleşik aşamada soruna sebep olan değişiklikleri yakalamak ve geri almak için yerleşik aşamalar, yalnızca yerleşik unsurla sınırlandırılan ölçümleri ayrıca geri alır. Örneğin, tüm isteklerin küçük bir yüzdesini oluşturan özellikle yerleşik unsur tarafından sunulan hatalı istek ücretlendirmesini geri alırlar. 

Örnek yerleşik geri alma alarmı

ALARM("High_Severity_Aggregate_Rollback_Alarm") OR
ALARM("FrontEndApiService_OneBox_High_Fault_Rate") OR
ALARM("FrontEndApiService_OneBox_High_P50_Latency") OR
ALARM("FrontEndApiService_OneBox_High_P90_Latency") OR
ALARM("FrontEndApiService_OneBox_High_P99_Latency") OR
ALARM("FrontEndApiService_OneBox_High_Cpu_Usage") OR
ALARM("FrontEndApiService_OneBox_High_Memory_Usage") OR
ALARM("FrontEndApiService_OneBox_High_Disk_Usage") OR
ALARM("FrontEndApiService_OneBox_High_Errors_In_Logs") OR
ALARM("FrontEndApiService_OneBox_Failing_Health_Checks")

Hizmet ekibinin tanımladığı alarmların dağıtımına ek olarak dağıtım sistemimiz de dâhili web hizmet çerçevemiz tarafından yayımlanan yaygın ölçümlere binaen herhangi bir anormalliği de otomatik olarak tespit durumu geri eski hâline almaktadır. Mikro hizmetlerimizin çoğu standart bir format ile istek sayısı, istek gecikmesi ve hata sayısı gibi ölçümleri yayımlamaktadır. Bu standart ölçümleri kullanan dağıtım sistemi, dağıtım faaliyeti sırasında ölçümlerde anormallik olması durumunda otomatik olarak durumu geri eski hâline alabilmektedir. Bu durumun örnekleri istek sayısının aniden sıfıra düşmesi ya da gecikme durumu ya da hata sayısı normalin çok üstüne çıktığında görülmektedir.

Pişme süresi

Bazen dağıtımdan kaynaklanan olumsuz bir etki o kadar da ön planda olmamaktadır. Süreç yavaş ilerlemektedir. Diğer bir deyişle, hizmet o esnada yük altında ise dağıtım sırasında bu olumsuz etki hemen ortaya çıkmamaktadır. Dağıtımdan hemen sonra bir sonraki işlem hattı aşamasına değişimi yansıtmak, etki ilk Bölgede kendini gösterinceye kadar birden çok Bölgede etkiler oluşturabilmektedir. Bir sonraki üretim aşamasına bir değişiklik yansıtmadan önce işlem hattı unsurundaki her bir üretim aşamasının pişme süresi vardır. Bu süre dağıtımın tamamlanması ile birlikte bir sonraki aşamaya geçmeden önce yavaş ilerleme etkisine yönelik olarak ekibin yüksek yoğunluklu toplu alarmın işlem hattı unsuru tarafından takip edildiği bir süreçtir.

Dünya genelinde müşterilerimize değişiklikler yansıtırken sahip olduğumuz hızla birlikte çoklu Bölgelere değişiklikler yansıtmak istiyorsak bir dağıtımı pişirmek amacıyla harcanan süreyi hesaplamak için daha büyük etkiyi yaratan riski dengelememiz gerekmektedir. Bu riskleri dengelemeye yönelik uygun yöntemin değişikliğe yönelik güven tarafımızca oluşturulduğu esnada daha uzun pişme süresi için işlem hattındaki dalgaların daha erken oluşmasıyla ve daha sonra daha kısa pişme süresi için sonraki dalgalar ile ilişkili olduğunu gördük. Amacımız çoklu Bölgelere yönelik etki riskini minimize etmektir. Pek çok dağıtım bir ekip üyesi tarafından aktif olarak takip edilmediği sürece, varsayılan tipik işlem hattı pişme süreleri korunumlu yapıdadır ve dört ya da beş iş günü içinde tüm Bölgelere değişiklik aktaracaktır. Daha büyük veya oldukça kritik hizmetlerin pişme süreleri ve işlem hatlarının bir değişikliği küresel çapta dağıtma süreleri çok daha korunumlu bir yapıdadır.

Tipik bir işlem hattı, her dalgadaki bireysel Bölgelerin, Erişilebilirlik Alanlarının ve hücrelerin ek pişme süreleriyle beraber her yerleşik aşama sonrası en az bir saat, ilk bölgesel dalga sonrası en az 12 saat ve kalan bölgesel dalgalarının her birinden sonra en az iki ila dört saat arası bekler. Pişme süresine, yeni kodun tamamen uygulanabilir olmasını mümkün kılan yeteri miktarda istek oluştuğundan emin olmak için ekibin ölçümlerinde belirli sayıda veri noktasını bekleme konusundaki gereksinimler (örneğin, “API oluşturmak için en az 100 istek bekle”) dâhildir. Tüm pişme süresi boyunca, ekibin yüksek öneme sahip toplu alarmı alarm durumuna geçtiğinde dağıtım otomatik olarak geri alınır.

Çok nadir olsa da bazı durumlarda acil bir değişikliğin (bir güvenlik düzeltmesi veya geniş kapsamlı bir etkinliğin hizmet erişebilirliğine olan etkisinin azaltılması gibi) işlem hattının değişiklikleri pişirip dağıtması için genel olarak gereken süreden daha hızlı bir şekilde müşterilere iletilmesi gerekebilir. Bu örneklerde, dağıtımı hızlandırmak için işlem hattının pişme süresini indirebiliriz fakat bunu yapmak için değişimde yüksek seviyede detaylı incelemeye ihtiyaç duyarız. Bu örnekler için kuruluşun Baş Mühendislerinin detaylı incelemelerine ihtiyaç duyarız. Ekip, operasyonel güvenlikte uzman çok deneyimli geliştiriciler ile kod değişiminin yanı sıra aciliyetini ve etki riskini de gözden geçirmelidir. Değişim, yine de işlem hattında her zamanki aynı adımlardan geçer fakat bir sonraki aşamaya daha hızlı yükseltilir. Mevcut soruna değinmek için gerekli yalnızca en minimal kod değişimine izin vererek işlem hattında hareket halinde değişiklikleri sınırlayarak ve dağıtımları aktif olarak izleyerek daha hızlı dağıtım riskini yönetiyoruz.

Alarm ve zaman pencere bloklayıcıları

İşlem hattı, negatif bir etki riskinin daha yüksek olduğu zamanlarda üretime otomatik dağıtımları engeller. İşlem hattı dağıtım riskini değerlendiren bir dizi “bloklayıcı” kullanır. Örneğin, bir sorun etkiyi daha kötü veya daha uzun hale getirebilecek bir ortamda hala devam ederken üretime otomatik olarak yeni bir değişim dağıtmak. Herhangi bir üretim aşamasına yeni bir dağıtım başlatmadan önce işlem hattı, herhangi bir aktif sorun olup olmadığını belirlemek için ekibin yüksek önem dereceli toplama alarmını kontrol eder. Eğer alarm mevcut olarak alarm durumundaysa işlem hattı değişimin ilerlemesini engeller. İşlem hatları ayrıca başka bir ekibin sistemlerinde geniş bir etki olup olmadığını belirten büyük ölçekli olay alarmı gibi kuruluş geneli alarmları kontrol edebilir ve genel etkiye katkıda bulunabilecek yeni dağıtımların başlamasını engeller. Bu dağıtım bloklayıcılar, yüksek önem dereceli bir sorundan kurtarmak için üretime bir değişim dağıtılması gerekiyorsa geliştiriciler tarafından geçersiz kılınabilir.

Ayrıca işlem hattı, bir dağıtımın başlamasına ne zaman izin verildiğini tanımlayan bir dizi zaman penceresi ile yapılandırılmıştır. Zaman pencerelerini yapılandırdığımız zaman dağıtım riskinin iki nedenini dengelememiz gerekir. Bir taraftan çok küçük zaman pencereleri, zaman penceresi kapalıyken değişimlerin işlem hattında birikmesine neden olabilerek bu değişimlerden birinin bir sonraki dağıtımda zaman penceresi açıldığında etki yaratma ihtimalini artırır. Diğer taraftan düzenli iş saatlerinin dışına çıkan çok büyük zaman pencereleri, başarısız bir dağıtımın etkisinin uzun sürmesi riskini artırır. Çalışma saatleri dışında nöbetçi mühendise ulaşmak gün içerisinde nöbetçi mühendis ve diğer ekip üyelerinin çalıştığı zamandan daha uzun sürer. Düzenli iş saatleri sırasında, manuel kurtarma adımlarının gerekli olduğu durumlarda başarısız bir dağıtımdan sonra ekip daha hızlı davranabilir.

Çoğu dağıtım aktif olarak bir ekip üyesi tarafından izlenmez, bu yüzden otomatik bir geri almadan sonra manuel bir eylem gerekmesi durumunda bir nöbetçi mühendise ulaşmak için gereken zamanı minimuma indirmek üzere dağıtım zamanlarını iyileştiririz. Genellikle geceleri, ofis tatillerinde ve hafta sonlarında nöbetçi mühendislere ulaşmak daha uzun sürer bu yüzden bu zamanlar zaman pencerelerinden hariç tutulur. Hizmetin kullanım modellerine bağlı olarak bazı sorunlar dağıtımdan sonra saatler boyunca ortaya çıkmayabilir, ayrıca dağıtımdan sonra gece veya hafta sonu nöbetçi mühendisi arama ihtiyacı riskini azaltmak için birçok ekip Cuma ve öğleden sonra geç saatteki dağıtımları zaman pencerelerinden hariç tutarlar. Bu zaman pencereleri dizisi manuel eylem gerektiği zamanlarda bile hızlı kurtarmayı mümkün kılıyor, düzenli çalışma saatleri dışında nöbetçi mühendisler ile daha az etkileşim yaşanmasını sağlıyor ve zaman pencereleri kapalıyken az sayıda değişimlerin bir araya geldiğinden emin oluyor.

Kod olarak işlem hatları

Sıradan AWS hizmeti ekibi, ekibin birden fazla mikro hizmetlerini ve kaynak türlerini (uygulama kodu, altyapı kodu, işletim sistemi düzeltme ekleri vb.) dağıtması için birçok işlem hatlarına sahiptir. Her işlem hattının giderek artan sayıda Bölgeler ve Erişilebilirlik Alanları için çok sayıda dağıtım aşamaları vardır. Bu, ekibin işlem hattı sisteminde, dağıtım sisteminde ve alarm sisteminde yönetmesi gereken çok sayıda yapılandırma olduğunun ve son en iyi uygulamalar ve yeni Bölgeler ve Erişilebilirlik Alanları ile güncel kalmak için fazla çaba gerektiği anlamına gelir. Son birkaç yılda, yapılandırmayı kodda modelleyerek daha kolay ve sürekli şekilde güvenli, güncel işlem hatları yapılandırmak için bir yol olarak “kod olarak işlem hatları” uygulamasını benimsedik. Dâhili kod olarak işlem hatları aracımız kolayca AWS boyunca yeni Bölgeler ve Erişilebilirlik Bölgeleri eklemek için merkezi bir Bölgeler ve Erişilebilirlik Bölgelerinden çeker. Ayrıca, araç bir üst sınıftaki (her bir dalgada hangi bölgelerin gideceği ve her dalganın pişme süresinin ne kadar süreceği gibi) bir ekibin işlem hatlarında yaygın yapılandırmayı tanımlayarak ve tüm mikro hizmet işlem hattı yapılandırmalarını tüm yaygın yapılandırmaları alan bir alt sınıf olarak tanımlayarak ekiplerin devralma özelliğini kullanarak işlem hattı modellemesine olanak tanır.

Sonuç

Amazon’da dağıtım güvenliğini dağıtım hızına dengelememize yardımcı olan şeye dayanarak zaman içinde otomatik dağıtım uygulamalarımızı oluşturduk. Aynı zamanda geliştiricilerin dağıtımlar konusunda endişelenerek geçirdikleri zamanı minimuma indirmek istiyoruz. Geniş kapsamlı üretim öncesi test, otomatik geri alma ve kademeli üretim dağıtımları kullanarak otomatik dağıtım güvenliği oluşturmak dağıtımların neden olduğu üretim üzerindeki potansiyel etkileri minimuma indirmemize olanak sağlar. Bu da geliştiricilerin aktif olarak üretime yapılan dağıtımları izlemesine ihtiyacı olmadığı anlamına gelir.

Tamamen otomatik işlem hatları ile geliştiriciler kodlarını denetlemek ve ayrıca değişimin üretime gitmeye hazır olduğunu onaylamak için kod incelemelerini kullanır. Değişim, kaynak kod deposu ile birleştirildikten sonra geliştirici bir sonraki göreve geçebilir ve işlem hattının, değişimlerinin üretime güvenli ve dikkatli bir şekilde geçişini sağlayacağına güvenerek dağıtımı düşünmeyi bırakabilir. Otomatik işlem hattı güvenlik ve hızı dengelerken günde birden fazla kez sürekli üretime dağıtımla ilgilenir. Sürekli teslim uygulamamızın kodda modellenmesi ile AWS hizmet ekiplerinin kod değişimlerini otomatik ve güvenli olarak dağıtmak için işlem hatları oluşturması her zamankinden daha kolay.

Daha fazla kaynak

Amazon’un müşteri memnuniyeti ve geliştirici üretkenliğini artırırken aynı zamanda hizmetlerinin güvenliği ve erişilebilirliğini nasıl iyileştirdiği hakkında daha fazla bilgi edinmek için Sürekli teslim ile daha hızlı ilerleme bölümüne göz atın.

Geriye dönük uyumluluk değişikliklerini yazmaya ve dağıtmaya yönelik stratejilerin bir tanımı için şu Derleyici Kitaplığı makalesine göz atın: Dağıtım sırasında geri alma güvenliğini sağlama


Yazar hakkında

Clare Liguori, AWS’de Baş Yazılım Mühendisidir. Kendisi şu sıralar AWS Container Services için geliştirici deneyimlerine odaklanmakta ve container’ler ve yazılım geliştirme yaşam döngüsünün kesişim noktasında şunlar gibi araçlar üretmektedir: yerel geliştirme, kod olarak altyapı, CI/CD, gözlemlenebilirlik ve faaliyetler.