DEV Community

Cover image for CI/CD
Enes Gerem
Enes Gerem

Posted on

CI/CD

Continuous Integration

Basitçe, tüm geliştiriciler tarafından yapılan işleri günde birkaç kez paylaşılan bir ana hatta birleştirme uygulaması.

Kodu bir Git reposunda saklanan bir uygulama göz önüne alındığında, geliştiriciler, bir uygulama için kod değişikliklerini gün içerisinde birden çok kez pushlar.
Repoya yapılan her pushlama için, uygulamayı otomatik olarak oluşturmak ve test etmek için bir dizi komut dosyası oluşturulabilir. Bunlar
komut dosyaları, uygulamada hatalara neden olma olasılığını azaltmaya yardımcı olur.

Bir dalda ana hatta birleşmeden geliştirme ne kadar uzun sürerse, çoklu
geliştirici dalı sonunda tekrar birleştirildiğinde entegrasyon çakışmaları ve başarısızlıklar oluşması riski o kadar artar. Geliştiriciler kod gönderdiğinde
kopyalarını aldıkları andan itibaren repodaki değişiklikleri yansıtmak için önce kodlarını güncellemeleri gerekir.
Repo ne kadar çok değişiklik içeriyorsa, geliştiricilerin kendi değişikliklerini göndermeden önce o kadar çok iş yapması gerekir.

ci-pipeline

Bir uygulamaya gönderilen her değişiklik, otomatik ve sürekli olarak oluşturulur ve test edilir. Bahsedilen testler değişikliklerin tüm testlerden geçtiğini, kod içerisindeki yönergelerin ve kod uyumluluk standartlarının geçerliliğini kontrol eder.

Continuous Delivery & Deployment

Sürekli Teslimat, her seferinde yalnızca uygulamanın oluşturulduğu ve test edildiği Sürekli Entegrasyonun ötesinde bir adımdır.
kod değişikliği kod tabanına aktarılır, ancak uygulama da sürekli olarak dağıtılır. Sürekli Teslimat
kodu otomatik olarak kontrol eder, ancak değişikliğin dağıtımı manuel olarak gerçekleşir ve stratejik olarak tetiklemek için insan müdahalesi gerektirir.

sequence

Sürekli Dağıtım, Sürekli Teslimata benzer bir başka adımdır. Aradaki fark,
uygulama manuel olarak dağıtımının yerine, otomatik olarak dağıtılacak şekilde ayarlanmıştır, bu nedenle insan müdahalesi gerekmez.

cd-pipeline

Deployment pipeline, yazılım kalitesini iyileştirmek, kararlılığı arttırıp kodun maliyetini düşürmek adına yapılandırma yönetimini, sürekli entegrasyonu ve dağıtım otomasyonunu bir arada birbirine bağlar.

Deploymentlarda dikkat edilmesi gerekenler;

  • Paketleri yalnızca bir kez oluşturmak. Dağıttığımız projenin deployment pipeline boyunca baştan beri test ettiğimiz projeyle aynı olduğundan emin olmak istiyoruz, böylece bir dağıtım başarısız olursa, paketleri hatanın kaynağı olarak ortadan kaldırabiliriz.
  • Geliştirme dahil her ortama aynı şekilde dağıtmak. Bu şekilde, dağıtım sürecini birçok kez test ediyoruz. Herhangi bir sorun kaynağının ortadan kaldırılabilmesi için üretime geçme aşamasından önce gerçekleştirilebiliyor.
  • Dağıtımlarınızı duman testi ile test etmek Uygulamanın tüm bağımlılıklarını doğrulayan bir komut dosyasına sahip olun. uygulamanın yapılandırıldığı konum, uygulamanın çalıştığından ve uygulamanın dağıtım sürecenin bir parçası olarak kullanılabilir olduğundan emin olun.
  • Ortamları benzer tutmak Donanım yapılandırmasında farklılık gösterseler de aynı işletim sistemi ve ara yazılım paketlerinin sürümü ve aynı şekilde yapılandırılmalıdır. Günümüzde modern sanallaştırma ve kapsayıcı teknolojisi ile bunu başarmak çok daha kolay hale geldi.

GitLab'da CI/CD

