GCP Cloud Storage ile Nesne Depolama Yönetimi

Bulut altyapısı yönetirken en çok zaman harcadığım konulardan biri nesne depolama. AWS S3 ile uzun yıllar çalıştıktan sonra GCP Cloud Storage’a geçiş yaptığımda bazı kavramlar çok benzer gelse de, GCP’nin kendine özgü güçlü yanlarını keşfetmek biraz zaman aldı. Bu yazıda Cloud Storage’ı production ortamında kullanırken öğrendiğim pratik bilgileri, gerçek senaryolar üzerinden paylaşacağım.

Cloud Storage Temelleri ve Bucket Yapısı

GCP Cloud Storage, Google’ın global olarak dağıtılmış nesne depolama servisidir. Dosyaları “bucket” adı verilen konteynerler içinde “object” olarak saklarsınız. Bir bucket oluştururken en kritik karar depolama sınıfı ve lokasyon seçimidir.

Depolama sınıfları şu şekilde sıralanır:

  • Standard: Sık erişilen veriler için, en yüksek performans
  • Nearline: Ayda bir veya daha az erişilen veriler, 30 günlük minimum saklama
  • Coldline: Üç ayda bir veya daha az erişilen veriler, 90 günlük minimum saklama
  • Archive: Yılda bir veya daha az erişilen veriler, 365 günlük minimum saklama

Lokasyon seçenekleri de performans ve maliyet dengesini doğrudan etkiler:

  • Multi-region: us, eu, asia gibi geniş coğrafi bölgeler, yüksek erişilebilirlik
  • Dual-region: İki belirli bölge arasında veri replikasyonu
  • Region: Tek bir coğrafi bölge, düşük gecikme ve düşük maliyet

gsutil CLI aracı veya gcloud storage komutu ile bucket yönetimi yapabilirsiniz. Modern GCP dokümantasyonu artık gcloud storage komutunu öneriyor çünkü daha hızlı ve daha tutarlı.

# Yeni bucket oluşturma
gcloud storage buckets create gs://sirket-uygulama-prod 
  --location=europe-west1 
  --storage-class=STANDARD 
  --uniform-bucket-level-access

# Bucket listesi
gcloud storage buckets list

# Bucket detayları
gcloud storage buckets describe gs://sirket-uygulama-prod

# Nearline bucket oluşturma - backup için ideal
gcloud storage buckets create gs://sirket-backup-nearline 
  --location=europe-west1 
  --storage-class=NEARLINE 
  --uniform-bucket-level-access

IAM ve Erişim Kontrolü

Cloud Storage’da erişim kontrolü için iki farklı yaklaşım mevcut: Uniform Bucket-Level Access ve Fine-Grained Access. Google artık güvenlik açısından Uniform erişimi şiddetle tavsiye ediyor. Fine-grained access, eski ACL (Access Control List) sistemine dayanıyor ve yönetmesi gerçekten baş ağrısına yol açabiliyor.

Uniform bucket-level access etkinleştirildiğinde tüm erişim kontrolü Cloud IAM üzerinden yapılıyor. Bu çok daha şeffaf ve yönetimi kolay bir yapı sunuyor.

# Service account oluşturma
gcloud iam service-accounts create storage-app-sa 
  --display-name="Storage Application Service Account"

# Bucket üzerinde belirli bir service account'a okuma izni verme
gcloud storage buckets add-iam-policy-binding gs://sirket-uygulama-prod 
  --member="serviceAccount:[email protected]" 
  --role="roles/storage.objectViewer"

# Yazma izni için
gcloud storage buckets add-iam-policy-binding gs://sirket-uygulama-prod 
  --member="serviceAccount:[email protected]" 
  --role="roles/storage.objectUser"

# Mevcut IAM policy görüntüleme
gcloud storage buckets get-iam-policy gs://sirket-uygulama-prod

# IAM izni kaldırma
gcloud storage buckets remove-iam-policy-binding gs://sirket-uygulama-prod 
  --member="serviceAccount:[email protected]" 
  --role="roles/storage.objectViewer"

