CoreDNS Rewrite Plugin ile DNS İstek Yönlendirme ve Alan Adı Dönüştürme

Kubernetes ortamlarında ya da kendi altyapını yönetirken DNS katmanında esneklik ihtiyacı er ya da geç karşına çıkar. Bir servisi taşıdın ama eski alan adına gelen istekleri yeni adrese yönlendirmen gerekiyor, ya da geliştirme ortamında production alan adlarını iç servislere map etmek istiyorsun. İşte tam bu noktada CoreDNS’in rewrite plugin’i devreye giriyor ve hayatını ciddi ölçüde kolaylaştırıyor.

Bu yazıda CoreDNS rewrite plugin’ini derinlemesine inceleyeceğiz. Temel sözdiziminden başlayıp gerçek dünya senaryolarına kadar her şeyi ele alacağız.

CoreDNS Rewrite Plugin Nedir?

CoreDNS, Go ile yazılmış, plugin tabanlı mimarisiyle öne çıkan modern bir DNS sunucusudur. Kubernetes’in varsayılan DNS çözümleyicisi olması sayesinde son yıllarda çok yaygınlaştı. Rewrite plugin ise gelen DNS sorgularını, sorgular backend’e ulaşmadan önce değiştirmenize ya da yanıtları istemciye dönmeden önce dönüştürmenize olanak tanır.

Birkaç önemli kullanım senaryosu şunlardır:

  • İstek tarafı yeniden yazma: Gelen sorgu adını değiştirerek farklı bir alan adına yönlendirme
  • Yanıt tarafı yeniden yazma: Upstream’den gelen yanıttaki alan adını değiştirme
  • CNAME zinciri kırma: Gereksiz CNAME hop’larını ortadan kaldırma
  • Geliştirme ortamı izolasyonu: Production URL’lerini test ortamına yönlendirme

Kurulum ve Temel Yapılandırma

CoreDNS zaten sisteminizde kuruluysa rewrite plugin varsayılan olarak geliyor. Eğer binary’yi kendiniz derliyorsanız plugin.cfg dosyasında rewrite satırının bulunduğundan emin olun.

Kubernetes kullanıyorsanız CoreDNS konfigürasyonu genellikle bir ConfigMap içinde tutulur:

kubectl -n kube-system get configmap coredns -o yaml

Kubernetes dışında bir sistemde CoreDNS’i başlatmak için şu şekilde bir Corefile oluşturabilirsiniz:

# /etc/coredns/Corefile
.:53 {
    errors
    health {
        lameduck 5s
    }
    ready
    log
    cache 30
    forward . 8.8.8.8 8.8.4.4
}

CoreDNS servisini başlatmak için:

sudo systemctl start coredns
sudo systemctl enable coredns
# Durumu kontrol et
sudo systemctl status coredns

Rewrite Plugin Sözdizimi

Rewrite plugin’in genel sözdizimi şöyle:

rewrite [continue|stop] FIELD [TYPE] FROM TO

Parametreleri açıklayalım:

  • continue: Eşleşme olduktan sonra sonraki kuralları da değerlendirmeye devam et
  • stop: Eşleşme olduktan sonra dur (varsayılan davranış)
  • FIELD: Hangi alanın değiştirileceği. name, class, type, edns0 olabilir
  • TYPE: Eşleşme türü. exact, prefix, suffix, substring, regex
  • FROM: Eşleştirilecek değer veya regex deseni
  • TO: Dönüştürülecek değer

Temel Rewrite Senaryoları

Exact Match ile Basit Yönlendirme

En yaygın kullanım, belirli bir alan adını tam eşleşmeyle başka bir adrese yönlendirmektir. Diyelim ki eski-servis.sirket.local sorgularını yeni-servis.sirket.local‘a yönlendirmek istiyorsunuz:

.:53 {
    rewrite stop name exact eski-servis.sirket.local. yeni-servis.sirket.local.
    forward . 192.168.1.1
    log
    errors
}

Önemli bir nokta: CoreDNS dahili olarak alan adlarını FQDN (Fully Qualified Domain Name) formatında işler. Yani trailing dot (sondaki nokta) eklemeyi unutmayın, aksi takdirde eşleşme gerçekleşmeyebilir.

