Sepet Modeli: Kodu Değiştirmeden Mikro Hizmetleri Genişletme
Modern bulut tabanlı sistemlerde mikro hizmetlerin iş mantığını çalıştırmaktan çok daha fazlasını yapması beklenir. Günlüğe kaydetmeyi yönetmeli, SSL/TLS sertifikalarını yönetmeli, ölçümleri toplamalı, yeniden deneme mekanizmalarını uygulamalı ve diğer hizmetlerle güvenli iletişimi koordine etmelidirler.
Tüm bu kesişen işlevleri doğrudan her uygulamanın kod tabanına yerleştirirsek, kod şişkinliği, sıkı bağlantı ve dil kilitlenmesiyle sonuçlanırız.
Sidecar Pattern tam da bu noktada devreye giriyor. Bu kılavuzda Sidecar modelinin ne olduğunu, modern mikro hizmet mimarileri için neden önemli olduğunu ve basit benzetmeler ve Kubernetes yapılandırma örneklerini kullanarak nasıl çalıştığını açıklayacağız.
Gerçek Dünya Analojisi: Motosiklet Sepeti
Bu modeli anlamanın en kolay yolu sepetli bir motosiklet düşünmektir.
Yüksek performanslı bir motosikletiniz olduğunu hayal edin. Tek bir şeyi son derece iyi yapmak için tasarlandı: Bir sürücüyü hızlı bir şekilde taşımak. Şimdi yolcu bagajı taşımanız veya ekstra koltuk eklemeniz gerektiğini varsayalım.
Motosikletin şasisini, motorunu ve tekerleklerini tamamen yeniden tasarlayarak onu bir arabaya dönüştürebilirsiniz. Ancak bu çok büyük bir çaba gerektirir, bisikletin sadeliğini bozar ve bakımını zorlaştırır.
Bunun yerine bir sepet eklersiniz.
Sepet, motosiklete bağlanan ayrı, bağımsız bir ünitedir. Motosikletin yolculuğunu paylaşır, motosiklet nereye giderse oraya gider ve yakın işbirliği içinde çalışır. Ancak motosikletin çekirdek motoruna dokunulmuyor.
Yazılım mimarisinde:
- Motosiklet birincil uygulama kapsayıcınızdır (ödeme veya kullanıcı kimlik doğrulaması gibi temel iş mantığınızı çalıştırır).
- Sidecar ayrı bir yardımcı kapsayıcıdır (SSL sonlandırma, izleme veya günlük gönderimi gibi yardımcı program görevlerini yürütür).
- Yolculuk dağıtımın yaşam döngüsüdür (ör. Kubernetes Pod).
Sorun: Kesişen Endişeler ve Kod Şişkinliği
Sepetlerden önce, geliştiricilerin yardımcı kitaplıkları doğrudan uygulama kodlarına dahil etmeleri gerekiyordu. Örneğin, günlükleri merkezi bir sunucuya göndermek istiyorsanız, bir günlük kütüphanesini içe aktardınız. Metriklere ihtiyacınız varsa bir metrik SDK’sı eklediniz.
Bu kütüphane tabanlı yaklaşım birçok önemli zorluk yarattı:
- Dil Kilitlenmesi: Bir izleme kitaplığı yalnızca Go’da yazılmışsa, bunu bir Python veya Java mikro hizmetinde kolayca kullanamazsınız. Yığınınızdaki her dil için bir kütüphane bulmanız veya oluşturmanız gerekir.
- Kod Kirliliği: İş mantığı, yeniden denemeler, hizmet keşfi, şifreleme ve günlüğe kaydetme için altyapıya özel kodlarla karmaşık hale gelir.
- Karmaşık Yükseltmeler: İletişim kitaplığında bir güvenlik açığı bulunursa, her bir mikro hizmetin bağımlılığını güncellemesi, yeniden derlemesi ve yeniden dağıtması gerekir.
- Kaynak Çatışması: Yardımcı kod, ana uygulamayla aynı çalışma zamanı sürecinde çalışır; bu, günlükçüdeki bir bellek sızıntısının tüm çekirdek uygulamanızı çökertebileceği anlamına gelir.
Çözüm: Sepet Deseni
Sidecar Pattern, yardımcı görevleri ana uygulama sürecinin dışına taşıyıp uygulamanın hemen yanında çalışan ayrı, bağımsız bir sürece yerleştirerek bu sorunları çözer.
Kubernetes gibi konteynerli ortamlarda, uygulama konteyneri ve sepet konteyneri aynı Pod içinde çalışır. Çünkü aynı Pod’u paylaşıyorlar:
- Aynı Ağ Ad Alanı: Aynı IP adresini ve ağ bağlantı noktalarını paylaşırlar. Neredeyse sıfır gecikmeyle
localhostüzerinden birbirleriyle anında konuşabilirler. - Paylaşılan Depolama Birimleri: Tam olarak aynı disk depolama birimine erişebilirler, bu da sepetin günlük dosyalarını okumasına veya ana uygulama tarafından yazılan yapılandırma dosyalarını yüklemesine olanak tanır.
- Özdeş Yaşam Döngüsü: Sepet, birincil uygulamayla birlikte dağıtılır, başlatılır, durdurulur ve ölçeklendirilir.
Sepet Deseninin Temel Kullanım Durumları
Sepetler inanılmaz derecede çok yönlüdür. En yaygın uygulamalardan bazıları şunlardır:
1. Hizmet Ağı Proxy’si (ör. Envoy, Linkerd)
Uygulamanız diğer hizmetlere doğrudan HTTP çağrıları yapmak yerine, yerel sepet proxy’sine istek gönderir. Yardımcı proxy, yönlendirmeyi, yeniden denemeleri, yük dengelemeyi, devre kesmeyi ve karşılıklı TLS (mTLS) şifrelemeyi yönetir ve ardından isteği iletir. Uygulama bu ağ karmaşıklıklarından tamamen habersizdir.
2. Günlük Toplama ve İletme (ör. Fluent Bit)
Uygulamanız basitçe günlük ifadelerini standart çıktıya veya yerel bir günlük dosyasına yazar. Bir sepet konteyneri bu dosyayı izler, günlükleri ayrıştırır ve bunları Elasticsearch veya Datadog gibi merkezi bir analiz motoruna iletir.
3. Yapılandırma ve Gizli Yeniden Yükleme
Bir sepet, yapılandırma güncellemeleri veya kriptografik anahtar rotasyonları için uzaktaki bir sunucuyu (Consul veya Vault gibi) izleyebilir. Bir değişiklik algılandığında, yeni dosyaları paylaşılan bir birime indirir ve yeniden başlatmaya gerek kalmadan ana uygulamaya bunları yeniden yüklemesi için sinyal gönderir.
Kubernetes Uygulama Örneği
Kubernetes’te bir sepet ayarlamak basittir. Burada, paylaşılan bir birime günlük yazan bir uygulama kapsayıcısını ve bu günlükleri okuyup gönderen bir Fluent Bit sepet kapsayıcısını gösteren basit bir YAML yapılandırması verilmiştir:
apiVersion: v1
kind: Pod
metadata:
name: app-with-logging-sidecar
labels:
app: billing-service
spec:
containers:
# 1. Primary Application Container
- name: web-app
image: node:18-alpine
command: ["/bin/sh", "-c"]
args:
- >
while true; do
echo "$(date) [INFO] Transaction processed successfully" >> /var/log/app/output.log;
sleep 5;
done
volumeMounts:
- name: shared-logs
mountPath: /var/log/app
# 2. Sidecar Container (Log Shipper)
- name: log-shipper
image: fluent/fluent-bit:latest
volumeMounts:
- name: shared-logs
mountPath: /var/log/app
# In a real setup, Fluent Bit config would read /var/log/app/output.log
# and forward it to an external logging system.
# Shared disk storage accessible by both containers
volumes:
- name: shared-logs
emptyDir: {}
Sepet Deseninin Artıları ve Eksileri
Herhangi bir tasarım modeli gibi, sepetler de bazı ödünleşimlerle birlikte gelir:
| Avantajı (Pro) | Dezavantajı (Con) |
|---|---|
| Dilden Bağımsız: Sepet kendi ortamında çalışır. Aynı sepet yardımcısını Go, Java, Python veya Ruby uygulamalarının yanında kullanabilirsiniz. | Kaynak Ek Yükü: Kapsül başına birden fazla kapsayıcının çalıştırılması CPU ve bellek tüketimini artırır. |
| Ayrılmış Yaşam Döngüsü: Altyapı ekipleri, uygulama koduna dokunmadan sepetin güvenlik yamalarını güncelleyebilir. | Artırılmış Karmaşıklık: İki kat daha fazla kapsayıcıyı yönetmek, dağıtım yapılandırmalarını, hata ayıklamayı ve planlamayı karmaşık hale getirir. |
| Bağımsız Arıza Yalıtımı: Sepet konteynerinin çökmesi durumunda Kubernetes, ana uygulamayı kapatmadan konteyneri otomatik olarak yeniden başlatabilir. | Hafif Ağ Gecikmesi: Yerel bir proxy sepeti üzerinden trafik yönlendirmesi, genellikle ihmal edilebilir olsa da, küçük bir atlama ekler (< 1ms). |
Çözüm
Sidecar Pattern, modern bulut tabanlı mimarilerin temel yapı taşıdır. Ağ proxy’si, güvenlik, günlük kaydı ve yapılandırma yönetimi gibi kesişen konuları ayrı bir tamamlayıcı süreçte izole ederek, geliştiricilerin yalnızca iş değeri oluşturmaya odaklanmasına olanak tanır.
Ekstra kaynak yükü getirse ve etkili bir şekilde yönetilebilmesi için Kubernetes gibi konteyner düzenleme platformlarına ihtiyaç duysa da, daha temiz kod tabanları, dil esnekliği ve bağımsız ölçeklendirmenin faydaları, onu kurumsal mikro hizmetler için vazgeçilmez bir model haline getiriyor.
Ghaznix Blogunda daha fazla yazılım geliştirme ve arka uç mühendisliği öngörülerini keşfedin →