Discovering Istio: Exploring the World of Service Mesh

Emirhan Doğandemir
folksdev
Published in
7 min readMay 13, 2024

Service Mesh Nedir ? Neden Kullanılır ? Istio Componentleri ve Daha Fazlası

Mikroservis mimarisinin hayatımıza getirdiği faydaların yanısıra hayatımıza mimarisel anlamda birçok zorluk getirmiştir. Bu zorluklara örnek verecek olursak ;

  1. Service Discovery
  2. Elasticity
  3. Authentication-Authorization
  4. Resilient Failures
  5. Operations Challenges: logging,monitoring,tracing

Service mesh aslında mimarisel mikroservis problemlerini adreslemek için dizayn edilmiş bir teknolojidir. Bu teknoloji, geliştiricileri birçok mimari probleminden soyutlar. Service mesh bir uygulamadaki birçok veya tüm uygulamalar için sağladığı özellikleri kontrol etmek için bir merkezi nokta oluşturur.

Service mesh komponentleri microservislerden gelen veya giden trafiği yakalar veya onları durdurur, istekleri değiştirir, yeniden yönlendirir veya diğer servislere yeni istekler oluşturur. Sonuç olarak service mesh kod düzeyinde değişiklikler gerektirmeden ek özellikler sunar. Genel olarak service mesh hayatımızda olmadan aşağıdaki şekilde gözükmektedir :

service mesh olmadan mimari

Gelin bir de service mesh hayatımıza girdikten sonrasındaki oluşan görüntüye bakalım :

service mesh ile olan görüntü

İstio Yapısı ve Core componentleri nelerdir ?

Kubernetes üzerinde kurulu bir istio playgroundu.

İstio service mesh mantıksal olarak data plane ve control plane olmak üzere ikiye ayrılır. Genel olarak kurulu olan Istıo service mesh mimari görünümü aşağıdaki gibidir.

Istıo Architecture

Data Plane

Data Plane kısmı; Envoy proxy listesi ve her Envoy proxysinde çalışan istio-agent bileşeninden oluşur. Istio, Envoy proxy’nin genişletişmiş bir versiyonunu kullanır. Burada terminolojik olarak data planeda sidecar container, proxy, Envoy proxy aynı anlama gelmektedir. Bu kısımda aslında service mesh yapısal anlamda işleyişini gerçekleştirir. Örnek verecek olursak; service discovery, health checks, traffic shaping and routing, security, metrics telemetry bu kısımda gerçekleşir.

Data Plane

Control Plane

Control plane, service mesh için konfigurasyon ve policyleri yönetir. Control plane doğrudan mesh içerisindeki trafik ile alakalı bir işlemde bulunmaz.İstio gibi bir service mesh sisteminde, Control Plane, ağdaki tüm Envoy proxy’lerini yönetmekten sorumludur.

İstiod, diğer Istio bileşenleri ile iletişim kurar ve bu bileşenler arasında yapılandırma ve politika bilgilerini paylaşır. İstiod’un doğrudan yönetiminde oluşturulan ve çalışan diğer bileşenler arasında Pilot (trafik yönlendirme), Citadel (güvenlik), Galley (konfigürasyon yönetimi) ve Telemetry (izleme) gibi bileşenler bulunur.

İstio Service Mesh Kullanımı

İstio service mesh ile çalışmadan önce 3 tane öğrenmemiz gereken Custom Resource Definition (CRD) bulunmaktadır.

  1. DestinationRule
  2. Virtual Service
  3. Gateway ( Bu yazıda gateway kısmına değinmeyeceğiz)

Destination

Destination rules, belirli bir hedefe ulaşmak için kullanılan trafik kurallarını tanımlar. Bu kurallar, hedef servisin belirli bir sürümüne yönlendirme yapma, trafik ağırlığını belirleme, trafik ayarlarını yapılandırma gibi işlevleri içerebilir

Bir örnek verecek olursak kubernetes clusterımızda aşağıdaki komut çıktısından podlarımızın ve servicelerimiz ile ilgili detayları görebiliriz.

Pod ve service çıktısı
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: notification
spec:
host: notification-service (1)
subsets: (2)
- name: v1 (3)
labels:
version: v1 (4)
- name: v2
labels:
version: v2
  1. Host : destinationRule’un uygulanacağı service adını belirtir. Burada notification-service adlı servise yönlendirme sağlanır.
  2. Subsets : Bu hedefteki servisin alt kümelerini tanımlar. Subsetler, farklı sürümleri, bölümleri veya diğer özellikleri temsil eder.
  3. Name : Subsetlerin adını belirtir. Bu örnekte v1 ve v2 adında iki subset bulunmaktadır.
  4. Labels : Subsetleri tanımlamak için kullanılan etiketlerdir. Burada, subsetler sürüm numaralarını etiket olarak kullanır. Örneğin, v1 alt kümesi version: v1 etiketine sahiptir.