Prefix ile Çoklu Alan Adı Yönlendirmesi

Birden fazla alt alan adını tek kuralda yönetmek için prefix kullanabilirsiniz. Örneğin tüm dev. prefix’li sorguları staging ortamına yönlendirmek için:

.:53 {
    rewrite stop name prefix dev. staging-proxy.internal.
    hosts {
        192.168.10.50 staging-proxy.internal
    }
    forward . 8.8.8.8
    log
    errors
}

Bu yapılandırmayla dev.api.sirket.com, dev.web.sirket.com gibi tüm sorgular staging proxy’ye gidecek.

Regex ile Gelişmiş Desen Eşleştirme

Regex desteği, rewrite plugin’in en güçlü özelliğidir. Karmaşık dönüşümler için {1}, {2} gibi yakalama gruplarını kullanabilirsiniz:

.:53 {
    rewrite stop name regex ^(.+).test.sirket.com.$ {1}.production.sirket.com.
    forward . 192.168.1.1
    log
    errors
}

Bu kural api.test.sirket.com sorgusunu api.production.sirket.com‘a dönüştürür. (.+) yakalama grubu ilk bölümü yakalar, {1} ise bunu TO kısmında kullanır.

Gerçek Dünya Senaryosu 1: Kubernetes’te Servis Geçişi

Kubernetes ortamında bir mikroservisi orders-v1 namespace’inden orders-v2 namespace’ine taşıdığınızı düşünün. Eski servisi referans eden uygulamaları hemen güncelleyemiyorsunuz. CoreDNS rewrite ile geçişi sorunsuz yapabilirsiniz.

Kubernetes CoreDNS ConfigMap’ini düzenleyelim:

kubectl -n kube-system edit configmap coredns
.:53 {
    errors
    health {
        lameduck 5s
    }
    ready
    kubernetes cluster.local in-addr.arpa ip6.arpa {
        pods insecure
        fallthrough in-addr.arpa ip6.arpa
        ttl 30
    }
    # orders-service v1'den v2'ye yönlendir
    rewrite stop name exact orders-service.orders-v1.svc.cluster.local. orders-service.orders-v2.svc.cluster.local.
    prometheus :9153
    forward . /etc/resolv.conf {
        max_concurrent 1000
    }
    cache 30
    loop
    reload
    loadbalance
}

Değişikliği uyguladıktan sonra CoreDNS pod’larının yeniden yüklenmesini bekleyin:

# CoreDNS pod'larını listele
kubectl -n kube-system get pods -l k8s-app=kube-dns

# Reload'u zorla (gerekirse)
kubectl -n kube-system rollout restart deployment coredns

# Test et
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup orders-service.orders-v1.svc.cluster.local

Yanıt Tarafı Yeniden Yazma (Answer Rewrite)

Bazı durumlarda sadece sorguyu değil, dönen yanıttaki ismi de değiştirmeniz gerekir. Bu özellikle CNAME kayıtlarıyla uğraşırken önemlidir:

.:53 {
    rewrite stop {
        name regex ^(.+).eski-domain.com.$ {1}.yeni-domain.com.
        answer name (.+).yeni-domain.com.$ {1}.eski-domain.com.
    }
    forward . 8.8.8.8
    log
    errors
}

answer name direktifi, upstream’den dönen yanıttaki alan adını istemci için geri dönüştürür. Böylece istemci kendi sorguladığı alan adıyla tutarlı bir yanıt alır.

Gerçek Dünya Senaryosu 2: Geliştirici Ortamı Split-Horizon DNS

Geliştirme ekibinin production URL’lerini kullanarak test yapabilmesi için split-horizon DNS kurgusu çok işe yarar. Geliştiricilerin api.sirket.com adresine yaptığı istekleri, yerel geliştirme sunucusuna yönlendirelim:

# /etc/coredns/Corefile - Geliştirici workstation için
.:53 {
    # Production API'yi local mock'a yönlendir
    rewrite stop name exact api.sirket.com. local-api-mock.dev.
    rewrite stop name exact cdn.sirket.com. local-cdn.dev.
    rewrite stop name exact auth.sirket.com. local-auth.dev.

    hosts /etc/coredns/dev-hosts {
        192.168.1.100 local-api-mock.dev
        192.168.1.100 local-cdn.dev
        192.168.1.100 local-auth.dev
        fallthrough
    }

    # Diğer tüm sorgular için upstream
    forward . 8.8.8.8 1.1.1.1
    log
    errors
    cache 10
}

Bu yapılandırmayla geliştirici api.sirket.com‘u çağırdığında gerçek production sunucusu yerine yerel mock servisine ulaşır. Diğer tüm DNS sorguları normal şekilde çözümlenir.

Gerçek Dünya Senaryosu 3: Çoklu Ortam DNS Yönetimi

Büyük organizasyonlarda dev, staging ve production ortamları için farklı Corefile’lar kullanmak yaygın bir pratiktir. Ancak merkezi bir CoreDNS instance’ından tüm ortamları yönetmek de mümkündür:

# /etc/coredns/Corefile - Merkezi DNS sunucusu
# Staging ortamı sorguları
staging.sirket.internal:53 {
    rewrite stop name suffix .staging.sirket.internal. .production.sirket.com.
    forward . 10.0.1.1
    log
    errors
}

# Dev ortamı sorguları
dev.sirket.internal:53 {
    rewrite continue name regex ^(.+).dev.sirket.internal.$ {1}.dev-cluster.internal.
    rewrite continue name regex ^db-(.+).dev.sirket.internal.$ db-mock.dev-infra.internal.
    forward . 10.0.2.1
    log
    errors
}

# Default zone
.:53 {
    forward . 8.8.8.8 8.8.4.4
    cache 300
    errors
}

Burada continue direktifini kullandığımıza dikkat edin. Birden fazla kural uygulanabiliyorsa hepsinin değerlendirileceği anlamına gelir. Bu, veritabanı sorgularını mock’a yönlendirirken diğer servisleri de dönüştürmenizi sağlar.

EDNS0 ile Metadata Tabanlı Yönlendirme

Rewrite plugin yalnızca alan adlarıyla sınırlı değil. EDNS0 option’larını da değiştirebilirsiniz. Bu özellikle DNS tabanlı yük dengeleyiciler veya GeoDNS çözümleriyle entegrasyon için kullanışlıdır:

# /etc/coredns/Corefile
.:53 {
    rewrite stop edns0 local set 0xffee "istanbul-datacenter"
    forward . 10.10.1.1
    log
    errors
}

Bu yapılandırma giden sorgulara EDNS0 option ekler ve upstream sunucunun isteği hangi veri merkezinden geldiğini anlamasına yardımcı olur.

Hata Ayıklama ve Test

Rewrite kurallarını test etmek için dig komutunu kullanabilirsiniz:

# Temel sorgu testi
dig @127.0.0.1 -p 53 eski-servis.sirket.local A

# Trace modu ile detaylı inceleme
dig @127.0.0.1 -p 53 +trace api.test.sirket.com

# Kısa çıktı formatı
dig @127.0.0.1 -p 53 +short orders-service.orders-v1.svc.cluster.local

# TTL ve tüm kayıt tipleri
dig @127.0.0.1 -p 53 +noall +answer sirket.local ANY

CoreDNS log çıktısını gerçek zamanlı izlemek için:

# Systemd servis logları
journalctl -u coredns -f

# Kubernetes pod logları
kubectl -n kube-system logs -f -l k8s-app=kube-dns

# Belirli bir sorguyu filtrele
kubectl -n kube-system logs -l k8s-app=kube-dns | grep "orders-service"

CoreDNS’i debug modunda çalıştırmak için Corefile’a debug ve log direktiflerini ekleyin:

.:53 {
    debug
    log
    errors
    rewrite stop name exact test.local. production.local.
    forward . 8.8.8.8
}

Yaygın Hatalar ve Çözümleri

