GitLab Kubernetes Entegrasyonu ve Auto DevOps Kurulum Rehberi

Kubernetes ortamına geçiş sürecinde en çok zaman harcadığım konulardan biri, CI/CD pipeline’larını Kubernetes cluster’larıyla düzgün entegre etmekti. GitLab’ın sunduğu Kubernetes entegrasyonu ve Auto DevOps özelliği kağıt üzerinde çok cazip görünüyor, ancak gerçek dünyada birkaç tuzak sizi bekliyor. Bu yazıda hem teorik altyapıyı hem de bizzat yaşadığım senaryoları paylaşacağım.

GitLab Kubernetes Entegrasyonuna Genel Bakış

GitLab, Kubernetes entegrasyonunu iki farklı yöntemle sunar. Birincisi eski usul “certificate-based” bağlantı yöntemi ki GitLab artık bunu deprecated saydı. İkincisi ise GitLab Agent for Kubernetes (kube-agent veya kas) üzerinden yapılan modern entegrasyon.

Eğer hâlâ certificate tabanlı entegrasyon kullanıyorsanız, bir an önce agent tabanlı yapıya geçmenizi öneririm. Hem daha güvenli hem de GitLab’ın aktif olarak geliştirdiği yöntem bu.

GitLab Agent Kurulumu

Önce GitLab projenizde .gitlab/agents//config.yaml dosyasını oluşturmanız gerekiyor. Ben genellikle agent adı olarak cluster’ın ortamını (staging, production) kullanırım.

mkdir -p .gitlab/agents/production-cluster
touch .gitlab/agents/production-cluster/config.yaml

config.yaml dosyasının içeriği şu şekilde olmalı:

ci_access:
  projects:
    - id: grup-adi/proje-adi
  groups:
    - id: grup-adi

observability:
  logging:
    level: info

Şimdi Kubernetes tarafında agent’ı yükleyelim. Helm üzerinden kurulum yapacağız:

helm repo add gitlab https://charts.gitlab.io
helm repo update

helm upgrade --install gitlab-agent gitlab/gitlab-agent 
  --namespace gitlab-agent 
  --create-namespace 
  --set config.token=<AGENT_TOKEN> 
  --set config.kasAddress=wss://kas.gitlab.com 
  --set image.tag=v16.5.0

Agent token’ını GitLab arayüzünden alıyorsunuz: Infrastructure > Kubernetes clusters > Connect a cluster. Token bir kez gösteriliyor, not alın.

Kurulumdan sonra agent’ın ayakta olup olmadığını kontrol edin:

kubectl get pods -n gitlab-agent
kubectl logs -n gitlab-agent -l app=gitlab-agent --tail=50

Log çıktısında "level":"info","msg":"Starting GitLab Agent" görüyorsanız bağlantı kurulmuştur.

CI/CD Pipeline’ında Kubernetes’e Erişim

Agent kurulduktan sonra .gitlab-ci.yml dosyanızda KUBE_CONTEXT değişkenini tanımlamanız yeterli. Bu sayede runner’larınız doğrudan kubectl komutlarını çalıştırabilir.

variables:
  KUBE_CONTEXT: grup-adi/proje-adi:production-cluster

deploy:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    - kubectl config use-context $KUBE_CONTEXT
    - kubectl apply -f k8s/
    - kubectl rollout status deployment/my-app -n production
  environment:
    name: production
    url: https://myapp.example.com

Burada dikkat edilmesi gereken nokta: KUBE_CONTEXT değeri namespace/proje:agent-adı formatında olmalı. Yanlış format verildiğinde runner sessiz sedasız hata verebilir, context bulunamadı diye.

Birden fazla cluster’ınız varsa environment’a göre context değiştirebilirsiniz:

.deploy_template: &deploy_template
  image: bitnami/kubectl:latest
  before_script:
    - kubectl config use-context $KUBE_CONTEXT

deploy_staging:
  <<: *deploy_template
  stage: deploy_staging
  variables:
    KUBE_CONTEXT: grup-adi/proje-adi:staging-cluster
  environment:
    name: staging
  only:
    - develop

