Skip to content
~/sph.sh

Traefik 101: Otomatik Keşifli Modern Reverse Proxy

nginx kullanmayı bilen geliştiriciler için pratik Traefik rehberi. Temel kavramlar, kurulum örnekleri ve geleneksel reverse proxy'lere göre Traefik'i ne zaman seçeceğinizi öğrenin.

Özet

Traefik, dinamik altyapılar için geliştirilmiş modern bir reverse proxy ve load balancer. Geleneksel reverse proxy'lerin manuel konfigürasyon güncellemeleri gerektirmesinin aksine, Traefik servisleri otomatik keşfeder ve routing kurallarını kendisi günceller. Bu yazıda temel kavramları, pratik Docker kurulumlarını ve nginx ile dürüst karşılaştırmaları bulacaksın - böylece senin use case'in için doğru aracı seçebilirsin.

Traefik Nedir?

Traefik, altyapındaki servisleri otomatik keşfeden ve kendini buna göre konfigure eden cloud-native bir edge router. nginx'te servisler değiştiğinde konfigürasyon dosyasını manuel olarak editlemen ve servisi reload etmen gerekirken, Traefik container orchestrator'ünü (Docker, Kubernetes) izler ve routing kurallarını otomatik günceller.

Öğrendiklerime göre Traefik, servislerin sık sık gelip gittiği ortamlarda parlıyor - microservice deployment'ları, development ortamları veya developer'ların kendi servislerini deploy ettiği platformlarda. Her yerde nginx'i replace etmeye çalışmıyor; spesifik bir sorunu çözüyor: dinamik konfigürasyon yönetimi.

Traefik'in Çözdüğü Temel Problem

Sürekli karşılaştığım bir senaryo var: Docker Swarm veya Kubernetes cluster'ına yeni bir microservice deploy ediyorsun. nginx ile yapman gerekenler:

  1. nginx konfigürasyon dosyasını editlemek
  2. Konfigürasyonu test etmek
  3. nginx'i reload etmek
  4. Bir şey bozulmadığını umut etmek

Traefik ile Docker container'ına label'lar ekliyorsun veya Kubernetes service'ine annotation'lar koyuyorsun, routing kuralları otomatik güncelleniyor. Sunuculara SSH yapman, konfigürasyon dosyası editlemen, servis reload'u gerekmiyor.

Temel Kavramlar

1. Provider'lar

Provider'lar Traefik'in servisleri keşfetme yöntemi. Yaygın provider'lar:

  • Docker: Docker container'larını ve label'larını izler
  • Kubernetes: Ingress/IngressRoute resource'larını okur
  • File: Geleneksel konfigürasyon dosyaları (evet, hala statik config kullanabilirsin)
  • Consul, Etcd: Service discovery backend'leri

Docker ile çalışırken öğrendim ki provider abstraction güçlü bir kavram—development'ta Docker label'ları ile başlayıp production'da Kubernetes annotation'larına geçebilirsin, aynı mental modeli kullanarak. Statik servisler için nginx genellikle yeterli; sık deployment varsa Traefik avantaj sağlar.

2. Entrypoint'ler

Entrypoint'ler Traefik'in hangi portları dinlediğini tanımlar. Tipik kurulum:

yaml
# Port 80'de HTTP entrypoint--entrypoints.web.address=:80
# Port 443'te HTTPS entrypoint--entrypoints.websecure.address=:443

3. Router'lar

Router'lar entrypoint'leri kurallara göre servislerle bağlar. Kurallar şunlara göre eşleşebilir:

  • Host header'ları: Host(api.example.com)
  • Path prefix'leri: PathPrefix(/api)
  • Header'lar: Headers(X-Custom-Header, value)
  • Birden fazla koşul: Host(api.example.com) && PathPrefix(/v1)

4. Middleware'ler

Middleware'ler request/response'ları dönüştürür. Traefik'in gücünün ortaya çıktığı yer burası:

  • HTTP'yi HTTPS'e redirect et
  • Header ekle/çıkar
  • Rate limiting
  • Basic authentication
  • Circuit breaker'lar
  • Compression

Pratik Kurulum Örneği

Hadi gerçek çalışan bir örnek oluşturalım. İşte iki servisi yöneten Traefik ile Docker Compose kurulumu:

