DevOps & Cloud

Kubernetes ile Mikroservis Mimarisi: Pod, Service ve Deployment

15 dk okuma17 Mart 2026
Kubernetes rehberiKubernetes tutorialMikroservisMicroservicesKubernetes podKubernetes deploymentKubernetes serviceHelm chartContainer orchestrationKubernetes .NET

Kubernetes (K8s), container orchestration alaninda fiili standart haline gelmis acik kaynakli bir platformdur. Mikroservis mimarilerinde uygulamalarin deployment, olceklendirme ve yonetimini otomatize eder. Bu yazida Kubernetes'in temel bilesenlerini, mikroservis deployment stratejilerini ve Helm ile paket yonetimini detayli olarak inceleyecegim.

Kendi projelerimde Kubernetes'e gecis yaptigimdan beri zero-downtime deployment, otomatik olceklendirme ve self-healing ozellikleri sayesinde production ortamlarinin guvenilirligi onemli olcude artti. Dogru yapilandirilmis bir K8s cluster'i, operasyonel yuku buyuk olcude azaltir.

Kubernetes Temel Bilesenler

Pod: En Kucuk Deployment Birimi

Pod, Kubernetes'teki en kucuk ve en temel birimdir. Bir veya daha fazla container'i, paylasilan depolama ve ag kaynaklarini icerir.

yaml
# pod.yaml - Temel pod tanimi
apiVersion: v1
kind: Pod
metadata:
  name: api-server
  labels:
    app: myapi
    version: v1
    environment: production
spec:
  containers:
    - name: api
      image: ghcr.io/myorg/myapi:1.0.0
      ports:
        - containerPort: 8080
          protocol: TCP
      env:
        - name: ASPNETCORE_ENVIRONMENT
          value: "Production"
        - name: ConnectionStrings__DefaultConnection
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: connection-string
      resources:
        requests:
          cpu: "250m"
          memory: "256Mi"
        limits:
          cpu: "500m"
          memory: "512Mi"
      livenessProbe:
        httpGet:
          path: /health/live
          port: 8080
        initialDelaySeconds: 15
        periodSeconds: 20
      readinessProbe:
        httpGet:
          path: /health/ready
          port: 8080
        initialDelaySeconds: 5
        periodSeconds: 10
      startupProbe:
        httpGet:
          path: /health/startup
          port: 8080
        failureThreshold: 30
        periodSeconds: 10
  restartPolicy: Always

Deployment: Bildirimsel Guncelleme Yonetimi

Deployment, Pod'larin istenen durumunu tanimlar ve guncelleme stratejilerini yonetir. ReplicaSet'leri otomatik olusturur ve rolling update ile zero-downtime deployment saglar.

yaml
# deployment.yaml - Production-ready deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapi-deployment
  labels:
    app: myapi
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapi
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: myapi
        version: v1
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchExpressions:
                    - key: app
                      operator: In
                      values:
                        - myapi
                topologyKey: kubernetes.io/hostname
      containers:
        - name: api
          image: ghcr.io/myorg/myapi:1.0.0
          ports:
            - containerPort: 8080
          envFrom:
            - configMapRef:
                name: myapi-config
            - secretRef:
                name: myapi-secrets
          resources:
            requests:
              cpu: "250m"
              memory: "256Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
          livenessProbe:
            httpGet:
              path: /health/live
              port: 8080
            initialDelaySeconds: 15
            periodSeconds: 20
          readinessProbe:
            httpGet:
              path: /health/ready
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
---
# service.yaml - ClusterIP ve LoadBalancer
apiVersion: v1
kind: Service
metadata:
  name: myapi-service
spec:
  selector:
    app: myapi
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
  type: ClusterIP
---
# Ingress - Dis erisim icin
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapi-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/rate-limit: "100"
    nginx.ingress.kubernetes.io/rate-limit-window: "1m"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - api.example.com
      secretName: api-tls-cert
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myapi-service
                port:
                  number: 80

ConfigMap ve Secret Yonetimi

Uygulama yapilandirmalarini ve hassas verileri konteyner imajindan ayirmak, Kubernetes'in temel prensiplerinden biridir. ConfigMap ortam degiskenleri ve yapilandirma dosyalari icin, Secret ise sifre ve API anahtarlari gibi hassas veriler icin kullanilir:

yaml
# configmap.yaml - Uygulama yapilandirmasi
apiVersion: v1
kind: ConfigMap
metadata:
  name: myapi-config
  namespace: production
data:
  ASPNETCORE_ENVIRONMENT: "Production"
  Logging__LogLevel__Default: "Information"
  AllowedOrigins: "https://example.com,https://www.example.com"
  Cache__DefaultExpirationMinutes: "30"
  FeatureFlags__NewDashboard: "true"
---
# secret.yaml - Hassas veriler (base64 encoded)
apiVersion: v1
kind: Secret
metadata:
  name: myapi-secrets
  namespace: production
type: Opaque
data:
  ConnectionStrings__DefaultConnection: SG9zdD1wb3N0Z3Jlczt...
  Redis__ConnectionString: cmVkaXM6NjM3OQ==
  JWT__SecretKey: c3VwZXItc2VjcmV0LWtleQ==
---
# External Secrets ile vault entegrasyonu (onerilen)
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: myapi-external-secrets
  namespace: production
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: ClusterSecretStore
  target:
    name: myapi-secrets
  data:
    - secretKey: ConnectionStrings__DefaultConnection
      remoteRef:
        key: myapi/production
        property: db-connection-string

ConfigMap ve Secret degisikliklerinin pod'lara yansimasi icin deployment'i yeniden baslatmak gerekir. Bu islemi otomatize etmek icin Reloader gibi araclar veya Helm hook'lari kullanabilirsiniz.

PersistentVolumeClaim ile Veri Kaliciligi

Stateful uygulamalar (veritabanlari, dosya depolama) icin PersistentVolumeClaim kullanarak kalici depolama talep edebilirsiniz:

yaml
# pvc.yaml - Kalici depolama talebi
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-data-pvc
  namespace: production
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: gp3
  resources:
    requests:
      storage: 50Gi
---
# StatefulSet ile veritabani deployment'i
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
  namespace: production
spec:
  serviceName: postgres
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:16-alpine
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_DB
              value: "myapp"
            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef:
                  name: postgres-credentials
                  key: username
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgres-credentials
                  key: password
          volumeMounts:
            - name: postgres-storage
              mountPath: /var/lib/postgresql/data
          resources:
            requests:
              cpu: "500m"
              memory: "1Gi"
            limits:
              cpu: "1"
              memory: "2Gi"
  volumeClaimTemplates:
    - metadata:
        name: postgres-storage
      spec:
        accessModes: ["ReadWriteOnce"]
        storageClassName: gp3
        resources:
          requests:
            storage: 50Gi

StatefulSet, veritabani gibi stateful uygulamalar icin Deployment'dan daha uygun bir secimdir. Her pod'a sabit bir kimlik ve kalici depolama atayarak veri butunlugunu korur.

Namespace ile Ortam Izolasyonu

Namespace'ler, cluster kaynaklarini mantiksal olarak ayirmak icin kullanilir. Farkli ortamlar (dev, staging, production) ve farkli takimlar icin izolasyon saglar:

bash
# Namespace olustur
kubectl create namespace production
kubectl create namespace staging
kubectl create namespace development

# Namespace bazli kaynak kotasi
kubectl apply -f - <<EOF
apiVersion: v1
kind: ResourceQuota
metadata:
  name: production-quota
  namespace: production
spec:
  hard:
    requests.cpu: "8"
    requests.memory: "16Gi"
    limits.cpu: "16"
    limits.memory: "32Gi"
    pods: "50"
    services: "20"
EOF

# Namespace bazli network policy
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: production
EOF

ResourceQuota ile her namespace'in kullanabilecegi kaynaklari sinirlandirabilir, NetworkPolicy ile namespace'ler arasi trafigi kontrol edebilirsiniz.

Horizontal Pod Autoscaler

Trafik artislarina otomatik olarak yanit vermek icin HPA kullanilir:

yaml
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapi-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapi-deployment
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 25
          periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 30
      policies:
        - type: Percent
          value: 100
          periodSeconds: 30