Prodüksiyon ortamında en az yetki prensibini uygulamak çok önemli. Bir uygulamanın sadece okuma yapması gerekiyorsa objectViewer, hem okuma hem yazma yapması gerekiyorsa objectUser rolü yeterli. objectAdmin ve admin rollerini sadece gerçekten gerektiğinde verin.

Nesne Yükleme, İndirme ve Yönetimi

Günlük operasyonlarda en çok kullandığım komutlar dosya transfer komutları. gcloud storage komutu paralel transfer desteği ve daha iyi hata yönetimiyle gsutil‘den ciddi şekilde daha hızlı çalışıyor.

# Tek dosya yükleme
gcloud storage cp /tmp/rapor.pdf gs://sirket-uygulama-prod/raporlar/

# Dizin yükleme (recursive)
gcloud storage cp -r /var/www/html/assets gs://sirket-uygulama-prod/

# Büyük dosyaları paralel yükleme
gcloud storage cp /backup/buyuk-dump.sql.gz gs://sirket-backup-nearline/db-backups/

# Rsync benzeri senkronizasyon - sadece değişen dosyaları gönderir
gcloud storage rsync -r /var/backups gs://sirket-backup-nearline/sunucu-backuplari/

# Silinen dosyaları da senkronize etmek için -d flag
gcloud storage rsync -r -d /var/www/html gs://sirket-static-site/

# Bucket içindeki nesneleri listeleme
gcloud storage ls gs://sirket-uygulama-prod/

# Detaylı liste (boyut ve tarih dahil)
gcloud storage ls -l gs://sirket-uygulama-prod/raporlar/

# Nesne indirme
gcloud storage cp gs://sirket-uygulama-prod/raporlar/rapor.pdf /tmp/

# Nesne silme
gcloud storage rm gs://sirket-uygulama-prod/eski-dosya.txt

# Wildcard ile toplu silme
gcloud storage rm gs://sirket-uygulama-prod/temp/**

Büyük veri transferlerinde --parallel-composite-upload-threshold flag’ini kullanmak transfer hızını önemli ölçüde artırıyor. 150 MB üzeri dosyalarda composite upload otomatik devreye giriyor ama bu eşiği kendiniz de ayarlayabilirsiniz.

Object Versioning ve Lifecycle Yönetimi

Production ortamında kritik verileri korumak için versioning mutlaka açık olmalı. Yanlışlıkla silinen veya üzerine yazılan dosyaları kurtarmak için hayat kurtarıcı bir özellik.

# Bucket üzerinde versioning aktifleştirme
gcloud storage buckets update gs://sirket-uygulama-prod 
  --versioning

# Versioning durumunu kontrol etme
gcloud storage buckets describe gs://sirket-uygulama-prod 
  --format="value(versioning)"

# Tüm versiyonları listeleme
gcloud storage ls -a gs://sirket-uygulama-prod/

# Belirli bir versiyonu indirme (generation numarası ile)
gcloud storage cp 
  "gs://sirket-uygulama-prod/config.json#1698765432123456" 
  /tmp/config-eski.json

Lifecycle kuralları ise maliyetleri kontrol altında tutmanın en etkili yöntemi. Eski dosyaları otomatik olarak daha ucuz depolama sınıfına taşıyabilir veya silebilirsiniz.

Lifecycle kurallarını JSON formatında tanımlamanız gerekiyor:

# lifecycle.json dosyası oluşturun
cat > /tmp/lifecycle.json << 'EOF'
{
  "lifecycle": {
    "rule": [
      {
        "action": {
          "type": "SetStorageClass",
          "storageClass": "NEARLINE"
        },
        "condition": {
          "age": 30,
          "matchesStorageClass": ["STANDARD"]
        }
      },
      {
        "action": {
          "type": "SetStorageClass",
          "storageClass": "COLDLINE"
        },
        "condition": {
          "age": 90,
          "matchesStorageClass": ["NEARLINE"]
        }
      },
      {
        "action": {
          "type": "Delete"
        },
        "condition": {
          "age": 365,
          "matchesStorageClass": ["COLDLINE"]
        }
      },
      {
        "action": {
          "type": "Delete"
        },
        "condition": {
          "numNewerVersions": 3,
          "isLive": false
        }
      }
    ]
  }
}
EOF

