GitLab CI/CD Pipeline Kurulumu ve Best Practices
Modern yazılım geliştirme süreçlerinde, kodun sürekli entegrasyonu (CI) ve sürekli dağıtımı (CD) iş akışlarının temelini oluşturur. GitLab CI/CD, bu süreçleri otomatikleştirmek için entegre, güçlü ve esnek bir platform sunar. Bu makale, GitLab CI/CD pipeline'larının kurulumunu, temel bileşenlerini ve üretim ortamlarında uygulanabilecek en iyi pratikleri teknik derinlikle ele almaktadır.
GitLab CI/CD Temel Kavramları
GitLab CI/CD, projenizin kök dizininde bulunan .gitlab-ci.yml dosyası ile yapılandırılır. Bu dosya, pipeline'ın adımlarını, işlerini (jobs) ve aşamalarını (stages) tanımlayan YAML formatında bir manifesttir.
- Stages: Pipeline'daki işlerin mantıksal gruplarıdır. Her aşama, önceki aşama başarıyla tamamlanmadan başlamaz. Yaygın aşamalar:
build,test,deploy. - Jobs: Belirli bir aşama içinde çalışan bağımsız görevlerdir. Her iş, tanımlanan komutları çalıştıran bir GitLab Runner üzerinde yürütülür.
- Runners: İşleri yürüten sanal makineler veya konteynerlerdir. GitLab'ın paylaşımlı runner'ları kullanılabileceği gibi, özel (private) runner'lar da kurulabilir.
- Artifacts: Bir iş tarafından üretilen ve sonraki işler veya indirme için saklanan dosyalardır (örn. derlenmiş binary'ler, test raporları).
- Cache: Bağımlılıkların veya derleme sonuçlarının tekrar tekrar indirilmesini önlemek için işler arasında yeniden kullanılan dosyalardır.
Basit Bir CI/CD Pipeline Kurulumu
Aşağıdaki örnek, basit bir Node.js uygulamasının build, test ve deploy aşamalarını içeren bir .gitlab-ci.yml dosyasıdır.
# .gitlab-ci.yml dosyasının başlangıcıstages: - build - test - deploy# Build aşaması: Uygulama bağımlılıklarını kurar ve paketlerbuild_job: stage: build image: node:16 # İşin çalışacağı Docker imajı script: - npm install - npm build artifacts: paths: - node_modules/ # Sonraki işler için bağımlılıkları sakla expire_in: 1 day # Artifact'ların saklanma süresi cache: key: ${CI_COMMIT_REF_SLUG} # Branch'e özel cache anahtarı paths: - node_modules/# Test aşaması: Uygulama testlerini çalıştırırtest_job: stage: test image: node:16 script: - npm install # Cache kullanılmazsa bağımlılıkları yeniden kurar - npm test dependencies: - build_job # build_job'dan artifact'ları (node_modules) çeker# Deploy aşaması: Uygulamayı bir sunucuya veya ortama dağıtırdeploy_job: stage: deploy image: alpine/git # Dağıtım için minimalist bir imaj script: - echo "Dağıtım Başlatılıyor..." - echo "Uygulama ${CI_COMMIT_REF_NAME} branch'inden ${CI_ENVIRONMENT_NAME} ortamına dağıtılıyor." # Gerçek bir senaryoda bu kısım AWS S3, EKS, Azure App Service vb. bir dağıtım komutu içerir. # Örn: aws s3 sync ./build s3://my-app-bucket --delete # Örn: kubectl apply -f kubernetes/deployment.yaml environment: # Ortam tanımlaması name: production url: https://my-app.example.com rules: - if: $CI_COMMIT_BRANCH == "main" # Sadece main branch'e commit yapıldığında çalıştırGerçek Dünya Senaryosu: Mikroservis Dağıtımı ve Testi
Bir mikroservis mimarisinde, her servis kendi pipeline'ına sahip olabilir veya monorepo yaklaşımlarında tek bir pipeline farklı servisleri yönetebilir. Genellikle bu senaryolarda Docker imajı oluşturma, konteyner kayıt defterine gönderme ve Kubernetes'e dağıtım adımları bulunur.
# Docker tabanlı bir mikroservis için CI/CD pipeline'ıstages: - build_image - test - deploy_to_dev - deploy_to_prod# Docker imajı oluşturma ve Container Registry'ye göndermebuild_docker_image: stage: build_image image: docker:19.03.12 # Docker-in-Docker (DinD) için uygun imaj services: - docker:19.03.12-dind # DinD servisi script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY # GitLab Container Registry'ye giriş - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA . # Docker imajını oluştur - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA # İmajı kayıt defterine gönder variables: DOCKER_HOST: tcp://docker:2375 # DinD için gerekli DOCKER_TLS_CERTDIR: "" DOCKER_DRIVER: overlay2 rules: - if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH =~ /feature/ # main veya feature branch'lerinde çalıştır# Konteyner imajı üzerinde entegrasyon ve birim testleritest_service: stage: test image: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA # Yeni oluşturulan imajı test için kullan services: - name: postgres:13 alias: db-service # Test ortamı için bağımlılık (örn. veritabanı) variables: DB_HOST: db-service DB_PORT: 5432 DB_USER: testuser DB_PASSWORD: testpassword script: - ./run_integration_tests.sh # Kapsamlı test script'i - ./run_unit_tests.sh# Geliştirme ortamına dağıtımdeploy_dev: stage: deploy_to_dev image: name: dtzar/helm-kubectl:latest # Helm ve Kubectl içeren bir imaj entrypoint: ["/bin/sh", "-c"] script: - kubectl config use-context my-dev-cluster # Kubernetes bağlamını ayarla - helm upgrade --install my-app-dev ./helm/my-app --namespace dev --set image.tag=$CI_COMMIT_SHORT_SHA environment: name: development url: https://dev.my-app.example.com rules: - if: $CI_COMMIT_BRANCH =~ /feature/ # Sadece feature branch'leri için# Üretim ortamına dağıtım (manuel onay gerektiren)deploy_prod: stage: deploy_to_prod image: name: dtzar/helm-kubectl:latest entrypoint: ["/bin/sh", "-c"] script: - kubectl config use-context my-prod-cluster # Prod Kubernetes bağlamı - helm upgrade --install my-app-prod ./helm/my-app --namespace prod --set image.tag=$CI_COMMIT_SHORT_SHA environment: name: production url: https://my-app.example.com rules: - if: $CI_COMMIT_BRANCH == "main" # Sadece main branch için when: manual # Manuel onay gerektirirGitLab CI/CD Best Practices
Pipeline Optimizasyonu
- Cache Kullanımı: Bağımlılıkların (
npm install,pip install) her çalışmada yeniden indirilmesini engellemek için cache mekanizmasını etkin kullanın. Anahtar olarak${CI_COMMIT_REF_SLUG}veya${CI_COMMIT_REF_NAME}gibi değişkenleri kullanarak branch bazında izolasyon sağlayın. - Artifacts: Bir işin çıktısını diğer işlere aktarmak için artifact'ları kullanın. Örneğin, build aşamasında derlenen binary'leri test veya deploy aşamalarına aktarmak.
- Paralel İşler: Bağımsız işleri
parallel: <sayı>anahtar kelimesiyle paralel çalıştırarak pipeline süresini kısaltın. - İmaj Optimizasyonu: İşlerin çalışacağı Docker imajlarını mümkün olduğunca küçük ve amaca yönelik tutun. Örneğin, sadece
kubectlkomutlarını çalıştıracak bir iş içinalpine/gitveya özel oluşturulmuş minimalist bir imaj kullanın.
Güvenlik
- CI/CD Variables ve Secrets Management: Hassas bilgileri (API anahtarları, veritabanı şifreleri)
.gitlab-ci.ymldosyasına doğrudan yazmayın. GitLab CI/CD Variables veya HashiCorp Vault gibi harici bir secret management sistemi kullanın. Maskelenmiş (masked) ve korumalı (protected) değişkenleri tercih edin. - SAST/DAST Entegrasyonu: Güvenlik taramalarını (Static Application Security Testing - SAST, Dynamic Application Security Testing - DAST) pipeline'a entegre ederek erken aşamalarda zafiyetleri tespit edin. GitLab, bu taramaları kolayca entegre etmek için hazır şablonlar sunar.
- İzinler ve Roller: GitLab kullanıcılarına ve runner'lara sadece ihtiyaç duydukları minimum izinleri verin (Least Privilege Principle).
Pipeline As Code ve Sürdürülebilirlik
- Küçük ve Modüler Pipeline'lar: Tek bir devasa
.gitlab-ci.ymlyerine, alt pipeline'ları (child pipelines) kullanarak karmaşıklığı azaltın ve okunabilirliği artırın. - Şablonlar (Templates): Tekrar eden iş veya aşama tanımları için GitLab şablonlarını veya kendi özel şablonlarınızı kullanın. Bu, tutarlılığı sağlar ve bakım maliyetini düşürür.
- Kod Kalitesi ve Testler: Pipeline'a otomatik kod linting, statik analiz ve kapsamlı birim/entegrasyon testleri ekleyerek kod kalitesini garanti altına alın.
Dağıtım ve Ortam Yönetimi
- Environment Definitions: Dağıtım yapılan ortamları (
development,staging,production)environmentanahtar kelimesiyle tanımlayın. Bu, GitLab UI'ında dağıtımları görselleştirmeye yardımcı olur. - Manuel Onay Adımları: Üretim ortamına yapılan dağıtımlar için
when: manualkullanarak manuel onay gerekliliği ekleyin. Bu, istenmeyen dağıtımları önler ve kontrol mekanizması sağlar. - Rollback Stratejileri: Dağıtım hatalarına karşı geri alma (rollback) yeteneğini pipeline'a entegre edin. Bu, genellikle önceki stabil sürüme dönme veya yeni bir düzeltme dağıtma şeklinde olabilir.
Sonuç
GitLab CI/CD, yazılım geliştirme ekipleri için güçlü ve entegre bir otomasyon platformudur. Doğru kurulum ve en iyi pratiklerin uygulanması, daha hızlı, güvenli ve güvenilir yazılım teslimat süreçleri sağlar. Yukarıdaki teknik detaylar ve gerçek dünya senaryoları, GitLab CI/CD'nin potansiyelini tam olarak kullanmak için sağlam bir temel sunar.