Dapr’ı Kubernetes İle Anlama: Service, Ingress ve Zipkin ile Kusursuz Deneyim

Bir önceki yazımda Dapr’ ın Kubernetes ortamına kurulumunu yaptık ve microservislerimize ait deployment hizmetlerini Kubernetes ortamına dağıttık. Bu microservislerin temel amacı şimdiki Dapr’ı kullanarak birbirleri ile iletişim sağlamaktı. Bu iletişimin oluşmasını sağlayıp Zipkin ile microservisler arasındaki bağımlılığı görüntülemekistiyorum.

İletişim başlaması için öncelikle Aggragation olarak tasarladığım microservisimde UpdateBasketAsync isimli endpointi tetiklemem gerekiyor. Peki Kubernetes içinde çalışan bu uygulamaya nasıl ulaşırım. Bunun çeşitli yöntemleri var. Birçoğu anlık test için yapılabilecek geçici çözümler olmak ile birlikte bazıları da mimariye göre değişiklik gösterebilir. Bu yöntemleri şu şekilde özetleyebiliriz.

  1. Pod Port Forward
  2. Service Port Forward
  3. Service type NodePort tanımlamak
  4. Service type LoadBalancer tanımlamak
  5. Ingress kullanarak servise ulaşmak

Pod, Service ve Ingress kavramlarını Kubernetes ile ilgili bir yazı serisinde anlatmayı planlıyorum. Bilmeyeneler için linklerini bıraktım. Ayrıca mimarideki yerlerini de bir çizimde göstermek istiyorum.

Yukarıda bahsettiğim yöntemlerden birisi olan Ingress ile yolumuza devam edeceğiz. Biz yukarıda gördüğünüz mimaride Deployment ve Pod’ları bir önceki makalede oluşturduk. Şimdi sıra Deployment önünde duran Service oluşturmak. Bizim “aggregator-deployment” ve “basketapi-deployment” isimli iki adet Deployment hizmetimiz olduğu için herbirizi için bir tane Service hizmeti oluşturacağız.

İlk önce “aggregator-deployment” ait service oluşturalım. Peki Kubernetes bu Service hizmetinin aggregator-deployment ait olduğunu nasıl anlıyor? İşte aşağıda paylaştığım Service configurasyonunda “selector” dediğimiz bir kavram ile yapıyor.

apiVersion: v1
kind: Service
metadata:
  name: aggregator-svc
  namespace: daprdotnetjourney
  labels:
    app: aggregator
    service: aggregator
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    service: aggregator

Şimdide “basketapi-deployment” ait service oluşturalım.

apiVersion: v1
kind: Service
metadata:
  name: basket-svc
  namespace: daprdotnetjourney
  labels:
    app: basketapi
    service: basketapi
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    service: basketapi

Service’ de bulunan port, targetPort gibi kavramlar önemli. İstek Ingress’ten geçer ve Service port’ta ulaşır. Service aldığı isteği arkasında duran podların “targetPort” olarak isimlendirdiğimiz containerın açık olan portuna ulaştırır.

Şimdi yukarıda oluşturduğumuz Service’ leri Kubernetes Cluster’ına dağıtalım.

kubectl apply -f aggregator-service.yaml
kubectl apply -f basketapi-service.yaml

Şimdi sıra Service’in de önünde duran Ingress kurulumlarında. Ingress, Kubernetes clusterına dışarıdan gelen istekleri karşılar ve Service hizmetin yönlendirir. Bu işlemi nasıl yaptığı ile ilgili dökümantasyon linkini bıraktım. Bu işlemden hemen önce nginx-ingress clustera yüklememiz gerekecek.

Helm Chart komutlarını aşağıya bırakıyorum.

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm upgrade --install ingress-nginx ingress-nginx --namespace ingress-nginx --create-namespace

Ingress-nginx yüklediysek sırada aşağıdaki yaml var.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: daprdotnetjourney-ingress
  namespace: daprdotnetjourney
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  ingressClassName: nginx
  rules:
  - host: basket.daprdotnetjourney.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: basket-svc
            port:
              number: 80
  - host: aggregator.daprdotnetjourney.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: aggregator-svc
            port:
              number: 80

Yukarıda ki Ingress yapılandırmasını aşağıdaki komut ile çalıştırın.

kubectl apply -f ingress.yaml

Herşey yolunda gittiyse Lens’ te Ingress aşağıdaki gibi görünür.

Yukarıdaki daprdotnetjourney-ingress isimli Ingress’te tanımladığımız “host” adresleri görüldüğü üzere “Rules” altında listelenmiş. Ayrıca “LoadBalancers” altında da hangi IP den yayın yaptıklarıda gösterilmiş. Biz Docker-Dosktop ile gelen Kubernete kullandığımız için “localhost” olarak tanımlı.

Tamda bu sebeble bu host adreslerine ulaşabilmemiz için “Host” dosyamıza aşağıdaki gibi kayıt oluşturmamız gerekecek.

Bu kayıt işleminide yaptıktan sonra artık Kubernetes’te çalışan podlarımaza ulaşabiliriz.

Artık swaggerda gördüğümüz “/api/v1/Basket/” adresine istek atabiliriz. Bu endpointe istek attığımızda Dapr tarafında neler olur biraz konuşalım.

