Skip to main content

Genel Bakış

Bu kılavuz, bir API projesinin main branch’e gönderilen her değişikliği otomatik olarak test ettiği, Docker image ürettiği ve dört Kubernetes ortamına (dev → test → UAT → prod) sıralı şekilde deploy ettiği bir CI/CD altyapısının nasıl kurulduğunu gösterir. Her deployment adımı Apinizer üzerindeki API proxy ile senkronize edilir.

Kullanılan Teknolojiler ve Versiyonlar

Pipeline Akışı

Bu pipeline’a ek olarak, herhangi bir ortama belirli bir versiyonu doğrudan deploy eden bağımsız bir Targeted Deploy job’ı da mevcuttur. Bu job, tam pipeline çalıştırmadan tek ortam güncellemesi veya rollback senaryoları için kullanılır.

Proje Yapısı


1. GitHub Actions — CI Pipeline

CI pipeline, main branch’e her push geldiğinde tetiklenir. İki iş (job) içerir: önce testler çalışır, testler geçmeden build başlamaz.

Workflow Dosyası

Aşağıdaki içeriği .github/workflows/ci.yaml olarak oluşturun ve reponuza push edin.
Jenkins job adı boşluk içeriyorsa urllib.parse.quote() ile URL-encode edilmesi gerekir. Aksi hâlde curl isteği hatalı gönderilir.

GitHub Secrets Yapılandırması

Repository Settings > Secrets and Variables > Actions ekranından aşağıdaki secret’ları tanımlayın:

2. Kubernetes Altyapısı

Base Manifests

k8s/base/ dizini tüm ortamların ortak kullandığı Deployment ve Service manifest’lerini içerir. ENVIRONMENT değeri her ortamda ayrı bir ConfigMap üzerinden uygulamaya iletilir.

Kustomize Overlay’leri

Her ortam için k8s/overlays/<env>/kustomization.yaml dosyası bulunur. Bu dosya ortama özgü namespace, ConfigMap değerleri ve aktif image tag’ini tanımlar. Jenkins, her başarılı deployment sonrasında newTag değerini otomatik olarak günceller.
Her ortamın NodePort değeri bir service patch ile tanımlanır:
Aynı yapıyı test, uat ve prod overlay’leri için tekrarlayın; her birinde farklı namespace ve NodePort değerleri kullanın.

3. Jenkins — Ana CD Pipeline

Tetiklenme: GitHub Actions’tan buildWithParameters çağrısıyla, VERSION_TAG parametresi ile.

Jenkins Job Kurulumu

1

Yeni Pipeline job oluşturun

Jenkins’te New Item > Pipeline seçin. Job adı olarak CD pipeline’ınızı temsil eden bir isim girin.
2

SCM yapılandırması

Pipeline sekmesinde Pipeline script from SCM seçin. SCM olarak Git seçin, repository URL’inizi girin ve branch’i */main olarak belirtin. Script Path alanına jenkins/Jenkinsfile yazın.
3

VERSION_TAG parametresini tanımlayın

This project is parameterized kutusunu işaretleyin. String Parameter ekleyin: Name: VERSION_TAG, Default Value boş bırakın.

Shared Library Yapılandırması

Bu pipeline shared library fonksiyonlarını kullanır (retryWithDelay, apinizerProxySync, apinizerPromoteProd, smokeTest). Library’nin Jenkins’e tanımlanması için:
1

Global Pipeline Libraries ekranını açın

Manage Jenkins > System sayfasında Global Pipeline Libraries bölümüne gidin.
2

Kütüphaneyi ekleyin

Add butonuna tıklayın. Name alanına kütüphane adını girin (örn. shared-lib). Default version olarak main yazın. Retrieval method olarak Modern SCM seçin ve proje reponuzu gösterin.
3

Implicit olarak işaretleyin

Library tanımı ekranındaki Load implicitly seçeneğini etkinleştirin. Bu sayede Jenkinsfile içine @Library(...) direktifi eklenmesine gerek kalmaz; fonksiyonlar tüm pipeline job’larında doğrudan kullanılabilir hale gelir.

Jenkinsfile

Her Deploy stage’i şu üç işlemi tek sh bloğu içinde sırayla yapar: kustomize ile image tag güncelleme → cluster’a apply → rollout tamamlandıktan sonra [skip ci] commit’i ile Git’e push. withCredentials bloğu hem kubeconfig hem de Git credential’larını aynı anda kapsar. cd k8s/overlays/<env> yapıldığından git add relative path kullanır.

Pipeline Aşamalarının Detayları