deploy_production:
  <<: *deploy_template
  stage: deploy_production
  variables:
    KUBE_CONTEXT: grup-adi/proje-adi:production-cluster
  environment:
    name: production
  when: manual
  only:
    - main

Auto DevOps Nedir ve Ne Zaman Kullanılmalı?

Auto DevOps, GitLab’ın sunduğu otomatik CI/CD pipeline’ı sistemi. Projenize özel bir .gitlab-ci.yml yazmadan test, build, security scan, deploy gibi aşamaları otomatik olarak çalıştırıyor.

Teoride harika. Pratikte ise… karma duygularım var.

Küçük ekipler veya standart web uygulamaları için gerçekten zamandan tasarruf ettiriyor. Ancak özelleştirilmiş build süreçleri, monorepo yapıları veya karmaşık deployment stratejileri olan projelerde Auto DevOps’u terk edip sıfırdan yazıyorsunuz. O yüzden “ileride özelleştirmem gerekecek mi?” sorusunu başta sormak gerekiyor.

Auto DevOps’u Aktif Etmek

Proje ayarlarından Settings > CI/CD > Auto DevOps bölümünü açın ve “Default to Auto DevOps pipeline” seçeneğini aktif edin. Ya da .gitlab-ci.yml içine şunu ekleyebilirsiniz:

include:
  - template: Auto-DevOps.gitlab-ci.yml

Template’i include etmek, özelleştirme imkânı açısından daha avantajlı. Belirli stage’leri override edebiliyorsunuz.

Auto DevOps Aşamaları

Auto DevOps pipeline’ı şu aşamaları içerir:

  • build: Heroku buildpack veya Dockerfile kullanarak image oluşturur
  • test: Otomatik test çalıştırır
  • code_quality: Code climate tabanlı kalite analizi
  • sast: Static Application Security Testing
  • secret_detection: Repo içindeki gizli bilgileri tarar
  • dependency_scanning: Bağımlılıklardaki güvenlik açıklarını bulur
  • container_scanning: Docker image’ı tarar
  • dast: Dynamic Application Security Testing
  • review: Merge request’ler için review environment oluşturur
  • staging: Staging ortamına deploy
  • canary: Production’a canary deploy
  • production: Production deploy
  • performance: Performans testi

Hepsini açık bırakmak gereksiz yere pipeline süresini uzatır. İhtiyacınıza göre bazı aşamaları devre dışı bırakabilirsiniz:

variables:
  CODE_QUALITY_DISABLED: "true"
  DAST_DISABLED: "true"
  PERFORMANCE_DISABLED: "true"
  TEST_DISABLED: "false"

Gerçek Dünya: E-Ticaret Uygulaması Deployment Senaryosu

Geçen yıl bir e-ticaret platformunun GitLab üzerinden Kubernetes’e geçiş sürecinde şöyle bir yapı kurdum. Hem Auto DevOps template’ini baz aldık hem de üzerine production-grade özelleştirmeler ekledik.

Uygulama Node.js tabanlı, MongoDB ve Redis kullanıyor, tek bir GitLab projesi içinde frontend ve backend kodları birlikte duruyor.

İlk iş, Auto DevOps template’ini include edip gereksiz aşamaları kapatmak oldu:

include:
  - template: Auto-DevOps.gitlab-ci.yml

variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: ""
  POSTGRES_ENABLED: "false"
  CODE_QUALITY_DISABLED: "true"
  DAST_DISABLED: "true"
  STAGING_ENABLED: "1"
  CANARY_ENABLED: "1"
  INCREMENTAL_ROLLOUT_ENABLED: "1"
  AUTO_DEVOPS_CHART: stable/nodejs
  KUBE_INGRESS_BASE_DOMAIN: k8s.example.com

stages:
  - build
  - test
  - staging
  - canary
  - production
  - cleanup

KUBE_INGRESS_BASE_DOMAIN değişkeni Auto DevOps’un otomatik Ingress yapılandırması oluşturması için kritik. Bu olmadan uygulama deploy olsa bile dışarıdan erişilemez.

