GCP GKE ile Kubernetes Cluster Kurulumu
Google Cloud Platform üzerinde Kubernetes cluster kurmak, ilk kez yapıyorsanız göz korkutucu görünebilir. Ama GKE (Google Kubernetes Engine), managed Kubernetes dünyasında en olgun ve en çok tercih edilen servislerden biri. Google’ın kendi altyapısında çalışıyor, otomatik node yönetimi, otomatik güvenlik yamaları, entegre load balancer desteği… Bunları elle kurmaya çalışsanız günler sürer. Bu yazıda sıfırdan üretim seviyesine yakın bir GKE cluster’ı nasıl kurarsınız, bunu adım adım ve gerçek hayattan örneklerle anlatacağım.
Ön Gereksinimler ve Ortam Hazırlığı
Başlamadan önce birkaç şeyi hazır etmeniz gerekiyor. GCP hesabınız olmalı ve faturalandırma aktif olmalı. Eğer yeni bir hesapsa $300 ücretsiz kredi ile başlıyorsunuz, bu kurulum için fazlasıyla yeterli.
Gerekli araçlar:
- gcloud CLI: Google Cloud komut satırı aracı
- kubectl: Kubernetes komut satırı aracı
- helm (opsiyonel): Kubernetes paket yöneticisi
gcloud CLI kurulumu için:
# Linux için gcloud CLI kurulumu
curl https://sdk.cloud.google.com | bash
exec -l $SHELL
# Kurulumu doğrula
gcloud version
# macOS için Homebrew ile
brew install --cask google-cloud-sdk
Kurulum tamamlandıktan sonra hesabınıza giriş yapıyorsunuz:
# GCP hesabına giriş
gcloud auth login
# Proje oluştur veya mevcut projeyi seç
gcloud projects create my-gke-project-001 --name="GKE Demo Project"
gcloud config set project my-gke-project-001
# Fatura hesabını projeyle ilişkilendir
gcloud billing accounts list
gcloud billing projects link my-gke-project-001
--billing-account=XXXXXX-XXXXXX-XXXXXX
# Gerekli API'leri aktif et
gcloud services enable container.googleapis.com
gcloud services enable compute.googleapis.com
gcloud services enable cloudresourcemanager.googleapis.com
kubectl’i de kuralım:
# gcloud üzerinden kubectl kurulumu (en kolay yol)
gcloud components install kubectl
# veya doğrudan sisteme kur
curl -LO "https://dl.k8s.io/release/$(curl -L -s
https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
kubectl version --client
Network Altyapısını Kurmak
Prodüksiyona yakın bir kurulum için özel bir VPC ağı oluşturmanızı kesinlikle tavsiye ederim. Default VPC ile de çalışır ama özellikle multi-environment (dev, staging, prod) senaryolarında ayrı ağ yapısı hayat kurtarır.
# Özel VPC oluştur
gcloud compute networks create gke-vpc
--subnet-mode=custom
--bgp-routing-mode=regional
# GKE için subnet oluştur
# /20 node'lar için yeterli IP verir (4094 IP)
gcloud compute networks subnets create gke-subnet
--network=gke-vpc
--region=europe-west1
--range=10.0.0.0/20
--secondary-range pod-range=10.16.0.0/14,svc-range=10.20.0.0/20
--enable-private-ip-google-access
# Firewall kuralları
gcloud compute firewall-rules create gke-allow-internal
--network=gke-vpc
--allow=tcp,udp,icmp
--source-ranges=10.0.0.0/8
gcloud compute firewall-rules create gke-allow-health-checks
--network=gke-vpc
--allow=tcp:8080,tcp:443,tcp:80
--source-ranges=130.211.0.0/22,35.191.0.0/16
Secondary range’leri neden tanımladık? GKE’de VPC-native cluster kullanıyorsanız (ki kullanmalısınız), pod’lar ve servisler için ayrı IP aralıkları gerekiyor. Bu yapı, pod’lardan doğrudan diğer VPC servislerine erişimi kolaylaştırıyor ve Network Policy’lerin düzgün çalışmasını sağlıyor.
GKE Cluster Kurulumu
Şimdi asıl işe geliyoruz. Küçük bir dev cluster ile başlayıp ardından production-grade bir cluster oluşturacağız.
Basit Bir Test Cluster’ı
Eğer sadece öğrenmek ve denemek istiyorsanız:
# Basit tek zone cluster (dev/test için)
gcloud container clusters create gke-dev-cluster
--zone=europe-west1-b
--num-nodes=2
--machine-type=e2-medium
--disk-size=50GB
--disk-type=pd-standard
--no-enable-basic-auth
--network=gke-vpc
--subnetwork=gke-subnet
Bu cluster 2-3 dakikada hazır olur. Ama bunu production’da kullanmayın. Tek zone’da çalıştığı için zone’un herhangi bir sorunu yaşaması cluster’ınızı etkiler.
Production-Grade Cluster Kurulumu
Gerçek bir prodüksiyon ortamı için çok daha fazla parametre düşünmeniz gerekiyor:
gcloud container clusters create gke-prod-cluster
--region=europe-west1
--node-locations=europe-west1-b,europe-west1-c,europe-west1-d
--num-nodes=2
--machine-type=e2-standard-4
--disk-size=100GB
--disk-type=pd-ssd
--network=gke-vpc
--subnetwork=gke-subnet
--cluster-secondary-range-name=pod-range
--services-secondary-range-name=svc-range
--enable-ip-alias
--enable-private-nodes
--master-ipv4-cidr=172.16.0.0/28
--enable-master-authorized-networks
--master-authorized-networks=YOUR_IP/32
--enable-network-policy
--enable-shielded-nodes
--shielded-secure-boot
--shielded-integrity-monitoring
--workload-pool=my-gke-project-001.svc.id.goog
--enable-autoscaling
--min-nodes=1
--max-nodes=5
--enable-autorepair
--enable-autoupgrade
--maintenance-window-start=2024-01-01T02:00:00Z
--maintenance-window-end=2024-01-01T06:00:00Z
--maintenance-window-recurrence="FREQ=WEEKLY;BYDAY=SA,SU"
--addons=HorizontalPodAutoscaling,HttpLoadBalancing,GcePersistentDiskCsiDriver
--logging=SYSTEM,WORKLOAD
--monitoring=SYSTEM
--release-channel=regular
Bu komuttaki kritik parametreleri açıklayalım:
–enable-private-nodes: Node’ların public IP almadığı anlamına gelir. Bu büyük bir güvenlik kazanımı. Node’larınız internete doğrudan açık olmaz.
–enable-master-authorized-networks: Kubernetes API’sine sadece belirttiğiniz IP’lerden erişilir. Ofis IP’nizi veya VPN IP’nizi koyun buraya.
–workload-pool: Workload Identity aktif eder. Service account key dosyası olmadan pod’ların GCP servislerine erişmesini sağlar. Güvenlik açısından çok önemli.
–release-channel regular: Stabil ama çok eski olmayan versiyonları otomatik alırsınız. Rapid kanalı daha yeni özellikleri daha hızlı getirir ama daha az stabil olabilir.
–maintenance-window: Otomatik güncellemelerin hafta sonu gece yapılmasını sağlıyoruz. Bunu mutlaka ayarlayın, yoksa iş saatlerinde update yiyebilirsiniz.
kubectl Bağlantısını Yapılandırma
Cluster hazır olduğunda kubeconfig dosyanızı güncellemeniz gerekiyor:
# Cluster credentials'ını al
gcloud container clusters get-credentials gke-prod-cluster
--region=europe-west1
--project=my-gke-project-001
# Bağlantıyı test et
kubectl get nodes
kubectl get namespaces
# Cluster bilgilerini gör
kubectl cluster-info
# Context'leri listele (birden fazla cluster varsa)
kubectl config get-contexts
# Context değiştir
kubectl config use-context gke_my-gke-project-001_europe-west1_gke-prod-cluster
Private cluster kullanıyorsanız (ki kullanıyorsunuz) kubectl erişimi için VPN veya Cloud Shell gerekebilir. Alternatif olarak master authorized networks’e kendi IP’nizi ekleyebilirsiniz:
# Kendi IP'nizi öğrenin
MY_IP=$(curl -s ifconfig.me)
# Master authorized networks'e ekle
gcloud container clusters update gke-prod-cluster
--region=europe-west1
--enable-master-authorized-networks
--master-authorized-networks=${MY_IP}/32
Node Pool Yönetimi
GKE’nin güçlü özelliklerinden biri farklı tipte workload’lar için farklı node pool’ları kullanabilmek. Mesela web uygulamalarınız için genel amaçlı node’lar, ML işleri için GPU node’lar, batch işler için spot/preemptible node’lar kullanabilirsiniz.
# Spot instance node pool ekle (batch işler, maliyet optimizasyonu için)
gcloud container node-pools create spot-pool
--cluster=gke-prod-cluster
--region=europe-west1
--machine-type=e2-standard-4
--num-nodes=0
--enable-autoscaling
--min-nodes=0
--max-nodes=10
--spot
--node-taints=workload=batch:NoSchedule
--node-labels=workload=batch
# GPU node pool ekle (ML workload'ları için)
gcloud container node-pools create gpu-pool
--cluster=gke-prod-cluster
--region=europe-west1
--machine-type=n1-standard-4
--accelerator=type=nvidia-tesla-t4,count=1
--num-nodes=0
--enable-autoscaling
--min-nodes=0
--max-nodes=4
--node-taints=gpu=true:NoSchedule
# Node pool listele
gcloud container node-pools list
--cluster=gke-prod-cluster
--region=europe-west1
Spot instance pool’a workload schedule etmek için pod spec’inizde toleration tanımlamanız gerekiyor:
# Örnek deployment manifest'i oluştur
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: batch-worker
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: batch-worker
template:
metadata:
labels:
app: batch-worker
spec:
tolerations:
- key: "workload"
operator: "Equal"
value: "batch"
effect: "NoSchedule"
nodeSelector:
workload: batch
containers:
- name: worker
image: busybox:latest
command: ["sh", "-c", "echo Batch job running && sleep 300"]
resources:
requests:
cpu: "500m"
memory: "256Mi"
limits:
cpu: "1000m"
memory: "512Mi"
EOF
Namespace ve RBAC Yapılandırması
Cluster’ınızı namespace’lere bölmek hem izolasyon hem de yönetim kolaylığı sağlar. Tipik bir kurumsal yapıda şöyle bir namespace organizasyonu kullanabiliriz:
# Namespace'leri oluştur
kubectl create namespace production
kubectl create namespace staging
kubectl create namespace monitoring
kubectl create namespace ingress-nginx
# Label ekle
kubectl label namespace production environment=production
kubectl label namespace staging environment=staging
# Ekip için service account ve role binding oluştur
kubectl create serviceaccount dev-team -n staging
kubectl create role staging-deployer
--namespace=staging
--verb=get,list,watch,create,update,patch,delete
--resource=deployments,pods,services,configmaps
kubectl create rolebinding dev-team-binding
--namespace=staging
--role=staging-deployer
--serviceaccount=staging:dev-team
# Namespace'e resource quota koy
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ResourceQuota
metadata:
name: staging-quota
namespace: staging
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
pods: "20"
services: "10"
EOF
Ingress ve Load Balancer Kurulumu
NGINX Ingress Controller, GKE’de en yaygın kullanılan ingress çözümlerinden biri. Helm ile kurmak en pratik yol:
# Helm kur (eğer yoksa)
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# NGINX Ingress Controller kur
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx
--namespace ingress-nginx
--create-namespace
--set controller.replicaCount=2
--set controller.nodeSelector."kubernetes.io/os"=linux
--set controller.service.type=LoadBalancer
--set controller.metrics.enabled=true
--set controller.podAnnotations."prometheus.io/scrape"="true"
--set controller.podAnnotations."prometheus.io/port"="10254"
# Load Balancer IP'sini bekle
kubectl get svc ingress-nginx-controller -n ingress-nginx -w
# Örnek Ingress kaynağı oluştur
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
namespace: production
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
EOF
Monitoring ve Logging
GKE, Cloud Monitoring ve Cloud Logging ile entegre geliyor. Ama çoğu ekip ayrıca Prometheus/Grafana stack’i de kuruyor. İkisini birlikte kullanmak en iyi sonucu veriyor:
# kube-prometheus-stack kur (Prometheus + Grafana + AlertManager)
helm repo add prometheus-community
https://prometheus-community.github.io/helm-charts
helm repo update
helm install kube-prometheus prometheus-community/kube-prometheus-stack
--namespace monitoring
--create-namespace
--set grafana.adminPassword=SecurePassword123
--set prometheus.prometheusSpec.retention=15d
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.storageClassName=standard-rwo
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage=50Gi
# Grafana'ya erişim için port-forward
kubectl port-forward -n monitoring svc/kube-prometheus-grafana 3000:80
# Prometheus metrics kontrol
kubectl port-forward -n monitoring svc/kube-prometheus-kube-prome-prometheus 9090:9090
GCP Cloud Monitoring için özel bir alert policy oluşturalım:
# Node CPU kullanım alerti (gcloud ile)
gcloud alpha monitoring policies create
--notification-channels=CHANNEL_ID
--display-name="GKE Node CPU High"
--condition-display-name="CPU above 80%"
--condition-filter='resource.type="k8s_node" AND metric.type="kubernetes.io/node/cpu/allocatable_utilization"'
--condition-threshold-value=0.8
--condition-threshold-comparison=COMPARISON_GT
--condition-duration=300s
Workload Identity ile GCP Servis Entegrasyonu
Pod’larınızın Cloud Storage, BigQuery veya başka GCP servislerine erişmesi gerekiyorsa Workload Identity kullanmanız şart. Service account JSON dosyası kullanmak güvenlik açığı yaratır.
# GCP Service Account oluştur
gcloud iam service-accounts create gke-app-sa
--display-name="GKE Application Service Account"
# Gerekli rolleri ver (örnek: Cloud Storage okuma)
gcloud projects add-iam-policy-binding my-gke-project-001
--member="serviceAccount:[email protected]"
--role="roles/storage.objectViewer"
# Kubernetes service account oluştur
kubectl create serviceaccount app-ksa -n production
# İki service account'ı birbirine bağla (Workload Identity binding)
gcloud iam service-accounts add-iam-policy-binding
[email protected]
--role=roles/iam.workloadIdentityUser
--member="serviceAccount:my-gke-project-001.svc.id.goog[production/app-ksa]"
# Kubernetes service account'a annotation ekle
kubectl annotate serviceaccount app-ksa
--namespace=production
iam.gke.io/gcp-service-account=gke-app-sa@my-gke-project-001.iam.gserviceaccount.com
# Artık pod'ları bu service account ile çalıştırın
# spec.serviceAccountName: app-ksa
Cluster Bakımı ve Güncelleme
GKE’de cluster versiyonunu güncel tutmak hem güvenlik hem de yeni özellikler açısından kritik. Release channel kullanıyorsanız GCP bunu otomatik yapıyor, ama manuel kontrol de önemli:
# Mevcut cluster versiyonunu ve uygun upgrade versiyonlarını gör
gcloud container clusters describe gke-prod-cluster
--region=europe-west1
--format="value(currentMasterVersion,currentNodeVersion)"
# Kullanılabilir versiyonları listele
gcloud container get-server-config
--region=europe-west1
--format="yaml(validMasterVersions[0:5])"
# Master'ı manuel upgrade et
gcloud container clusters upgrade gke-prod-cluster
--region=europe-west1
--master
--cluster-version=1.28.5-gke.1000
# Node pool upgrade et (rolling update yapar)
gcloud container clusters upgrade gke-prod-cluster
--region=europe-west1
--node-pool=default-pool
# Cluster'ı yeniden boyutlandır
gcloud container clusters resize gke-prod-cluster
--region=europe-west1
--node-pool=default-pool
--num-nodes=3
Maliyet optimizasyonu açısından önemli bir ipucu: Geliştirme ortamınızı geceleri ve hafta sonları kapatmak için aşağıdaki yaklaşımı kullanabilirsiniz:
# Dev cluster'ı node sayısını 0'a indir (cluster silinmez, sadece node'lar durur)
gcloud container clusters resize gke-dev-cluster
--zone=europe-west1-b
--node-pool=default-pool
--num-nodes=0
# Sabah tekrar ayağa kaldır
gcloud container clusters resize gke-dev-cluster
--zone=europe-west1-b
--node-pool=default-pool
--num-nodes=2
Bu işlemi Cloud Scheduler + Cloud Functions ile otomatize etmek mümkün ve aylık maliyetinizi ciddi ölçüde düşürür.
Yaygın Sorunlar ve Çözümleri
Gerçek hayatta en sık karşılaştığım birkaç sorunu paylaşayım:
Pod’lar Pending durumunda kalıyor: Çoğunlukla resource yetersizliği. kubectl describe pod POD_NAME komutunu çalıştırın, Events bölümüne bakın. Node’larda yeterli CPU/Memory yoksa cluster autoscaler devreye girmeli, girmiyorsa min/max node sayılarını kontrol edin.
ImagePullBackOff hatası: Private registry kullanıyorsanız imagePullSecrets tanımlamamışsınızdır. Workload Identity ile GCR veya Artifact Registry’ye erişim için node service account’a roles/artifactregistry.reader rolü verin.
DNS çözümleme sorunları: CoreDNS pod’larını kontrol edin, kubectl get pods -n kube-system | grep coredns. Yeniden başlatmak genellikle işe yarar ama kök nedeni araştırın.
Yüksek egress maliyeti: GKE’de pod’lar farklı zone’lardaki servislerle konuşunca inter-zone trafik ücreti oluşuyor. Topology Aware Routing aktif ederek bu maliyeti azaltabilirsiniz.
Sonuç
GKE, managed Kubernetes deneyimi açısından piyasadaki en olgun çözümlerden biri. Bu yazıda anlattığım adımları takip ederek hem güvenli hem de ölçeklenebilir bir cluster ortamı kurabilirsiniz.
Özetlemek gerekirse en önemli noktalar şunlar: Private cluster ve Workload Identity kullanarak güvenlik temelini sağlam atın. Node pool’ları workload tipine göre ayırarak hem maliyet hem de performans optimize edin. Maintenance window tanımlayın, release channel’ı regular olarak bırakın ve güncellemeleri GCP’nin otomatik yapmasına izin verin. Namespace’leri ve resource quota’ları ihmal etmeyin, bunlar büyüyen ekiplerde hayat kurtarıyor.
Bir sonraki adım olarak GitOps yaklaşımıyla Argo CD veya Flux kurulumuna, ya da Cloud Armor ile WAF entegrasyonuna bakabilirsiniz. GKE ekosistemi gerçekten çok geniş, her yazıda yeni bir katman keşfediyorsunuz.
