Mikroservisler etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Mikroservisler etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

7 Aralık 2025 Pazar

Kubernetes’te Horizontal Pod Autoscaler (HPA) ile Otomatik Ölçeklendirme: Adım Adım Kurulum ve İpuçları

Giriş

Kubernetes üzerinde çalışan uygulamalarınızın trafiğe göre otomatik ölçeklenmesi, maliyet ve performans dengesini korumak için kritik öneme sahiptir. Horizontal Pod Autoscaler (HPA), pod sayısını metriklere göre dinamik olarak artırıp azaltarak bu dengeyi sağlar. Bu rehberde, Kubernetes’te HPA’yı adım adım nasıl kuracağınızı, doğru metrikleri nasıl seçeceğinizi ve üretim ortamlarında dikkat edilmesi gereken noktaları paylaşacağım.

Neden HPA?

HPA, belirli bir hedefe (örneğin CPU kullanımının %70’te kalması) göre pod sayısını yatayda (horizontal) değiştirir. Ani trafik artışlarında hızlıca ölçeklenmek, düşük trafik saatlerinde ise maliyeti kısmak için idealdir. Üstelik Kubernetes 1.26+ sürümlerinde autoscaling/v2 API’si ile birden fazla metriği aynı anda değerlendirerek daha akıllı kararlar verebilir.

Önkoşullar

HPA’nın doğru çalışması için kümenizde bazı bileşenlerin hazır olması gerekir. En kritik bağımlılık metrics-server’dır. Bu bileşen, CPU ve bellek gibi kaynak metriklerini Kubernetes API üzerinden ulaşılabilir kılar.

Ayrıca Deployment’ınızdaki container’ların resource requests/limits alanlarının tanımlı olması gerekir. Aksi hâlde HPA CPU/Bellek bazlı hedefleri doğru hesaplayamaz.

Metrics Server Kurulumu (Örnek)

Çoğu yönetilen Kubernetes hizmeti (GKE, AKS, EKS) metrics-server’ı hazır getirir. Kendi kümenizde kurmanız gerekiyorsa, resmi manifest veya Helm chart kullanabilirsiniz.

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl get apiservices | grep metrics
kubectl top nodes
kubectl top pods -A

Yukarıdaki komutlar hatasız çalışıyorsa, metrik akışı sağlanmıştır ve HPA için hazırsınız.

Örnek Uygulama ve HPA Tanımı

Aşağıdaki örnekte CPU hedefi %70 olan bir HPA tanımı bulunuyor. API sürümü olarak autoscaling/v2 kullanıyoruz. Bu sürüm, ölçeklendirme davranışını (behavior) detaylı kontrol etmeye izin verir.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-api-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-api
  minReplicas: 2
  maxReplicas: 15
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 30
      policies:
        - type: Percent
          value: 100
          periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 20
          periodSeconds: 60
      selectPolicy: Min

Bu yapılandırma, ihtiyaç durumunda pod sayısını hızlı artırırken (burst trafiği yakalama), azaltma işlemlerinde daha konservatif davranır (ani düşüşlerde dalgalanmayı engelleme).

Gelişmiş Metrikler: CPU, Bellek, Özel ve Harici

HPA, birden fazla metrikle çalışabilir ve ölçeklendirme kararını en baskın sinyale göre verir:

CPU/Bellek (Resource): averageUtilization ile yüzdesel hedefler verilir. CPU için genellikle %60–70, bellek için uygulama karakteristiğine göre %60–80 yaygındır.

Object/Pods: Uygulama seviyesinde RPS (request per second) gibi metrikleri pod başına normalize ederek ölçeklenebilir. Örneğin Nginx Ingress üzerinden istek sayısı.

External: Prometheus Adapter gibi bir adaptörle gecikme süresi, kuyruk uzunluğu, Kafka lag gibi harici metriklere göre ölçeklendirme yapılabilir.

Test: Yük Üreterek Doğrulama

HPA’nın doğru tepki verip vermediğini anlamak için kısa süreli bir yük testi yapabilirsiniz. Örneğin hey veya k6 ile endpoint’lerinize istek gönderebilir, ardından aşağıdaki komutla HPA durumunu izleyebilirsiniz:

kubectl describe hpa web-api-hpa
kubectl get hpa
kubectl top pods -n default

Çıkışta “Current” ve “Target” metrikleri ile “Desired Replicas” alanının beklenen şekilde değiştiğini gözlemlemelisiniz.

En İyi Pratikler