Validate Parameters: VERSION_TAG parametresinin dolu olduğu kontrol edilir. GitHub Actions bypass edilerek Jenkins manuel tetiklendiğinde boş parametre gelme ihtimaline karşı bu koruma kritiktir. Checkout: Jenkinsfile’ın bulunduğu repo checkout edilir. Sonraki stage’lerde k8s/overlays/ altındaki Kustomize dosyaları üzerinde işlem yapılabilmesi için bu adım zorunludur. Deploy (her ortam için): withCredentials bloğu hem kubeconfig hem de Git credential’larını aynı anda kapsar. Tek bir sh bloğu içinde sırasıyla: kustomize edit set image ile overlay’deki newTag güncellenir, kubectl apply -k . ile cluster’a uygulanır, rollout tamamlandıktan sonra git add kustomization.yaml → commit → push yapılır. [skip ci] etiketi sayesinde GitHub Actions yeniden tetiklenmez. Apinizer Sync (dev / test / uat): apinizerProxySync shared library fonksiyonu, Apinizer’daki proxy’yi oluşturur veya günceller ve ilgili ortama deploy eder. Geçici hatalar için retryWithDelay wrapper’ı 3 deneme × 15 saniye bekleme uygular. Apinizer Promote Prod: Production için proxy sıfırdan deploy edilmez. apinizerPromoteProd fonksiyonu, UAT’ta onaylanan konfigürasyonu Apinizer’ın promotion API’si üzerinden production’a taşır. Approve (Test / UAT / Prod öncesi): Her ortam geçişinde Jenkins pipeline bekler; yetkili kullanıcı Jenkins UI’dan onaylayarak devam ettirir. Smoke Test: Deployment sonrasında kubectl rollout status ve /health endpoint kontrolü yapılır. Detaylar için Shared Library — smokeTest bölümüne bakınız.

4. Jenkins — Targeted Deploy Pipeline

Belirli bir versiyonu tek bir ortama deploy etmek için kullanılır. CI/CD akışını çalıştırmadan hotfix veya rollback senaryolarında tercih edilir.

Jenkins Job Kurulumu

1

Gerekli plugin'i yükleyin

Jenkins’te Manage Jenkins > Plugins ekranından Active Choices plugin’ini kurun. Bu plugin olmadan dinamik parametre dropdown’ları çalışmaz.
2

Yeni Pipeline job oluşturun

New Item > Pipeline seçin. Job adını targeted-deploy veya tercih ettiğiniz bir isim olarak girin.
3

SCM yapılandırması

Pipeline script from SCM seçin, aynı repo ve */main branch’ini kullanın. Script Path: jenkins/Jenkinsfile.targeted.
4

Parametreleri tanımlayın

Üç dinamik parametre eklenecektir: ENVIRONMENT, VERSION_TAG ve CURRENT_VERSION. Ayrıntılar aşağıdadır.

Dinamik Parametreler

Targeted deploy job’ı üç dinamik parametre kullanır. Bu parametrelerin tanımlanabilmesi için Active Choices plugin kurulu olmalıdır. ENVIRONMENT (Active Choices Parameter): Kullanıcının hedef ortamı seçtiği dropdown.
VERSION_TAG (Reactive Choice Parameter — ENVIRONMENT referanslı): Docker Hub API’sinden son 25 tag çekilerek kullanıcıya liste olarak sunulur.
CURRENT_VERSION (Reactive Choice Parameter — ENVIRONMENT referanslı): Seçili ortamın kustomization.yaml dosyasından newTag değeri okunarak “şu an deploy edilmiş versiyon” bilgisi gösterilir. Cache bypass için timestamp query parametresi eklenir.
VERSION_TAG ve CURRENT_VERSION parametrelerindeki Groovy script’ler sandbox dışında çalışır (sandbox: false). Jenkins’te Manage Jenkins > In-process Script Approval ekranından bu script’lerin onaylanması gerekir.

Jenkinsfile.targeted

Ana pipeline’dan farklı olarak bu pipeline’da git işlemleri ayrı bir Update Git stage’inde yapılır ve cluster’dan önce çalışır. kustomize edit ve git add/commit ayrı sh bloklarındadır; git push ise credential scope’unu daraltmak için ayrı bir withCredentials bloğuna alınmıştır. git add workspace root’unda çalıştığından full path kullanır. Deploy stage’inde git işlemi yoktur; yalnızca kubectl apply ve başarısızlık durumunda otomatik rollback çalışır.

Pipeline Aşamalarının Detayları

Validate: Parametre kontrolünün yanı sıra Docker Hub API’sine istek atarak seçilen tag’ın gerçekten mevcut olduğunu doğrular. Var olmayan bir tag’ın deploy edilmesi bu aşamada önlenir. Update Git: İki ayrı sh bloğu çalışır: ilki kustomize edit set image ile overlay’i günceller; ikincisi git add → commit yapar. git add full path kullanır (k8s/overlays/${ENVIRONMENT}/kustomization.yaml) çünkü workspace root’unda çalışılır. git push ise credential scope’unu daraltmak için ayrı bir withCredentials bloğuna alınmıştır. Git değişikliği cluster’dan önce yapılır; bu sayede pipeline başarısız olsa bile Git, deployment girişimini yansıtır. Deploy: Yalnızca kubectl apply -k . ve kubectl rollout status çalışır; bu stage’de git işlemi yoktur. Rollout başarısız olursa kubectl rollout undo ile önceki Kubernetes deployment’ına otomatik olarak geri dönülür. Rollback gerçekleştiğinde Apinizer senkronizasyonu çalışmaz; proxy önceki sürümü göstermeye devam eder. Apinizer Sync: Hedef ortama göre doğru port ve Apinizer proje adı dinamik olarak seçilir, ardından apinizerProxySync çağrılır.