GitLab, kendisine ait olan Sürekli Entegrasyon ve Sürekli Dağıtım sistemiyle oluşturulmuştur. Bir GitLab projesinde, projenin yapılandırılması için gitlab-ci.yml adlı bir configuration dosyası reponun içine yerleştirilir. Dosya, projede gerçekleşen her bir push komutuyla uygulamanın inşasının ve testinin tapılacağı GitLab Runner tarafından yürütülür.

GitLab Runner projenin işlerini çalıştırmak ve sonuçları GitLab'a geri göndermek için kullanılan açık kaynaklı bir projedir. Bu servis GitLab'a dahil olup CI ve CD'den ardışık düzen komut dosyasını yürütmek için onunla birlikte kullanılır.

GitLab'da CI/CD Örneği

Bu örnek proje bir küme yönetim sistemi olan Google Cloud Container Engine'e deploy edilecektir.

Gereksinimler; Dockerfile, Kubernetes deployment.

Spring Boot uygulamasını Docker Container olarak paketleme

FROM adoptopenjdk/openjdk11:alpine-jre
VOLUME /tmp
ADD /target/cdexample-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
Enter fullscreen mode Exit fullscreen mode

Kubernetes deployment'ı tanımlama

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: cdexample
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: cdexample
    spec:
      containers:
        - name: cdexample
          image: registry.gitlab.com/enesgerem/cdexample
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
      imagePullSecrets:
        - name: registry.gitlab.com
Enter fullscreen mode Exit fullscreen mode

Bir GitLab CI Pipeline oluşturma

Yukarıdaki dosyaları commitleyip pushladıktan sonra GitLab CI Pipeline'ı tanımlamaya hazırız.

image: docker:latest
services:
  - docker:dind

variables:
  DOCKER_DRIVER: overlay2
  SPRING_PROFILES_ACTIVE: gitlab-ci

stages:
  - build
  - package
  - deploy

maven-build:
  image: maven:3.8.1-jdk-11
  stage: build
  script: "mvn package -B"
  artifacts:
    paths:
      - target/*.jar

docker-build:
  stage: package
  script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker build -t registry.gitlab.com/enesgerem/cdexample .
    - docker push registry.gitlab.com/enesgerem/cdexample

k8s-deploy:
  image: google/cloud-sdk
  stage: deploy
  script:
    - echo "$GOOGLE_KEY" > key.json
    - gcloud auth activate-service-account --key-file key.json
    - gcloud config set compute/zone europe-west1-c
    - gcloud config set project cdexample
    - gcloud config set container/use_client_certificate True
    - gcloud container clusters get-credentials cdexample
    - kubectl delete secret registry.gitlab.com
    - kubectl create secret docker-registry registry.gitlab.com --docker-server=https://registry.gitlab.com --docker-username=enesgerem --docker-password=$REGISTRY_PASSWD --docker-email=enesgerem@gmail.com
    - kubectl apply -f deployment.yml
Enter fullscreen mode Exit fullscreen mode
  • image objesi kullanmak istediğimiz Docker image'ın ismini tanımlar.
  • services objesi projeye linklenmiş kullanmak istediğimiz ek Docker image'larını tanımlar.
  • variables objesi oluşturduğumuz environment içindeki değişkenleri tanımlar.
    • DOCKER_DRIVER hangi depolama sürücülerini kullandığımızı Docker Engine'a bildirir.
    • SPRING_PROFILES_ACTIVE uygulamamızın bölümlerini ayıran ve yalnızca belirli ortamlarda kullanılabilir hale getirmenin bir tolunu sağlayan Spring Profiles'ı etkinleştirir.
  • stages objesi build'ımızın yaşam döngüsünü tanımlar.
  • maven-build, docker-build ve k8s-deploy iş tanımlamalarıdır.
    • $GOOGLE_KEY Google Cloud serviste kullandığımız hesap anahtarımızdır, API Manager Section'daki Google Cloud Platform'dan edinilir.
    • kubectl create secret docker-registery ... kodu deployment.yml içinde tanımladığımız imagePullSecret objesini yaratır.

Son olarak, her şeyin yolunda olduğunu kontrol etmek adına küme aşağıdaki gibi kontrol edilebilir.

$ kubectl get deployments
NAME        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE    AGE
cdexample   2         2         2            2            2m

$ kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
cdexample-3641958612-3e5xy   1/1       Running   0          2m
cdexample-5542343546-fr4gh   1/1       Running   0          2m
Enter fullscreen mode Exit fullscreen mode

Discussion (0)