1) Doğru resource requests/limits: “request” değerlerini gerçekçi belirleyin. Çok düşük değerler HPA’yı gereğinden fazla tetikler; çok yüksek değerler ise ölçeklenmeyi geciktirir.

2) Stabilizasyon pencereleri: behavior.scaleDown altında 300–600 saniye aralığı çoğu web uygulaması için uygundur. Bu, titremeyi (flapping) azaltır.

3) Çoklu metrik kullanın: CPU’ya ek olarak RPS veya kuyruk uzunluğu gibi iş metrikleri eklemek daha doğru ölçeklendirme sağlar. Baskın metrik prensibini unutmayın: en yüksek gereksinimi işaret eden metrik kazanır.

4) Soğuk başlangıç sürelerini hesaba katın: Container başlatma süresi uzunsa scaleUp politikalarını daha agresif yapın; ör. Percent 100 veya Pods 4 gibi.

5) Pod Disruption Budget (PDB) ve Readiness: HPA ile birlikte PDB ve readinessProbe ayarlarını gözden geçirerek ölçeklenme ve dağıtım sırasında kesinti riskini azaltın.

6) VPA ve HPA birlikte kullanım: HPA yatay, VPA dikey ölçekleme yapar. Aynı kaynağı aynı anda hedeflememek için VPA’yı “recommendation” modunda çalıştırmayı değerlendirin.

Sık Karşılaşılan Hatalar ve Çözümler

Hata: HPA metrik okuyamıyor. Çözüm: metrics-server’ın sağlıklı çalıştığını doğrulayın; API erişim hatalarını ve TLS ayarlarını kontrol edin.

Hata: Pod sayısı artmıyor. Çözüm: Deployment’ın replicas alanı başka bir kontrolcü tarafından sabitlenmiş olabilir. Ayrıca node kapasitesi yetersizse Cluster Autoscaler gerekebilir.

Hata: Ölçeklendirme çok agresif veya çok yavaş. Çözüm: behavior.policies ve stabilizationWindowSeconds değerlerini gözden geçirin; metrik hedeflerini (averageUtilization) gerçek yük profiline göre ayarlayın.

Sonuç

Doğru yapılandırılmış bir HPA, Kubernetes ortamınızda esneklik ve maliyet verimliliği sağlar. Metrics-server, isabetli resource ayarları ve davranış politikaları ile desteklendiğinde, yük dalgalanmalarına hızla uyum sağlayan, istikrarlı ve performanslı bir mimari kurabilirsiniz. Üretime geçmeden önce küçük bir yük testiyle ayarları doğrulamak, canlıya çıktıktan sonra ise metrikleri izleyip ince ayar yapmak en sağlıklı yaklaşımdır.

12 Ekim 2025 Pazar

OpenTelemetry ile Node.js Uygulamalarında Dağıtık İzleme: Jaeger ile 15 Dakikada Kurulum

OpenTelemetry nedir ve neden şimdi?

Modern uygulamalar mikroservisler, HTTP çağrıları, mesaj kuyrukları ve veritabanı etkileşimleriyle dolu. Bir isteğin nerede yavaşladığını veya neden hata verdiğini anlamak için klasik loglar tek başına yetmiyor. OpenTelemetry (OTel), dil bağımsız bir standart ve SDK seti olarak uygulama içinde otomatik enstrümantasyon sağlar; iz (trace), span, metrik ve log verilerini toplayıp OTLP gibi açık protokollerle istediğiniz araca yollar. Bu rehberde, Node.js bir servise OTel entegre ederek izleri Jaeger üzerinden görselleştireceğiz.

Hedef

Amaç: Node.js uygulamanızdaki HTTP isteklerinin uçtan uca izlenmesini 15 dakikada etkinleştirmek. İzleri toplamak için OpenTelemetry Node SDK’sını kullanacağız, çıktıyı OTLP üzerinden gönderecek ve Jaeger All-in-One ile arayüzde görüntüleyeceğiz.

Önkoşullar

- Node.js 16+ ve npm yüklü olmalı. - Docker çalışıyor olmalı. - Uygulama Express, Fastify veya yerleşik HTTP modülü kullanıyor olabilir; OTel, otomatik enstrümantasyonla bu kütüphaneleri tanır.

Adım 1: Paketleri yükleyin

Projeye OpenTelemetry bağımlılıklarını ekleyin: npm i @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/resources @opentelemetry/semantic-conventions @opentelemetry/exporter-trace-otlp-http