5. Shared Library Fonksiyonları

Jenkins shared library jenkins/shared-library/vars/ altında dört fonksiyon içerir. Library, Jenkins’te Global Pipeline Libraries altında implicit olarak yapılandırıldığından Jenkinsfile içine @Library(...) direktifi eklenmesine gerek yoktur; fonksiyonlar tüm pipeline job’larında doğrudan kullanılabilir.

apinizerProxySync

Apinizer’da proxy oluşturur veya günceller, ardından ilgili ortama deploy eder. Akış:
Proxy mevcutsa güncellemeden önce export/ endpoint’inden ZIP alınır ve Jenkins artifact olarak arşivlenir. Bu sayede başarısız bir güncelleme sonrasında Apinizer UI’dan elle geri yükleme yapılabilir. Güncelleme sırasında mevcut relativePathList değeri API’den okunarak korunur; elle yazılmaz. Proxy oluşturma payload’u:
Proxy güncelleme payload’u:
deploy: false ile proxy ortama otomatik deploy edilmez. Akış sonundaki ayrı POST .../environments/{env}/ isteği ile kontrollü deployment yapılır.
Detaylı bilgi için Create API Proxy from URL ve Update API Proxy referanslarını inceleyebilirsiniz.

apinizerPromoteProd

UAT ortamındaki proxy konfigürasyonunu Apinizer’ın promotion mekanizması ile production’a taşır. Proxy sıfırdan deploy edilmez; önceden tanımlanmış mapping üzerinden kopyalanır.
Promotion mapping’lerinin Apinizer UI’da önceden tanımlanmış olması gerekir. mappingNames parametresi bu mapping’lere referans verir. Detaylı bilgi için API Mapping Oluşturma referansını inceleyebilirsiniz.

smokeTest

İki adımlı doğrulama yapar: önce kubectl rollout status ile deployment tamamlandığını kontrol eder, 5 saniye bekler, ardından /health endpoint’ine en fazla 3 kez istek atar. Denemeler arasında 5 saniye beklenir. HTTP 200 dönerse başarılı kabul edilir.

retryWithDelay

Herhangi bir closure’ı belirtilen sayıda ve bekleme süresiyle yeniden dener. Tüm denemeler başarısız olursa son hata fırlatılır ve stage failure olarak işaretlenir.

6. Jenkins Credentials Yapılandırması

Manage Jenkins > Credentials > System > Global credentials ekranından aşağıdaki credential’ları tanımlayın:
Apinizer API token oluşturma hakkında detaylı bilgi için Token Alma Yöntemleri dokümanını inceleyebilirsiniz.
kubeconfig dosyası cluster’a tam erişim sağlar. Jenkins’e Secret File olarak yükleyin; dosyayı workspace’e kopyalamaktan kaçının.

7. Apinizer API Endpoint Referansı

Bu pipeline’da kullanılan Apinizer Management API endpoint’leri:
Apinizer Management API hakkında detaylı bilgi için API Genel Bakış dokümanını inceleyebilirsiniz.

Kendi Pipeline’ınızı Uyarlamak

1

Docker Hub ve image adı

IMAGE_BASE değişkenini kendi Docker Hub kullanıcı adınız ve image adınızla güncelleyin. CI workflow’undaki IMAGE_NAME değerini de aynı şekilde düzenleyin.
2

Kubernetes yapılandırması

NODE_IP değerini cluster node IP’nizle, NodePort değerlerini her ortam için kullandığınız portlarla değiştirin. Deployment ve namespace adlarını kendi naming convention’ınıza göre düzenleyin.
3

Apinizer projeleri

PROJECT_NAME_* değişkenlerini Apinizer’da oluşturduğunuz proje adlarıyla güncelleyin. PROXY_NAME değerini API proxy adınızla değiştirin.
4

Apinizer promotion mapping

Production promotion için apinizerPromoteProd çağrısındaki mappingNames listesini Apinizer UI’da tanımladığınız mapping adlarıyla güncelleyin.
5

Git ve credentials

GIT_REPO_URL değerini reponuzla güncelleyin. Jenkins credentials ekranında apinizer-management-url, Apinizer token credential’ı, kubeconfig ve github-credentials ID’lerini tanımlayın.

Sonuç

Bu kılavuz, GitHub Actions, Jenkins ve Kubernetes’i birleştiren çok ortamlı bir CI/CD pipeline’ının nasıl kurulacağını göstermiştir. Her kod değişikliği otomatik olarak test edilir, versiyonlanır ve onay kapıları korunarak sıralı ortamlara deploy edilirken Apinizer’daki API proxy senkronize tutulur.