Kubernetes Ingress kaynakları temelde HTTP/HTTPS trafiğini yönlendirmek için tasarlanmıştır. Ancak, NGINX Ingress Controller gibi ek özelliklere sahip bir çözümle, aynı Ingress üzerinden TCP/UDP trafiğini de yönlendirebilirsiniz. Böylece veritabanı bağlantıları veya özel protokollerle iletişim kuran servislerinizi “tek bir LoadBalancer IP” üzerinden dışarıya açmak mümkün hâle gelir.

Bu rehberde, TCP trafiğinin ingress-nginx üzerinden nasıl yapılandırılacağını adım adım anlatacak ve gerektiğinde hızlı konfigürasyon değişikliği yapabilmeniz için kubectl edit komutlarına örnekler vereceğiz.


1. Neden TCP/UDP Desteği Gerekir?

  • HTTP dışı servisler: MySQL, PostgreSQL gibi veritabanları veya Redis, RabbitMQ gibi TCP bazlı uygulamalar.
  • Tek bir giriş noktası: Farklı port/protokol kullanan servisleri, ek bir LoadBalancer oluşturmak yerine var olan Ingress Controller üzerinden sunmak.
  • Yönetilebilirlik: Tüm trafiği tek bir yönetim katmanı (NGINX Ingress Controller) altında toplamak ve aynı güvenlik/izleme politikalarını uygulamak.

2. NGINX Ingress Controller Parametreleri

TCP/UDP port yönlendirmesini etkinleştirmek için, NGINX Ingress Controller manifest (Deployment/DaemonSet) tanımında şu argümanlara ihtiyaç duyulur:

args:
  - /nginx-ingress-controller
  - --tcp-services-configmap=ingress-nginx/tcp-services
  - --udp-services-configmap=ingress-nginx/udp-services

Bu sayede controller, ConfigMap içinde tanımlanmış TCP/UDP portlarını okuyup yönlendirebilir.

kubectl edit ile Argüman Ekleme

Mevcut bir NGINX Ingress Controller’ın Deployment/DaemonSet’ine bu argümanları eklemek için:

kubectl edit deployment ingress-nginx-controller -n ingress-nginx

Açılan editörde, spec.template.spec.containers[].args altına yukarıdaki satırları ekleyin ve kaydedin. Kaydettiğinizde Kubernetes, ilgili Pod’ları yeniden başlatarak yeni argümanlarla ayağa kaldıracaktır.


3. NGINX Ingress Controller’ın Service Tanımı

Ingress Controller, dış dünyaya tek bir IP ya da DNS aracılığıyla erişim sağladığı için, TCP portunuzu da bu Service üzerinde açmalısınız. Aşağıdaki örnekte, 9000 numaralı portu TCP olarak sunuyoruz:

apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  type: LoadBalancer
  ports:
    - name: http
      port: 80
      targetPort: 80
      protocol: TCP
    - name: https
      port: 443
      targetPort: 443
      protocol: TCP
    - name: proxied-tcp-9000
      port: 9000
      targetPort: 9000
      protocol: TCP
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

Güncel bir Service’de sonradan TCP port eklemek için:

kubectl edit service ingress-nginx -n ingress-nginx

Açılan YAML’da spec.ports listesine 9000 numaralı port tanımını ilave edin.


4. TCP ConfigMap Tanımı

TCP/UDP yönlendirmesinin kalbi, ingress-nginx namespace’inde tanımlanan ConfigMap nesneleridir. Her satırda dış dünyaya açılacak port, ilgili Service’e yönlendirilir.

Örnek TCP ConfigMap (tcp-services):

apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: ingress-nginx
data:
  9000: "default/example-go:8080"
  • Anahtar (key): Dış dünyada dinlenecek port, burada 9000.
  • Değer (value): <namespace>/<servis>:<port>[:PROXY][:PROXY] şeklinde yazılır. Bu örnekte, default namespace’indeki example-go servisine, 8080 portu üzerinden yönlendirme yapılır.

kubectl edit ile ConfigMap Güncelleme

Herhangi bir ConfigMap değişikliği için:

kubectl edit configmap tcp-services -n ingress-nginx

Yeni satır ekledikten veya var olanı değiştirdikten sonra kaydederseniz, Ingress Controller otomatik olarak konfigürasyonu yeniden yükleyecektir.


5. Örnek Uygulama: Deployment ve Service

Aşağıdaki kod, Go tabanlı bir uygulamanın Deployment’ını ve Servis tanımını tek bir YAML içinde gösterir. Bu servis, 8080 portunda dinliyor.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-go
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: example-go
  template:
    metadata:
      labels:
        app: example-go
    spec:
      containers:
      - name: example-go
        image: your-image:latest
        ports:
        - containerPort: 8080

---
apiVersion: v1
kind: Service
metadata:
  name: example-go
  namespace: default
spec:
  selector:
    app: example-go
  ports:
    - name: tcp-echo
      port: 8080
      protocol: TCP

Bu uygulamayı dışarıya 9000 numaralı TCP portundan yönlendirmek için, önce tcp-services ConfigMap’e 9000: "default/example-go:8080" satırını eklemeniz yeterli.


6. Proxy Protokolünü Kullanmak (İsteğe Bağlı)

Orijinal istemci IP’si gibi bilgileri TCP katmanında korumak istiyorsanız, ConfigMap değerinin sonuna :PROXY ekleyebilirsiniz:

data:
  9000: "default/example-go:8080:PROXY"
  • İlk PROXY, gelen bağlantıdan proxy protokolünü decode eder (işlemciye gerçek IP’yi aktarır).
  • İkinci PROXY, isterseniz çıkış trafiğinde proxy protokolü uygulamak içindir (:PROXY:PROXY şeklinde).

7. Sık Karşılaşılan Sorunlar

  1. Port Çakışması: Aynı Service veya başka bir serviste 9000 portu tanımlı olabilir. Farklı bir port seçerek sorun çözülebilir.
  2. Eksik Argümanlar: ingress-nginx Pod’larında --tcp-services-configmap veya --udp-services-configmap tanımlı değilse, ConfigMap verileri işlenmez.
  3. Namespace Uyuşmazlığı: tcp-services ConfigMap, mutlaka Ingress Controller’ın çalıştığı namespace’te (örn. ingress-nginx) olmalı.
  4. kubectl edit Kaydetmeme: Düzenleme yaptığınızda, editörden çıkmadan önce mutlaka değişiklikleri kaydedin.

8. Sonuç

NGINX Ingress Controller ile TCP ya da UDP servislerinizi kolaylıkla dışarıya açabilirsiniz. Bu yaklaşım sayesinde, birden fazla LoadBalancer kaynağı oluşturmadan tüm trafiği tek bir noktadan yönetir, konfigürasyon değişikliklerini de kubectl edit ile hızlıca yapabilirsiniz.

Böylece microservices mimarinizde hem HTTP/HTTPS hem de özel protokolleri tek bir Ingress Controller üzerinden yönetmenin avantajını yaşarsınız.

Kaynaklar ve İleri Okuma:

Sorularınızı yorumlarda paylaşabilirsiniz!