Bu paketler; API yüzeyi, Node SDK, otomatik enstrümantasyon, kaynak (resource) nitelikleri ve OTLP HTTP trace exporter içerir. İhtiyaca göre gRPC tabanlı exporter da tercih edebilirsiniz fakat yerelde HTTP pratik ve hızlıdır.

Adım 2: Tracing başlatıcısını oluşturun

Proje köküne tracing.js isminde bir dosya ekleyin ve SDK’yı minimum ayarlarla başlatın. Ana fikir: servis adını tanımlayın, OTLP exporter’ı 4318 portuna yönlendirin ve otomatik enstrümantasyon modüllerini etkinleştirin.

Örnek yapılandırma (özet): const { NodeSDK } = require('@opentelemetry/sdk-node'); const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node'); const { Resource } = require('@opentelemetry/resources'); const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http'); const sdk = new NodeSDK({ resource: new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: 'orders-api', [SemanticResourceAttributes.SERVICE_VERSION]: '1.0.0' }), traceExporter: new OTLPTraceExporter({ url: 'http://localhost:4318/v1/traces' }), instrumentations: [getNodeAutoInstrumentations()] }); sdk.start(); process.on('SIGTERM', () => sdk.shutdown());

Burada service.name gelecekteki sorgular için kritik; Jaeger’de projeyi bu ad üzerinden bulacaksınız. Versiyon alanı, sürüm bazlı karşılaştırmalar için faydalıdır.

Adım 3: Uygulamayı OTel ile çalıştırın

Node sürecini tracing başlatıcısı ile preload ederek başlatın: node -r ./tracing.js app.js

Eğer bir test isteği göndermek isterseniz, uygulama ayağa kalktıktan sonra örneğin curl http://localhost:3000/health gibi basit bir çağrı yapın. OTel, HTTP istemci ve sunucu katmanlarını, Express route’larını ve veritabanı sürücülerini otomatik olarak span’lere dönüştürür.

Adım 4: Jaeger All-in-One’ı başlatın

Jaeger’i tek komutla çalıştırabilirsiniz. Bu imaj, OTLP HTTP alıcısı ve web arayüzünü içerir: docker run -d --name jaeger -p 16686:16686 -p 4318:4318 jaegertracing/all-in-one:1.56

- 16686: Jaeger UI portu. - 4318: OTLP HTTP endpoint’i. Uygulamanızdaki exporter URL’si ile eşleşir. Arayüze tarayıcıdan erişip (localhost:16686) “services” alanında orders-api servisini seçerek izleri görüntüleyebilirsiniz.

Adım 5: Manuel span eklemek (opsiyonel)