Virtual Service

Virtual Service, bir servisin belirli özelliklerini tanımlayan ve istemcilerin bu servisle iletişim kurmasını sağlıyan bir ögedir.

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: notification
spec:
hosts:
- notification-service (1)
http: (2)
- route: (3)
- destination:
host: notification-service (4)
subset: v1 (5)
  1. Hosts : VirtualService’in yönlendireleceği servis adını belirtir. Bu örnekte notification-service isminde bir servis kullanılıyor.
  2. Http: Bu bölüm http trafiği için yönlendirme kurallarını belirtir.
  3. Route : belirli bir service’ e gelen trafiğin yönlendirme kurallarını içerir.
örnek bir virtual service ve destinatinrule akışı

Ne yaptık ?

Kubernetes clusterımızda podlar ve serviceler vardı burada bu podları label bilgilerine göre subsetlere ayırdık ve hangi servis bilgisiyle olduğunu destinationrule ile tanımladık. Bir adet virtualService oluşturduk ve burada notification-service’e gelen http trafiğini yönlendirme sağladık. Burada yönlendirme sağladığımız aslında kendi servisimiz burada sadece subset v1'i verdik v2'ye dair herhangi bir şey yok yani bu durumda dışarıdan notification servisine gelen tüm istekler v1 poduna gidecektir. Request Routing olarak adlandırılan kısma örnek olarak verilebilir. Peki kontrol edersek tester podumuzdan notification-service’ine request attığımızda tüm isteklerin sadece belli bir çıktıda olduğunu görüyoruz.

request yönlendirme

Fault Injection

Belirli hata senaryolarını zorlayarak sistem davranışını test etmek için kullanılan bir test tekniktir. İstio gibi bir hizmet mesh kullanarak bu tür hataları enjekte etmek, hizmetler arasındaki güvenilirliği artırmak ve sistemlerin beklenmedik hata durumlarına nasıl tepki vereceğini anlamak için önemlidir. İki türü vardır ; Delay Injection ve Abort Injection.

Delay Injection

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: example-vs
spec:
hosts:
- example-svc
http:
- route:
- destination:
host: example-svc
subset: v1
fault:
delay:
percentage:
value: 10.0
fixedDelay: 400ms

Bu servise gelen isteklerin %10'unun 400 milisaniye sabit bir gecikmeyle (delay) işlenmesi için hata enjeksiyonu yapılandırması yapılmıştır. Mesela iki servisiniz arasında 500 ms’lik bir gecikme sonrasında timeouta düşme case’i var bunu test etmek için kullanabilirsiniz.

Abort Injection

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: example-vs
spec:
hosts:
- example-svc
http:
- route:
- destination:
host: example-svc
subset: v1
fault:
abort:
percentage:
value: 20.0
httpStatus: 400

Abort belirli bir yüzdeyle gelen isteklerin belirli bir HTTP koduyla iptal edilmesini sağlar. Bu durumda gelen %20 istek 400 Bad Request koduyla iptal edicektir. Örneğin, belirli bir oranda gelen isteklerin iptal edilmesi durumunda, servisinizin performansının nasıl etkilendiğini ve diğer isteklere nasıl yanıt verdiğini gözlemleyebilirsiniz.

Traffic Shifting

Bir servisin birden fazla sürümünü veya farklı hedeflere sahip subsetleri yönetmek için kullanılan bir tekniktir. Burada mesela bir uygulamamızın v1 versiyonu bulunmakta son eklenen featurelar ile v2 versiyonu hazır bunu test edeceğim.

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 80
- destination:
host: reviews
subset: v2
weight: 20

Burada weight kullanımları ile review servisine gelen isteklerin yalnızca %20'sinin v2 poduna gitmesini sağlarız.

Mirroring

Mirroring, bir servise gelen isteklerin aynısının, gerçek işleme tabi tutulmadan önce başka bir hedefe kopyalanmasıdır. Bu işlem, asıl işlem sırasında gerçekleşen işlemleri etkilemeden, farklı bir hedefte isteklerin aynısının işlenmesini sağlar. Güvenlik kontrolleri,performans ve hata analizi,yedekleme ve kurtarma görevlerinde kullanılır

 apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: my_virtual_service