Rewrite kurallarını yazarken sıkça karşılaşılan sorunlar ve çözümleri:

  • Trailing dot unutmak: CoreDNS dahili olarak FQDN kullanır. sirket.com yerine sirket.com. yazın. Aksi halde exact match çalışmaz.
  • Regex özel karakterleri escape etmemek: Nokta (.) regex’te herhangi bir karakteri eşler. Alan adlarında . kullanın.
  • continue/stop direktifini yanlış kullanmak: Birden fazla kural uygulayacaksanız continue, ilk eşleşmede durmak istiyorsanız stop kullanın. Varsayılan stop‘tur ama bunu açıkça belirtmek kodu daha okunabilir kılar.
  • Yanıt yeniden yazma eksikliği: Sadece sorguyu yeniden yazıp yanıtı yazmamak, istemcinin beklenmedik alan adları almasına neden olabilir. answer name bloğunu unutmayın.
  • Cache sorunları: Rewrite kuralı ekledikten sonra eski DNS yanıtları cache’den gelmeye devam edebilir. Cache TTL’ini düşürün ya da cache plugin’ini geçici olarak devre dışı bırakın.
  • Plugin sırası önemli: CoreDNS’te plugin’lerin Corefile’daki sırası işlenme sırasını belirler. Rewrite’ı her zaman forward ve cache’den önce tanımlayın.

Performans Optimizasyonu

Çok sayıda rewrite kuralı performansı etkileyebilir. Büyük ölçekli ortamlarda şu noktalara dikkat edin:

  • Regex yerine exact/prefix/suffix kullanın: Mümkün olduğunda regex yerine daha basit eşleşme türleri kullanın. Regex her sorgu için derlenir ve işlenir.
  • Kural sayısını minimize edin: On binlerce kural yerine, birkaç akıllı regex kuralı tercih edin.
  • Cache’i aktif tutun: Rewrite edilmiş yanıtlar da cache’lenebilir. Cache plugin’ini mutlaka kullanın.
# Optimum cache yapılandırması
.:53 {
    rewrite stop name regex ^(.+).legacy.com.$ {1}.modern.com.
    cache {
        success 9984
        denial 9984
        ttl 30
    }
    forward . 8.8.8.8
    errors
}

Prometheus ile Monitoring

CoreDNS rewrite işlemlerini izlemek için Prometheus entegrasyonu çok değerlidir:

.:53 {
    rewrite stop name exact eski.sirket.com. yeni.sirket.com.
    prometheus 0.0.0.0:9153
    forward . 8.8.8.8
    errors
    log
}

Prometheus scrape config:

# /etc/prometheus/prometheus.yml konfigürasyon parçası
scrape_configs:
  - job_name: 'coredns'
    static_configs:
      - targets: ['localhost:9153']
    scrape_interval: 15s

coredns_dns_requests_total ve coredns_dns_responses_total metrikleriyle hangi sorguların ne sıklıkla rewrite edildiğini takip edebilirsiniz.

Sonuç

CoreDNS rewrite plugin, DNS katmanında inanılmaz esneklik sağlayan güçlü bir araçtır. Kubernetes servis geçişlerinden geliştirici ortamı izolasyonuna, legacy sistemlerin modern altyapıya sorunsuz entegrasyonundan split-horizon DNS uygulamalarına kadar geniş bir kullanım yelpazesi sunar.

Pratikte en çok değer aldığım senaryolar şunlar oldu: Kubernetes’te sıfır kesinti servis geçişleri, geliştirme ekibi için production ortamını simüle eden yerel DNS yapılandırmaları ve büyük şirket birleşmelerinde iki farklı DNS namespace’ini tek çatı altında yönetmek.

Dikkat edilmesi gereken kritik nokta, her rewrite kuralını mutlaka test etmek. Yanlış bir regex deseni beklenmedik alanları da etkileyebilir. dig ile kapsamlı test, CoreDNS debug log’larıyla doğrulama ve kademeli rollout her zaman doğru yaklaşımdır.

Rewrite plugin’i doğru kullandığınızda, uygulama katmanında hiçbir değişiklik yapmadan DNS düzeyinde büyük esneklik kazanırsınız. Bu, özellikle büyük ve köklü altyapılarda “kod değiştirmeden geçiş” stratejilerinin temel taşlarından biri haline gelir.

Bir yanıt yazın

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