# Lifecycle kurallarını bucket'a uygulama
gsutil lifecycle set /tmp/lifecycle.json gs://sirket-uygulama-prod

# Mevcut lifecycle kurallarını görüntüleme
gsutil lifecycle get gs://sirket-uygulama-prod

Bu lifecycle kuralı şunu yapıyor: Dosyalar 30 gün sonra Nearline’a, 90 gün sonra Coldline’a taşınıyor ve 365 gün sonra siliniyor. Ayrıca 3’ten fazla eski versiyonu olan noncurrent objeler de temizleniyor. Bu tür bir yapı özellikle log arşivlemede çok işe yarıyor.

Gerçek Dünya Senaryosu: Otomatik Backup Sistemi

Bir e-ticaret müşterisinde kurduğumuz veritabanı backup sistemini paylaşayım. Her gece PostgreSQL dump alınıp Cloud Storage’a yükleniyor ve lifecycle kuralları ile otomatik arşivleniyor.

#!/bin/bash
# /usr/local/bin/backup-to-gcs.sh

set -euo pipefail

TIMESTAMP=$(date +%Y%m%d_%H%M%S)
DB_NAME="eticaret_prod"
BACKUP_FILE="/tmp/backup_${DB_NAME}_${TIMESTAMP}.sql.gz"
GCS_BUCKET="gs://sirket-backup-nearline"
GCS_PATH="${GCS_BUCKET}/postgresql/${DB_NAME}/"
LOG_FILE="/var/log/gcs-backup.log"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

log "Backup basliyor: ${DB_NAME}"

# PostgreSQL dump alma
PGPASSWORD="${DB_PASSWORD}" pg_dump 
    -h localhost 
    -U postgres 
    -d "${DB_NAME}" 
    --verbose 
    --format=custom 
    | gzip > "${BACKUP_FILE}"

BACKUP_SIZE=$(du -sh "${BACKUP_FILE}" | cut -f1)
log "Dump tamamlandi. Boyut: ${BACKUP_SIZE}"

# GCS'e yükleme
gcloud storage cp "${BACKUP_FILE}" "${GCS_PATH}" 
    --gzip-in-flight-all

log "GCS yüklemesi tamamlandi: ${GCS_PATH}$(basename ${BACKUP_FILE})"

# Lokal geçici dosyayı temizle
rm -f "${BACKUP_FILE}"

# Son 7 günün backup listesini logla
log "Mevcut backuplar:"
gcloud storage ls -l "${GCS_PATH}" | tail -10 >> "${LOG_FILE}"

log "Backup tamamlandi"

Bu script’i cron’a ekliyoruz:

# Crontab'a ekleme
echo "0 2 * * * /usr/local/bin/backup-to-gcs.sh" | crontab -

# Service account key'ini ortam değişkeni olarak ayarlama
export GOOGLE_APPLICATION_CREDENTIALS="/etc/gcp/backup-sa-key.json"

Signed URL’ler ile Güvenli Dosya Paylaşımı

Bir müşteri portalı projesinde kullanıcılara private bucket’taki dosyalara geçici erişim vermek gerekiyordu. Signed URL’ler bu iş için biçilmiş kaftan.

# 1 saatliğine geçerli signed URL oluşturma (indirme için)
gcloud storage sign-url gs://sirket-uygulama-prod/faturalar/fatura-001.pdf 
  --duration=1h 
  --private-key-file=/etc/gcp/app-sa-key.json

# 24 saatliğine geçerli signed URL - büyük dosya indirmeleri için
gcloud storage sign-url gs://sirket-uygulama-prod/raporlar/aylik-rapor.xlsx 
  --duration=24h 
  --private-key-file=/etc/gcp/app-sa-key.json 
  --headers=Content-Disposition:attachment

# PUT methodu ile yükleme için signed URL (kullanıcı doğrudan upload yapabilir)
gcloud storage sign-url gs://sirket-uygulama-prod/uploads/user-123/ 
  --duration=30m 
  --method=PUT 
  --private-key-file=/etc/gcp/app-sa-key.json 
  --headers=Content-Type:image/jpeg

Python veya Node.js uygulamalarında bu URL’leri programatik olarak üretmek çok daha yaygın ama CLI ile test yaparken bu komutlar çok işe yarıyor.