yaml
version: '3.8'
services:  traefik:    image: traefik:v2.10    command:      # Docker provider'ı etkinleştir      - "--providers.docker=true"      - "--providers.docker.exposedbydefault=false"      # Entrypoint'leri tanımla      - "--entrypoints.web.address=:80"      - "--entrypoints.websecure.address=:443"      # Dashboard'u etkinleştir (production'da kaldır)      - "--api.dashboard=true"      # Access log'ları etkinleştir      - "--accesslog=true"    ports:      - "80:80"      - "443:443"      - "8080:8080"  # Dashboard    volumes:      - /var/run/docker.sock:/var/run/docker.sock:ro    labels:      # Dashboard için Traefik'i etkinleştir      - "traefik.enable=true"      - "traefik.http.routers.dashboard.rule=Host(`traefik.localhost`)"      - "traefik.http.routers.dashboard.service=api@internal"
  whoami:    image: traefik/whoami    labels:      # Bu container için Traefik'i etkinleştir      - "traefik.enable=true"      # Routing kuralını tanımla      - "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)"      # Entrypoint'i belirt      - "traefik.http.routers.whoami.entrypoints=web"
  api:    image: nginx:alpine    labels:      - "traefik.enable=true"      - "traefik.http.routers.api.rule=Host(`api.localhost`)"      - "traefik.http.routers.api.entrypoints=web"      # Path stripping için middleware ekle      - "traefik.http.routers.api.middlewares=api-stripprefix"      - "traefik.http.middlewares.api-stripprefix.stripprefix.prefixes=/api"

Bunu docker-compose up -d ile başlat ve şunlara erişebilirsin:

  • http://whoami.localhost - whoami servisi
  • http://api.localhost - nginx servisi
  • http://traefik.localhost - Traefik dashboard

Eşdeğer nginx Konfigürasyonu

Karşılaştırma için, aynı kurulum için nginx'te ihtiyacın olanlar:

nginx
# /etc/nginx/conf.d/services.conf
# Upstream tanımlarıupstream whoami_backend {    server whoami:80;}
upstream api_backend {    server api:80;}
# whoami servisiserver {    listen 80;    server_name whoami.localhost;
    location / {        proxy_pass http://whoami_backend;        proxy_set_header Host $host;        proxy_set_header X-Real-IP $remote_addr;        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_set_header X-Forwarded-Proto $scheme;    }}
# API servisiserver {    listen 80;    server_name api.localhost;
    location /api {        rewrite ^/api/(.*)$ /$1 break;        proxy_pass http://api_backend;        proxy_set_header Host $host;        proxy_set_header X-Real-IP $remote_addr;        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_set_header X-Forwarded-Proto $scheme;    }}

nginx config gayet iyi, ama yeni bir servis eklediğinde ne olduğuna dikkat et: dosyayı editliyorsun, test ediyorsun ve nginx'i reload ediyorsun. Traefik ile sadece label'lı yeni bir container başlatıyorsun.

Middleware'ler Çalışırken

İşte HTTPS redirect ve rate limiting kullanan middleware'ler ile pratik bir örnek:

yaml
services:  traefik:    image: traefik:v2.10    command:      - "--providers.docker=true"      - "--providers.docker.exposedbydefault=false"      - "--entrypoints.web.address=:80"      - "--entrypoints.websecure.address=:443"      # Global HTTP to HTTPS redirect      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"    ports:      - "80:80"      - "443:443"    volumes:      - /var/run/docker.sock:/var/run/docker.sock:ro
  api:    image: your-api:latest    labels:      - "traefik.enable=true"      - "traefik.http.routers.api.rule=Host(`api.example.com`)"      - "traefik.http.routers.api.entrypoints=websecure"
      # Rate limiting middleware'i uygula      - "traefik.http.routers.api.middlewares=api-ratelimit,api-auth"
      # Rate limit: saniyede ortalama 100 request, 50 burst      - "traefik.http.middlewares.api-ratelimit.ratelimit.average=100"      - "traefik.http.middlewares.api-ratelimit.ratelimit.burst=50"
      # Basic authentication      - "traefik.http.middlewares.api-auth.basicauth.users=admin:$$apr1$$hash..."

Aynı rate limiting'i nginx'te uygulamak ngx_http_limit_req_module (iyi çalışır) veya harici araçlar gerektirir. Her iki yaklaşım da işe yarar; Traefik versiyonu sadece farklı konfigure edilir.

Request Flow Mimarisi

Request'lerin Traefik'ten nasıl geçtiğine geleneksel kurulumla karşılaştırmalı bakalım:

nginx Yerine Traefik Ne Zaman Seçilmeli

Öğrendiklerime göre seçim "daha iyi" olmaktan çok amaca uygunluk hakkında. İşte işe yarayanlar:

Traefik'i Şunlarda Seç:

  1. Dinamik altyapı: Servisler sık deploy edilip kaldırılıyor
  2. Container-native: Docker, Kubernetes veya benzeri orchestrator'lar kullanıyorsun
  3. Developer self-service: Takımlar kendi servislerini label/annotation'larla deploy ediyor
  4. Otomatik HTTPS: Let's Encrypt entegrasyonu built-in ve çok kolay
  5. Microservice'ler: Bağımsız değişen bir sürü küçük servis

Gerçek senaryo: 30+ geliştirme takımının 200+ servis deploy ettiği bir platform takımıyla çalışırken Traefik'in otomatik keşfi, önceki nginx kurulumumuza göre routing konfigürasyon yükünü yaklaşık %70 azalttı. Artık reverse proxy config'lerini güncellemek için ticket açılmıyordu.

nginx'i Şunlarda Seç:

  1. Statik altyapı: Servisler nadiren değişiyor
  2. Kompleks URL rewriting: nginx'in rewrite engine'i daha olgun
  3. Maksimum performans: nginx'in latency'si daha düşük (fark küçük olsa da)
  4. Gelişmiş caching: nginx'in caching yetenekleri daha sofistike
  5. Statik dosya sunma: nginx bu işte üstün

Gerçek senaryo: Çoğunlukla statik asset'ler sunan yüksek trafikli bir content delivery kurulumu için, düzgün caching konfigürasyonlu nginx Traefik kurulumumuzu geçti. Konfigürasyon karmaşıklığı performans kazancına değdi.

Yaygın Pattern'ler ve Gotcha'lar

Pattern 1: Servis Başına Birden Fazla Router

Aynı servise farklı path'leri farklı middleware'lerle yönlendirebilirsin:

yaml
labels:  - "traefik.enable=true"
  # Public API - rate limited  - "traefik.http.routers.api-public.rule=Host(`api.example.com`) && PathPrefix(`/public`)"  - "traefik.http.routers.api-public.middlewares=rate-limit"
  # Internal API - rate limit yok, authentication gerekli  - "traefik.http.routers.api-internal.rule=Host(`api.example.com`) && PathPrefix(`/internal`)"  - "traefik.http.routers.api-internal.middlewares=auth"

Pattern 2: Weighted Load Balancing

yaml
# Servis A - trafiğin %80'ilabels:  - "traefik.http.services.myapp.loadbalancer.server.port=8080"  - "traefik.http.services.myapp.loadbalancer.sticky.cookie=true"
# Servis B - trafiğin %20'si (canary deployment)labels:  - "traefik.http.services.myapp-canary.loadbalancer.server.port=8080"
# Weighted load balancing'li routerlabels:  - "traefik.http.routers.myapp.service=myapp-weighted"  - "traefik.http.services.myapp-weighted.weighted.services[0].name=myapp"  - "traefik.http.services.myapp-weighted.weighted.services[0].weight=80"  - "traefik.http.services.myapp-weighted.weighted.services[1].name=myapp-canary"  - "traefik.http.services.myapp-weighted.weighted.services[1].weight=20"

Gotcha 1: Docker Socket Erişimi

Traefik'in Docker socket'ine read erişimi lazım. Production'da, maruz kalma riskini sınırlamak için tecnativa/docker-socket-proxy gibi bir Docker socket proxy kullanmayı düşün.

Gotcha 2: Label Syntax

Label'lar string olduğu için kompleks değerler düzgün escape edilmeli:

yaml
# Yanlış - bozulur- "traefik.http.routers.api.rule=Host(`api.example.com`) && PathPrefix(`/v1`)"
# Doğru - compose versiyonuna göre backtick'leri escape et- 'traefik.http.routers.api.rule=Host(`api.example.com`) && PathPrefix(`/v1`)'

Gotcha 3: Default Ayarlar

Varsayılan olarak Traefik TÜM container'ları expose eder. exposedbydefault=false yap ve servisleri açıkça etkinleştir:

yaml
command:  - "--providers.docker.exposedbydefault=false"

Gerçek Dünya Use Case'leri

Use Case 1: Development Ortamı

Multi-service local development için işe yarayanlar:

yaml
version: '3.8'
services:  traefik:    image: traefik:v2.10    command:      - "--providers.docker=true"      - "--providers.docker.exposedbydefault=false"      - "--entrypoints.web.address=:80"    ports:      - "80:80"    volumes:      - /var/run/docker.sock:/var/run/docker.sock:ro
  frontend:    image: node:18    working_dir: /app    command: npm run dev    volumes:      - ./frontend:/app    labels:      - "traefik.enable=true"      - "traefik.http.routers.frontend.rule=Host(`app.local`)"      - "traefik.http.services.frontend.loadbalancer.server.port=3000"
  backend:    image: node:18    working_dir: /app    command: npm start    volumes:      - ./backend:/app    labels:      - "traefik.enable=true"      - "traefik.http.routers.backend.rule=Host(`app.local`) && PathPrefix(`/api`)"      - "traefik.http.services.backend.loadbalancer.server.port=4000"

/etc/hosts'a 127.0.0.1 app.local ekle, birleşik bir local development URL'ine sahip olursun.

Use Case 2: Let's Encrypt ile Otomatik HTTPS

yaml
services:  traefik:    image: traefik:v2.10    command:      - "--providers.docker=true"      - "--providers.docker.exposedbydefault=false"      - "--entrypoints.web.address=:80"      - "--entrypoints.websecure.address=:443"
      # Let's Encrypt konfigürasyonu      - "[email protected]"      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"      - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
      # HTTP'den HTTPS'e redirect      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"    ports:      - "80:80"      - "443:443"    volumes:      - /var/run/docker.sock:/var/run/docker.sock:ro      - ./letsencrypt:/letsencrypt
  app:    image: your-app:latest    labels:      - "traefik.enable=true"      - "traefik.http.routers.app.rule=Host(`example.com`)"      - "traefik.http.routers.app.entrypoints=websecure"      - "traefik.http.routers.app.tls.certresolver=letsencrypt"

Traefik sertifika alımını, yenilemeyi ve sunmayı otomatik halleder. nginx ile genelde certbot'u cron job'larla ve nginx'i reload eden hook'larla kullanırsın.

Performans Değerlendirmeleri

Deneyimlerime göre, hem Traefik hem nginx çoğu workload için mükemmel performans gösteriyor. Gözlemlerim:

  • Latency: nginx tipik olarak 1-2ms, Traefik 2-4ms ekler (çoğu uygulama için fark edilmez)
  • Throughput: nginx sentetik benchmark'larda biraz daha yüksek request/saniye sağlar
  • Resource kullanımı: Traefik daha fazla memory kullanır (baseline 50-100MB vs nginx'in 10-20MB'ı)
  • CPU: Normal yüklerde benzer; nginx ekstrem trafik altında öne geçer

Çoğu uygulama için Traefik'in otomatik keşfinin operasyonel faydaları küçük performans farkından ağır basar. Ultra-yüksek-trafikli statik content delivery için nginx'in performans avantajı daha önemli.

Migration Stratejisi

nginx'ten Traefik'e geçmeyi düşünüyorsan, işe yarayanlar:

  1. Hybrid başla: nginx ve Traefik'i yan yana çalıştır
  2. İncrementally migrate et: Servisleri teker teker taşı
  3. File provider kullan: Traefik statik config dosyalarını okuyabilir (nginx'e benzer)
  4. İyice test et: Özellikle middleware chain'leri ve routing kurallarını
  5. Metrikleri izle: Latency, hata oranları, resource kullanımını karşılaştır

Öğrendim ki her şeyi migrate etmen gerekmiyor. Bazı takımlar statik content ve API'ler için nginx kullanırken Traefik dinamik microservice'leri hallediyor.

Sonuç

Traefik nginx'i replace etmiyor - farklı bir sorunu çözüyor. Container'larla dinamik altyapı çalıştırıyorsan, Traefik'in otomatik keşfi operasyonel yükü önemli ölçüde azaltabilir. Statik content sunuyorsan veya stabil altyapı çalıştırıyorsan, nginx'in olgunluğu ve performansı cazip olmaya devam ediyor.

Aralarında seçim yapmak için işe yarayanlar:

  • Dinamik microservice'ler, sık deployment'lar → Traefik
  • Statik altyapı, maksimum performans → nginx
  • Her ikisi de lazım mı? → Birlikte çalıştır

En iyi tarafı ikisinin de mükemmel araçlar olması ve ihtiyaçlarına uygun olanı kullanabilmen. Yukarıdaki Docker Compose örneklerini kullanarak küçük bir denemeyle başla ve hangi mental modelin senin workflow'una daha uygun olduğunu gör.

Ek Kaynaklar

Bu yazıdaki konfigürasyon örnekleri kendi ortamında kopyalayıp deneyebilmen için hazır. Basit kurulumla başla, sonra ihtiyaçlarına göre middleware'leri ve otomatik HTTPS'i keşfet.

İlgili Yazılar