Otomatik enstrümantasyon çoğu senaryo için yeterli olsa da domain mantığınızı daha iyi anlamak için manuel span eklemek değerlidir. Örneğin kritik bir iş kuralını ölçmek için: const { context, trace } = require('@opentelemetry/api'); const tracer = trace.getTracer('orders-business'); await tracer.startActiveSpan('price-calculation', span => { // iş mantığı ... span.setAttribute('discount.applied', true); span.end(); });

Bu şekilde, Jaeger’de sadece altyapı çağrılarını değil, iş süreçlerinizi de okunaklı şekilde takip edebilirsiniz.

Üretim için en iyi uygulamalar

- Örnekleme (sampling): Trafiğiniz yüksekse, varsayılan oranı düşürün. Çevresel değişkenle kontrol etmek pratik: OTEL_TRACES_SAMPLER=traceidratio ve OTEL_TRACES_SAMPLER_ARG=0.1 (yüzde 10). - Kaynak nitelikleri: Ortam bilgilerini ekleyin: deployment.environment=prod, cloud.region=eu-central-1. - Veri güvenliği: Hassas verileri span attribute veya event’lerde taşımayın. Maskleme/sansürleme katmanı ekleyin. - Bağımlılık izleme: HTTP client timeouts, retry politikaları ve hataları span event’lerinde açıkça belirtin. - Başlatma düzeni: Tracing dosyanızı uygulama kodundan önce yüklediğinizden emin olun; aksi halde ilk istekler enstrümanlanmayabilir.

Sorun giderme

- İzler gelmiyor: Exporter URL’sini ve portu doğrulayın (http://localhost:4318/v1/traces). - CORS/agent hatası: Sunucu tarafında çalıştığınızdan emin olun; tarayıcı için farklı SDK gerekir. - Servis görünmüyor: service.name niteliği boşsa Jaeger listede göstermeyebilir. - Ağ çakışmaları: 4318 portu başka bir süreç tarafından kullanılıyorsa, Jaeger’i farklı portla çalıştırın ve exporter URL’sini eşitleyin.

Sonuç

OpenTelemetry ile Node.js uygulamanıza dakikalar içinde dağıtık izleme ekleyebilir, Jaeger üzerinden gecikmeleri, hata oranlarını ve bağımlılık zincirlerini şeffaf biçimde görebilirsiniz. Daha ileri kullanımda OpenTelemetry Collector ekleyip verileri birden fazla hedefe (ör. Tempo, Zipkin) yönlendirebilir; metrik ve log’ları aynı bağlamda zenginleştirerek tam kapsamlı gözlemlenebilirlik elde edebilirsiniz. Başlangıç için bu kurulum, üretimde dahi temel ihtiyaçları karşılayacak kadar hafif ve esnektir.

6 Eylül 2025 Cumartesi

Docker ve OpenTelemetry ile Node.js Uygulamasında Dağıtık İzleme: Adım Adım Kurulum Kılavuzu

Giriş

Modern mikroservis mimarilerinde bir isteğin sistem içinde nasıl yol aldığını anlamak, performans sorunlarını çözmek ve kök neden analizi yapmak için dağıtık izleme artık bir zorunluluk. OpenTelemetry (OTel), dil bağımsız açık standartları ve zengin SDK’ları ile Node.js uygulamalarınızda izleme (tracing) kurulumunu kolaylaştırır. Bu yazıda, Docker + OpenTelemetry Collector + Jaeger kullanarak Node.js tabanlı bir serviste uçtan uca izlemeyi adım adım kuracağız. Amaç, üretime yakın bir geliştirme deneyimi sağlamak, gecikmeleri ölçmek ve bağımlılıkları görünür kılmaktır.

Mimari ve Bileşenler

Kuracağımız basit topolojide üç temel bileşen bulunuyor: 1) Otomatik enstrümantasyonla iz verisi üreten Node.js servisi, 2) OTLP üzerinden iz kabul edip yöneten OpenTelemetry Collector, 3) Sorgulama ve görselleştirme için Jaeger. Collector, gelecekte Grafana Tempo, Honeycomb veya Zipkin gibi hedeflere geçişi kolaylaştıran bir ara katman görevi görür.

Node.js Projesini Hazırlama

Yeni bir proje başlatın ve gerekli bağımlılıkları kurun. Örnek bir Express API üzerinden gideceğiz, fakat otomatik enstrümantasyon HTTP, gRPC, MySQL, Redis gibi birçok paketi destekler.

# Projeyi başlat
npm init -y

# Express ve OpenTelemetry paketleri
npm i express
npm i @opentelemetry/sdk-node @opentelemetry/api @opentelemetry/resources \
@opentelemetry/semantic-conventions @opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-otlp-grpc

Ardından uygulama girişinde OpenTelemetry’yi başlatacak bir dosya oluşturun. Bu dosya, servis adı ve ortam gibi meta bilgileri de ekler.

// tracing.js
'use strict';
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { Resource } = require('@opentelemetry/resources');
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-otlp-grpc');