spec:
hosts:
- target_host
http:
- route:
- destination:
host: old_service_name
subset: old_subset
mirror:
host: new_service_name
subset: new_subset
mirror_percent: 10

Yukarıdaki örnekte old_service_name’e gelen gerçek isteklerin aynısının %10 new_service_name’ e yönlendirelecektir.

Resilience Nedir ?

Mikroservis mimarisi içinde yer alan hizmetlerin, sistemdeki hatalara, arızalara ve değişkenlere karşı dayanıklı olma yeteneğini ifade eder. Dayanıklılık, bir hizmetin beklenmedik koşullar altında dahi işlevselliğini sürdürme yeteneği olarak tanımlanabilir.

Farklı resilience strategyleri vardır:

  • Load Balancing
  • Time-outs
  • Retries
  • Circuit Breakers

Circuit Breaker

Circuit Breakerdaki ana amaç isteklere gereken şekilde veya hiç cevap veremeyen bir servise ısrarla istek atmaktan vazgeçip bir süre boyunca servisin rahatlamasına izin vermek.

Circuit Breaker Akışı
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
...
spec:
host: httpbin
trafficPolicy:
connectionPool:
http:
http1MaxPendingRequests: 15 (1)
maxRequestsPerConnection: 1 (2)
maxRetries: 3 (3)
outlierDetection:
baseEjectionTime: 15sn (4)
consecutiveErrors: 5 (5)
interval: 5s (6)
maxEjectionPercent: 50 (7)
  1. Cevap bekleyen request sayısını belirtir fazla requestler reddedilir.
  2. Bir connection ile servise yapılacak maksimum request sayısını belirtir.
  3. Bir isteğin en fazla kaç kez deneneceği
  4. Bir pod trafikten çıkarıldığında buradaki süre kadar trafiğe kapalı kalır.
  5. Circuit Breaker açılması için gerekli olan artarda hata sayısı
  6. Anomali tespit kontrolü ( Her şeyin yolunda olup olmadığını ne kadar zamanda bir kontrol edeceğimizi belirtir )
  7. Servisi üzerinde çalıştığı podların en fazla yüzde kaçında circuit breakerin aktif olacağı

Retry Pattern

Retry, geçici ve kısa süreli iletişim hatalarını azaltmaya odaklanan bir davranışsal tasarım desenidir. Geçici hataların yayılmasını önlemeyi amaçlar.

Ağ hataları, Hedef servis hataları, zaman aşımı gibi sorunlarda aynı parametrelerle tekrarlanan bir isteğin hala başarılı olacabileceğini varsayar.

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: notification-vs
spec:
hosts:
- notification
http:
- route:
- destination:
host: notification
port:
number: 8080
retries:
attempts: 10 (1)
perTryTimeout: 2s (2)
retryOn: 5xx,gateway-error,connect-failure,refused-stream (3)
  1. Yeniden deneme sayısını belirtir
  2. Herbir yeniden deneme için maksimum süreyi belirtir
  3. Yeniden denemenin ne tür hata kodları veya durumları için yapılacağını belirtir

Request Timeout

Bazı durumlarda, bir servisin işlemi tamamlaması beklenenden daha uzun sürebilir veya servis yanıt vermeden kalabilir. Bu gibi durumlarda, belirli bir zaman dilimi içinde bir yanıt alınamadığında, istemcinin beklemesi gereken maksimum süreyi belirlemek önemlidir. Bu, hizmetler arasındaki iletişimin güvenilirliğini artırır ve hizmetlerin hata durumlarında daha etkin bir şekilde tepki vermesini sağlar. Aşağıdaki örnekte isteğin 0.5 saniye (500 milisaniye) içinde yanıt alması beklenmektedir. Eğer bu süre içinde yanıt alınamazsa, istek zaman aşımına uğrayacaktır.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v2
timeout: 0.5s

Tüm bu süreçlerin Istio kullanarak nasıl yapıldığını öğrenmek için bu linke tıklamanız yeterli.

Faydalandığım Kaynaklar:

Sonuna kadar okuduğunuz için teşekkür ederiz. Gitmeden önce:

Lütfen yazıyı alkışlamayı ve beni takip etmeyi unutmayın! 👏
Beni takip etmek isterseniz LinkedIn | Github

--

--

Emirhan Doğandemir
folksdev

DevOps & Platform Engineer #Kubernetes #CI/CD #GitOps #Automation #DevSecOps