Helm Values Özelleştirmesi

Auto DevOps, deploy aşamasında kendi Helm chart’ını kullanır. Bu chart’ı özelleştirmek için proje kökünde helm/ dizini oluşturabilirsiniz veya CI değişkenleri üzerinden Helm values geçebilirsiniz:

# CI/CD değişkenlerine eklenecek HELM_UPGRADE_EXTRA_ARGS
--set replicaCount=3 
--set resources.requests.memory=256Mi 
--set resources.requests.cpu=100m 
--set resources.limits.memory=512Mi 
--set resources.limits.cpu=500m 
--set livenessProbe.initialDelaySeconds=30 
--set readinessProbe.initialDelaySeconds=10

Daha temiz bir yol olarak auto-deploy-values.yaml dosyasını proje köküne koyabilirsiniz, Auto DevOps bunu otomatik okur:

replicaCount: 3

resources:
  requests:
    memory: "256Mi"
    cpu: "100m"
  limits:
    memory: "512Mi"
    cpu: "500m"

service:
  externalPort: 3000
  internalPort: 3000

livenessProbe:
  path: /health
  initialDelaySeconds: 30

readinessProbe:
  path: /ready
  initialDelaySeconds: 10

extraEnv:
  - name: NODE_ENV
    value: production
  - name: REDIS_URL
    valueFrom:
      secretKeyRef:
        name: app-secrets
        key: redis-url

Canary Deployment ve Incremental Rollout

Auto DevOps’un en değerli özelliklerinden biri canary deployment desteği. CANARY_ENABLED: "1" ayarladığınızda, production’a tam geçmeden önce trafiğin küçük bir yüzdesini yeni versiyona yönlendiriyor.

Varsayılan olarak canary stage %10 trafik gönderir. Bunu değiştirmek için:

variables:
  CANARY_PRODUCTION_REPLICAS: "2"
  PRODUCTION_REPLICAS: "10"

Canary başarılıysa incremental rollout ile kademeli geçiş yapabilirsiniz. INCREMENTAL_ROLLOUT_ENABLED: "1" ile %10, %25, %50, %100 şeklinde kademeli olarak ilerler, her aşama manuel onay gerektirir.

Bu yapıyı production’da ilk kez kullandığımda beklenmedik bir sorunla karşılaştım: Ingress controller canary annotation’larını doğru yorumlamıyordu. Nginx Ingress kullanıyorsanız controller’ın version’ına dikkat edin, eski versiyonlarda nginx.ingress.kubernetes.io/canary annotation’ları düzgün çalışmayabiliyor.

Review Environments

Auto DevOps’un bir diğer güçlü özelliği review environments. Her merge request için otomatik olarak Kubernetes üzerinde geçici bir environment oluşturuyor.

Bu özellik için REVIEW_DISABLED değişkenini tanımlamamanız yeterli (zaten varsayılan olarak aktif).

Review environment URL’si otomatik olarak şu formatta oluşuyor: https://proje-adi-branch-adi.KUBE_INGRESS_BASE_DOMAIN

MR kapandığında veya merge edildiğinde environment otomatik temizleniyor, ancak bazen Kubernetes namespace’leri geride kalabiliyor. Bunun için cleanup job’ı kontrol edin, bazen timeout sorunlarından dolayı çalışmıyor. Elle temizlemek gerekiyor:

kubectl get namespaces | grep review
kubectl delete namespace review-proje-adi-branch-adi

Secret Yönetimi

Kubernetes secret’larını GitLab CI değişkenleriyle yönetmek konusunda bir standart oturtmak önemli. Şöyle bir yaklaşım benimsedim:

Uygulama secret’larını Kubernetes’e CI pipeline üzerinden push ediyoruz, GitLab group/project değişkenlerinde tutuyoruz:

create_secrets:
  stage: .pre
  image: bitnami/kubectl:latest
  script:
    - kubectl config use-context $KUBE_CONTEXT
    - |
      kubectl create secret generic app-secrets 
        --from-literal=database-url="$DATABASE_URL" 
        --from-literal=redis-url="$REDIS_URL" 
        --from-literal=jwt-secret="$JWT_SECRET" 
        --namespace production 
        --dry-run=client -o yaml | kubectl apply -f -
  only:
    - main
  when: manual

--dry-run=client -o yaml | kubectl apply -f - kombinasyonu çok işe yarıyor. Secret zaten varsa günceller, yoksa oluşturur. kubectl create secret komutu secret zaten mevcutsa hata verdiği için bu yöntem daha güvenli.

Monitoring ve Observability Entegrasyonu

GitLab’ın Kubernetes entegrasyonu sadece deployment ile bitmiyor. Prometheus metrikleri GitLab üzerinden görüntülenebilir. Bunun için cluster’da Prometheus kurulu olmalı ve GitLab Kubernetes entegrasyon ayarlarından Prometheus URL’sini belirtmelisiniz.

Auto DevOps deploy ettiği uygulamaların otomatik olarak Prometheus scraping annotation’larını ekler:

prometheus.io/scrape: "true"
prometheus.io/port: "5000"
prometheus.io/path: "/metrics"

Uygulamanız bu endpoint’i expose ettiği sürece GitLab CI/CD > Environments sayfasında metrik grafikleri görmeye başlarsınız. Müşterilere göstermek için kullanışlı bir özellik bu, ayrı bir monitoring dashboard’u açmadan temel metriklere bakılabiliyor.

Sık Karşılaşılan Sorunlar ve Çözümleri

Agent bağlantısı kesiliyor: Production ortamlarında gitlab-agent pod’unun resource limit’lerini artırın. Yoğun CI/CD trafiğinde memory squeeze yaşayabilir.

ImagePullBackOff hatası: Auto DevOps, build ettiği image’ı GitLab Container Registry’ye push ediyor ve Kubernetes’e pull secret eklemesi gerekiyor. KUBE_PULL_POLICY değişkeni ve registry’e erişim için deploy token ayarlarını kontrol edin.

Helm release stuck: Zaman zaman Helm release’ler PENDING_UPGRADE durumunda kalabiliyor. Çözüm:

kubectl get secrets -n production | grep helm
helm rollback my-app 0 -n production
# ya da direkt secret'ı silerek:
kubectl delete secret sh.helm.release.v1.my-app.v5 -n production

Review environment namespace kotası: Çok fazla açık MR varsa namespace kotası dolabilir. ResourceQuota tanımlamanızı öneririm:

kubectl apply -f - <<EOF
apiVersion: v1
kind: ResourceQuota
metadata:
  name: review-env-quota
  namespace: review-proje-adi-branch-adi
spec:
  hard:
    requests.cpu: "500m"
    requests.memory: 512Mi
    limits.cpu: "1"
    limits.memory: 1Gi
EOF

Sonuç

GitLab Kubernetes entegrasyonu, doğru kurulduğunda gerçekten end-to-end bir DevOps deneyimi sunuyor. Agent tabanlı mimari, eski certificate yöntemine göre çok daha güvenli ve yönetilebilir. Auto DevOps ise standart uygulamalar için hızlı başlangıç noktası, ancak production’da mutlaka özelleştirme yapmanız gerekecek.

Benim tavsiyem: Yeni bir proje başlatıyorsanız Auto DevOps template’ini include ederek başlayın, ihtiyaçlarınızı anlayın, sonra aşama aşama özelleştirin. Sıfırdan yazmak yerine GitLab’ın halihazırda test ettiği template’leri baz almak uzun vadede bakım yükünü azaltıyor.

Canary deployment ve review environments gibi özellikleri küçük ekiplerin bile erişebilir hale gelmesi, GitLab’ın bu alandaki en büyük katkısı bence. Birkaç değişken ayarıyla production-grade deployment stratejileri elde edebilmek, altyapı ekibi olmayan şirketler için gerçek bir avantaj.

Bir yanıt yazın

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