CORS ve Static Web Hosting Yapılandırması

Static site hosting veya frontend uygulamalardan doğrudan Cloud Storage’a upload yapılmasına izin vermek için CORS yapılandırması şart.

# cors.json dosyası oluşturma
cat > /tmp/cors.json << 'EOF'
[
  {
    "origin": ["https://app.sirket.com", "https://www.sirket.com"],
    "method": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
    "responseHeader": [
      "Content-Type",
      "Access-Control-Allow-Origin",
      "x-goog-resumable"
    ],
    "maxAgeSeconds": 3600
  }
]
EOF

# CORS ayarlarını uygulama
gsutil cors set /tmp/cors.json gs://sirket-static-site

# CORS ayarlarını kontrol etme
gsutil cors get gs://sirket-static-site

Static web hosting için bucket’ı public erişime açmak gerekiyor. Bunun için önce Uniform bucket-level access’i devre dışı bırakmanız veya AllUsers’a storage.objectViewer yetkisi vermeniz gerekiyor:

# Bucket'ı web sitesi olarak yapılandırma
gsutil web set -m index.html -e 404.html gs://sirket-static-site

# AllUsers'a okuma izni verme (public site için)
gcloud storage buckets add-iam-policy-binding gs://sirket-static-site 
  --member="allUsers" 
  --role="roles/storage.objectViewer"

Monitoring ve Maliyet Optimizasyonu

Cloud Storage maliyetlerini kontrol altında tutmak için önce ne kadar harcadığınızı anlamanız lazım. gsutil du komutu bucket boyutlarını analiz etmek için güçlü bir araç.

# Bucket toplam boyutunu görme
gsutil du -sh gs://sirket-uygulama-prod

# Klasör bazlı boyut analizi
gsutil du -sh gs://sirket-uygulama-prod/**

# Depolama sınıfı dağılımını inceleme
gsutil ls -L gs://sirket-uygulama-prod/ | grep "Storage class"

# 90 günden eski nesneleri listeleme
gsutil ls -l gs://sirket-uygulama-prod/ | awk '{print $NF, $2}' | 
  awk -v date="$(date -d '90 days ago' '+%Y-%m-%d')" '$2 < date {print $1}'

Maliyet optimizasyonu için dikkat etmeniz gereken noktalar:

  • Gereksiz versiyonları temizleyin: Versioning açıksa eski versiyonlar birikerek ciddi maliyet oluşturur
  • Lifecycle kurallarını doğru yapılandırın: Sık erişilmeyen verileri otomatik olarak daha ucuz sınıfa taşıyın
  • Egress maliyetlerine dikkat edin: GCP dışına veri transferi ücretli, mümkünse aynı region içinde tutun
  • Nearline ve Coldline minimum saklama sürelerine dikkat edin: Erken silme durumunda minimum saklama ücreti alınır
  • Storage Insights raporlarını kullanın: Hangi nesnelerin ne kadar erişildiğini analiz edin

Encryption ve Veri Güvenliği

GCP Cloud Storage, nesneleri varsayılan olarak Google tarafından yönetilen anahtarlarla şifreler. Ama bazı compliance gereksinimleri kendi anahtarlarınızı kullanmanızı zorunlu kılabilir.

# Customer-Managed Encryption Key (CMEK) ile bucket oluşturma
# Önce Cloud KMS'de anahtar oluşturun
gcloud kms keyrings create storage-keyring 
  --location=europe-west1

gcloud kms keys create storage-key 
  --location=europe-west1 
  --keyring=storage-keyring 
  --purpose=encryption

# Cloud Storage service account'una KMS erişimi verme
gcloud kms keys add-iam-policy-binding storage-key 
  --location=europe-west1 
  --keyring=storage-keyring 
  --member="serviceAccount:service-PROJE_NUMARASI@gs-project-accounts.iam.gserviceaccount.com" 
  --role="roles/cloudkms.cryptoKeyEncrypterDecrypter"

# CMEK ile bucket oluşturma
gcloud storage buckets create gs://sirket-sifrelenmis-bucket 
  --location=europe-west1 
  --default-kms-key=projects/proje-id/locations/europe-west1/keyRings/storage-keyring/cryptoKeys/storage-key