const sdk = new NodeSDK({
  resource: new Resource({
    [SemanticResourceAttributes.SERVICE_NAME]: 'node-api',
    [SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: process.env.NODE_ENV || 'dev',
  }),
  traceExporter: new OTLPTraceExporter({
    url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://otel-collector:4317'
  }),
  instrumentations: [getNodeAutoInstrumentations()],
});

sdk.start()
  .then(() => console.log('OpenTelemetry başlatıldı'))
  .catch((err) => console.error('OTel hatası:', err));

process.on('SIGTERM', () => {
  sdk.shutdown().finally(() => process.exit(0));
});

Basit bir Express sunucusu ekleyelim. tracing.js, uygulamadan önce yüklenmelidir ki tüm modüller doğru enstrümante edilsin.

// index.js
'use strict';
require('./tracing'); // OTel ön yükleme

const express = require('express');
const app = express();

app.get('/health', (req, res) => {
  res.json({ ok: true, ts: Date.now() });
});

app.get('/slow', async (req, res) => {
  await new Promise(r => setTimeout(r, 300)); // yapay gecikme
  res.send('yavaş yanıt');
});

app.listen(3000, () => console.log('API 3000 portunda'));

OpenTelemetry Collector ve Jaeger ile Docker Compose

Collector, uygulamadan gelen OTLP verilerini alıp Jaeger’a iletecek. Aşağıda temel bir docker-compose yapısı ve Collector konfigürasyonu bulunuyor.

# docker-compose.yml
version: '3.9'
services:
  api:
    build: .
    command: node index.js
    environment:
      NODE_ENV: dev
      OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4317
      OTEL_TRACES_SAMPLER: parentbased_traceidratio
      OTEL_TRACES_SAMPLER_ARG: '0.5'
    ports:
      - "3000:3000"
    depends_on:
      - otel-collector

  otel-collector:
    image: otel/opentelemetry-collector-contrib:0.103.0
    command: ["--config=/etc/otelcol-config.yaml"]
    volumes:
      - ./otelcol-config.yaml:/etc/otelcol-config.yaml:ro
    ports:
      - "4317:4317"   # OTLP gRPC
      - "4318:4318"   # OTLP HTTP (opsiyonel)
    depends_on:
      - jaeger

  jaeger:
    image: jaegertracing/all-in-one:1.57
    ports:
      - "16686:16686" # Jaeger UI

Collector’ın konfigürasyon dosyası, OTLP alıcıyı etkinleştirir ve verileri Jaeger’a yollar. İleride Zipkin, Tempo veya başka hedeflere ek ihracatçılar tanımlayabilirsiniz.

# otelcol-config.yaml
receivers:
  otlp:
    protocols:
      grpc:
      http:

exporters:
  jaeger:
    endpoint: jaeger:14250
    tls:
      insecure: true

processors:
  batch:
    timeout: 1s
    send_batch_size: 512

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [jaeger]

Çalıştırma ve Doğrulama

Proje köküne basit bir Dockerfile ekleyin. Node tabanlı minimal bir imaj, üretime giden yolda iyi bir başlangıçtır.

# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]

Artık ortamı ayağa kaldırabilirsiniz. Aşağıdaki komut, API, Collector ve Jaeger’ı birlikte çalıştırır.

docker compose up --build

Tarayıcıdan http://localhost:16686 adresine gidip Jaeger UI’ı açın. Service menüsünde “node-api” servis adını göreceksiniz. Ayrıntılı izler için bir iki istek atın:

curl http://localhost:3000/health
curl http://localhost:3000/slow

Jaeger üzerinden isteklerin gecikme dağılımını, span ağaçlarını, endpoint bazlı hataları ve bağımlılık grafini analiz ederek performans darboğazlarını hızla teşhis edebilirsiniz.

En İyi Uygulamalar ve İpuçları

Örnek konfigürasyonda örnekleme oranını yüzde 50 olarak ayarladık. Üretimde, trafik seviyesine göre oranı düşürmek ve belirli endpoint’lerde dinamik örnekleme uygulamak mantıklıdır. Ayrıca, Resource etiketlerine versiyon, bölge ve takım bilgisi eklemek arama ve filtrelemeyi kolaylaştırır. Kolektörde attributes veya transform işlemcileri ile PII verileri kırpma/anonimleştirme adımları ekleyebilirsiniz. Gecikmeleri daha iyi yorumlamak için kritik yerlerde manuel span eklemek (ör. yoğun CPU işlemi, harici API çağrıları) fayda sağlar.

Güvenlik açısından Collector ile uygulama arasındaki trafiği mTLS ile şifrelemek ve dış ağlara ihracatta TLS’i etkinleştirmek önemlidir. Gözlemlenebilirlik verisi de kritiktir; erişim kontrolü, saklama süresi ve maliyet optimizasyonu (ör. örnekleme, toplu gönderim ayarları) planlanmalıdır. CI/CD’de, tracer başlatma hatalarını görünür kılmak için sağlık kontrolleri ve basit duman testleri ekleyin.

Sonuç

OpenTelemetry, Node.js servisleriniz için satıcı bağımsız, geleceğe dönük bir izleme altyapısı kurmanızı sağlar. Docker ile izleme yığınını dakikalar içinde ayağa kaldırabilir, Collector aracılığıyla hedef sistemleri esnekçe değiştirebilir, Jaeger ile sorunları hızla teşhis edebilirsiniz. Bugünkü kurulum, üretime geçişte ihtiyaç duyacağınız dinamik örnekleme, ek işlemciler, metrik ve log toplama gibi yeteneklerin de temelini oluşturur. İlk adımı attınız; şimdi span’ları zenginleştirip gerçek kullanıcı senaryolarını görünür kılma zamanı.