Prometheus ile Monitoring

Kubernetes ortaminda Prometheus, metrik toplama ve izleme icin standart cozumdur. ServiceMonitor ile uygulama metriklerini otomatik olarak kesfedebilirsiniz:

yaml
# servicemonitor.yaml - Prometheus ile uygulama izleme
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: myapi-monitor
  namespace: production
  labels:
    release: prometheus
spec:
  selector:
    matchLabels:
      app: myapi
  endpoints:
    - port: http
      path: /metrics
      interval: 30s
      scrapeTimeout: 10s
---
# PrometheusRule ile alarm tanimlama
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: myapi-alerts
  namespace: production
spec:
  groups:
    - name: myapi.rules
      rules:
        - alert: HighErrorRate
          expr: |
            rate(http_requests_total{status=~"5..", app="myapi"}[5m])
            / rate(http_requests_total{app="myapi"}[5m]) > 0.05
          for: 5m
          labels:
            severity: critical
          annotations:
            summary: "Yuksek hata orani tespit edildi"
            description: "Son 5 dakikada hata orani %5'in uzerinde"
        - alert: HighLatency
          expr: |
            histogram_quantile(0.95, rate(http_request_duration_seconds_bucket{app="myapi"}[5m])) > 1
          for: 5m
          labels:
            severity: warning
          annotations:
            summary: "Yuksek yanit suresi tespit edildi"

Prometheus + Grafana kombinasyonu ile CPU, bellek, HTTP istek sayisi, hata oranlari ve response time gibi metrikleri gorsellestirebilir ve alarm kurallari tanimlayabilirsiniz.

Helm ile Paket Yonetimi

Helm Chart Yapisi

Helm, Kubernetes uygulamalarinin paketlenmesi ve dagitilmasi icin kullanilan bir paket yoneticisidir.

yaml
# Chart.yaml
apiVersion: v2
name: myapi
description: My API Helm Chart
version: 1.0.0
appVersion: "1.0.0"

# values.yaml - Varsayilan degerler
replicaCount: 3

image:
  repository: ghcr.io/myorg/myapi
  tag: "1.0.0"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: true
  host: api.example.com
  tls: true

resources:
  requests:
    cpu: 250m
    memory: 256Mi
  limits:
    cpu: 500m
    memory: 512Mi

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilization: 70

Helm ile deployment:

bash
# Chart kurulumu
helm install myapi ./charts/myapi -f values-production.yaml -n production

# Guncelleme
helm upgrade myapi ./charts/myapi -f values-production.yaml -n production

# Rollback
helm rollback myapi 1 -n production

# Durum kontrolu
helm status myapi -n production

Mikroservis Iletisim Patternleri

Kubernetes ortaminda mikroservisler arasi iletisim icin:

  • ClusterIP Service: Cluster ici senkron HTTP/gRPC iletisimi
  • Headless Service: Service discovery icin DNS tabanli cozum
  • Service Mesh (Istio/Linkerd): mTLS, traffic management, observability
  • Message Queue: RabbitMQ veya Kafka ile asenkron iletisim

Pratik Oneriler ve Ozet

Kubernetes ile mikroservis yonetiminde su noktalara dikkat edin:

  1. Resource limits: Her container icin CPU ve bellek sinirlari mutlaka tanimlayin
  2. Health probes: Liveness, readiness ve startup probe'lari dogru yapilandirin
  3. Pod anti-affinity: Pod'lari farkli node'lara dagitarak yuksek erisilebilirlik saglayin
  4. Namespace izolasyonu: Ortamlari (dev, staging, prod) namespace'lerle ayirin
  5. GitOps: ArgoCD veya Flux ile deklaratif deployment yonetimi uygulayin

Kubernetes, dogru yapilandirildiginda mikroservis mimarilerinin olceklendirme, guvenilirlik ve yonetim sorunlarini buyuk olcude cozer. Kucuk baslayip ihtiyaca gore buyutmek en saglikli yaklasimdir.

İlgili Makaleler

Flutter Projeniz mi Var?

iOS, Android ve web için yüksek performanslı Flutter uygulamaları geliştiriyorum.

İletişime Geç