# Bucket retention policy ayarlama (WORM - Write Once Read Many)
gcloud storage buckets update gs://sirket-compliance-bucket 
  --retention-period=2592000s  # 30 gün saniye cinsinden

Retention policy özellikle fintech ve sağlık sektöründe zorunlu oluyor. Bir kez ayarlandıktan sonra retention süresi dolmadan nesne silinemiyor, bu da compliance açısından kritik bir özellik.

Notification ve Event-Driven Mimari

Cloud Storage olaylarını Pub/Sub ile yakalayarak event-driven sistemler kurabilirsiniz. Bir dosya yüklendiğinde otomatik işlem tetiklemek çok yaygın bir kullanım senaryosu.

# Pub/Sub topic oluşturma
gcloud pubsub topics create storage-events

# Cloud Storage'a Pub/Sub'a yayın yapma yetkisi verme
gsutil notification create 
  -t projects/proje-id/topics/storage-events 
  -f json 
  -e OBJECT_FINALIZE 
  gs://sirket-uygulama-prod

# Yükleme, silme ve metadata değişikliklerini dinleme
gsutil notification create 
  -t projects/proje-id/topics/storage-events 
  -f json 
  -e OBJECT_FINALIZE 
  -e OBJECT_DELETE 
  -e OBJECT_METADATA_UPDATE 
  gs://sirket-uygulama-prod

# Mevcut notification'ları listeleme
gsutil notification list gs://sirket-uygulama-prod

Bu yapıyla bir görsel yükleme servisi kurabilirsiniz: Kullanıcı görseli bucket’a yüklüyor, Pub/Sub event tetikleniyor, Cloud Function görseli işleyip küçük boyutlu versiyonları oluşturuyor. Tamamen serverless ve ölçeklenebilir bir mimari.

Transfer Service ile Büyük Veri Göçü

Başka bulut sağlayıcılarından veya on-premise sistemlerden büyük miktarda veri taşırken Storage Transfer Service devreye giriyor.

# AWS S3'ten GCS'e transfer job oluşturma
gcloud transfer jobs create 
  --source-agent-pool=default 
  s3://aws-kaynak-bucket 
  gs://gcp-hedef-bucket 
  --source-creds-file=/tmp/aws-credentials.json 
  --include-modified-after-absolute="2024-01-01T00:00:00Z"

# Transfer job durumunu kontrol etme
gcloud transfer jobs list

# Belirli bir job'ın detayları
gcloud transfer jobs describe JOB_ID

AWS’den GCP’ye büyük veri göçlerinde Transfer Service’i gsutil ile manuel kopyalamaya tercih ediyorum. Yeniden deneme mekanizması, bant genişliği limitleme ve detaylı raporlama özellikleri production göçlerinde çok değerli.

Sonuç

GCP Cloud Storage, doğru yapılandırıldığında son derece güçlü ve maliyet etkin bir nesne depolama çözümü sunuyor. Bu yazıda ele aldığımız konuları özetleyecek olursak:

  • Bucket oluştururken depolama sınıfı ve lokasyon seçimi maliyet ve performansı doğrudan etkiliyor, bu kararları baştan doğru verin
  • IAM yönetiminde Uniform bucket-level access kullanın ve en az yetki prensibine sıkı sıkıya uyun
  • Versioning ve lifecycle kurallarını birlikte kullanmak hem veri güvenliği hem de maliyet optimizasyonu açısından kritik
  • Signed URL’ler private verilere geçici erişim vermek için güvenli ve pratik bir yöntem
  • Event-driven mimari için Pub/Sub entegrasyonu oldukça güçlü kullanım senaryoları açıyor
  • Büyük veri göçleri için Storage Transfer Service’i tercih edin

En çok dikkat etmeniz gereken nokta maliyet yönetimi. Lifecycle kuralları ve depolama sınıflarını doğru yapılandırmadan bırakılan bucket’lar zamanla ciddi faturalara yol açabiliyor. Her yeni bucket oluştururken lifecycle politikasını da beraberinde tanımlamayı bir alışkanlık haline getirin.

Bir yanıt yazın

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