DevOps & Cloud
Kubernetes ile Mikroservis Mimarisi: Pod, Service ve Deployment
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.
# 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: AlwaysDeployment: 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.
# 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: 80ConfigMap 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:
# 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-stringConfigMap 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:
# 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: 50GiStatefulSet, 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:
# 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
EOFResourceQuota 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:
# 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: 30Prometheus ile Monitoring
Kubernetes ortaminda Prometheus, metrik toplama ve izleme icin standart cozumdur. ServiceMonitor ile uygulama metriklerini otomatik olarak kesfedebilirsiniz:
# 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.
# 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: 70Helm ile deployment:
# 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 productionMikroservis 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:
- Resource limits: Her container icin CPU ve bellek sinirlari mutlaka tanimlayin
- Health probes: Liveness, readiness ve startup probe'lari dogru yapilandirin
- Pod anti-affinity: Pod'lari farkli node'lara dagitarak yuksek erisilebilirlik saglayin
- Namespace izolasyonu: Ortamlari (dev, staging, prod) namespace'lerle ayirin
- 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
.NET ile Mikroservis Mimarisi: Tasarım ve Uygulama
.NET ile mikroservis mimarisi tasarlayın. Service communication, Docker ve orchestration stratejileri.
Docker Konteyner Rehberi: Dockerfile, Compose ve Multi-Stage Build
Docker ile konteynerleştirme rehberi. Dockerfile yazma, Docker Compose ile çoklu servis, multi-stage build optimizasyonu ve production deployment.
CI/CD Pipeline: GitHub Actions ile Otomatik Test ve Deployment
GitHub Actions ile CI/CD pipeline kurulumu. Otomatik test, build, Docker image oluşturma ve AWS'e deployment.
Flutter Projeniz mi Var?
iOS, Android ve web için yüksek performanslı Flutter uygulamaları geliştiriyorum.
İletişime Geç