Aşağıdaki kod çalışacak.

Bu komut setinde,

var httpClient = DaprClient.CreateInvokeHttpClient("basket-api");

komutu ile Id‘ si “basket-api” olan Dapr Sidecar poduna istek atmak istiyor. Peki basket apisinin Dapr Sidecar’ına ben bu Id’ yi nasıl veriyorum. basketapi-deployment.yaml dosyasına baktığınızda orada Dapr için oluşturulan “annotations” ları göreceksiniz. Bu Annotations’larda “dapr.io/app-id” bu Sidecar’ın benzenrsiz Id’ sidir. Aşağıdaki gibi,

Artık sırada yukarıda swagger görüntüsünü paylaştığım endpointe request atmak. Eğer başarılı bir şekilde Aggregator microservisinden Basket mikroservisine ulaşırsak, sırada bu iletişimi monitoring edecek Zipkin var.

Sepete 3 tane ürün gönderiyorum. Çıktısı şu şekilde,

Bu requesti Basket apisinde işleyen kod parçacığı şu şekilde.

namespace DaprDotNetJourney.Microservices.Basket.Application.Services
{
    public class BasketService : IBasketService
    {
        public async Task<Result<BasketDto>> UpdateBasketAsync(BasketDto basket)
        {
            basket.Items.ForEach(x => Console.WriteLine(x.ProductId+" ===== "+ x.ProductName + " ===== " + x.UnitPrice));

            return new SuccessResult<BasketDto>(basket)
            {
                Messages = new List<string>
                {
                    $"{basket.Items.Count} sayıda ürün sepete kaydedildi"
                }
            };
        }
    }
}

Basket apisinin Kubernetes’ te çalışan Container’ın consolune düşen logta şu şekilde,

Tüm bu süreçten anlaşılan biz Dapr Sidecar’ları kullanarak micreservisler arasında “Service Invocation” yöntemi ile iletişim sağladık. Şimdi bu iletişimi Zipkin ile görüntüleyelim. Önce Zipkin yüklememiz gerekir. Zipkin’ i zaten hali hazırda Dapr’ın da yüklü olduğu “dapr-system” namespacesine yüklemeyi tercih ediyorum.

kubectl create deployment zipkin --image openzipkin/zipkin -n dapr-system

Zipkin deployment oluşturduktan sonra daha öncede yaptığımız gibi bu deployment için bir Service hizmeti oluşturmak. Amacımız bu Service ile deploymenta ulaşmak. Biz daha önce Service’yi bir yaml hazırlayarak oluşturmuştuk. Aşağıdaki örnekte yaml gerek kalmadan komut ile oluşturma öreneğidir.

kubectl -n dapr-system expose deployment zipkin --type ClusterIP --port 9411

Daha sonra size bu projenin kodlarını paylaşacağım. Dapr/Configuration klasörü altında config.yaml göreceksiniz. Bunu aşağıdaki gibi güncelleyeceğim.

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: config
  namespace: daprdotnetjourney
spec:
  tracing:
    samplingRate: "1"
    zipkin:
      endpointAddress: "http://zipkin.dapr-system.svc.cluster.local:9411/api/v2/spans"

Bu Dapr Configuration’u aşağıdaki komut ile Kubernetes’ te çalıştıralım.

kubectl apply -f config.yaml

Şimdi yapacağımız şey Zipkin’e dışarıdan ulaşabilmek için Ingress hazırlamak. Aşağıdaki Ingress bu maksatla hazırlanmıştır.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: zipkin-ingress
  namespace: dapr-system
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  ingressClassName: nginx
  rules:
  - host: zipkin.daprdotnetjourney.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: zipkin
            port:
              number: 9411

Aşağıdaki komut ile çalıştırabilirsiniz.

kubectl apply -f .\zipkin-ingress.yaml

Şimdi yapmamız gerek şey aşağıdaki gibi host dosyamıza “zipkin.daprdotnetjourney.com” kaydetmek.

Artık Zipkin için tanımladığımız host adresine gidersek aşağıdaki görüntüleri elde ederiz.

Zipkin’ de bu akışları göremediyseniz öncelikle Deployment’ları aşağıdaki komutlar ile restart edin ve Aggregator Api’den Basket Api’ sine birkaç istek gönderin.

kubectl rollout restart deployment/aggregator-deployment -n daprdotnetjourney
kubectl rollout restart deployment/basketapi-deployment -n daprdotnetjourney

Makalemizin sonuna geldik. Bu işlemlerin bir miktar Kubernetes bilgisi gerektirdiğinin farkındayım. Şahsi kaanatim Kubernetes gibi bir teknolojinin biz Developer’ lar tarafından zaten belirli bir seviyede bilinmesi gerektiği. Sonraki konum Dapr ile Pub-Sub mekanizmalarının nasıl çalıştığı ile ilgili olacak.

Görüşmek üzere.

Proje Github Linki

İnternet sitesi http://cahityusuf.com
Yazı oluşturuldu 6

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Benzer yazılar

Aramak istediğinizi üstte yazmaya başlayın ve aramak için enter tuşuna basın. İptal için ESC tuşuna basın.

Üste dön