DevOpskubernetes

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS

DevSecOps CI-CD Netflix Project

DevSecOps CI-CD Netflix PROJECT

Bu makalemizde Netflix Platformunun ufak bir replicasını kod seviyesinde Güvenlik analizinden geçirecek sonrasında bir docker image yaratacağız ve bu yarattığımız imajı güvenlik analizinden geçirip cloud ve local olmak üzere birden fazla repoya gönderip Kubernetes üzerinde dağıtımını gerçekleştiriyor olacağız.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 2

Adımlar

Bu makalemizde aşağıdaki adımları izleyeceğiz.

  • Step 1a — Create an Ubuntu 24.04 T2 Large Instance
  • Step 1b — Install Jenkins, Docker,Trivy,Sonarqube on Container using Docker,Docker-Scout
  • Step 1c — Install Plugins like JDK, Sonarqube Scanner, OWASP Dependency Check
  • Step 1d — Configure Sonarqube Server in Manage Jenkins
  • Step 2a — TMBD Account configuration for API
  • Step 2b — Create a Pipeline Project in Jenkins using a Declarative Pipeline
  • Step 3a — Docker Image Build and Push
  • Step 3b — Deploy the image using Docker
  • Step 4a —-install&Configure Nexus Repostrory
  • Step 4b — Docker host configure Nexus Repostroy
  • Step 5a — Gmail Configuration
  • Step 5 — AWS EKS Kubernetes setup
  • Step 6 — Configuration Kubernets to Jenkins
  • Step 7 — Using jenkins Deploy to application on Kubernetes

Ön Gereksinimler

Jenkins Server için :

  • AWS EC2 t2.Large Machine
  • On Premis |Os:Ubuntu 24.04 | Cpu:2 Core| Ram:8GB
  • Security Group Port: 8080(Jenkins),8081,8082,8083,9000(Sonarqube),22(ssh)

Kubernetes Cluster için:

  • AWS EKS Kubernetes için AWS cli aracı

Step 1 → Jenkins Server Kurulumu

AWS üzerinde 1 adet ubuntu “T2 Large Instance” oluşturuyoruz.

Not : Eğer on prem vm üzerinde kurulum yapıyorsanız Min CPU:2 core Ram:8GB

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 3

Aşağıdaki Linkte yer alan “Install Jenkins on Ubuntu” kod bloğunu yukarıdaki bu bölüme yapıştırarak tüm kurulumu otomatik hale getirip tüm gerekli paketleri sunucumuza yüklüyoruz.

Github: https://github.com/serdarbayram01/Code_Store

işlem bitince makinemiz aşağıdaki gibi hazır olacak.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 4

Yukarıdaki Linkte yer alan komut setini AWS EC2 makinemi oluştururken “User data” bölümüne giriyorum böylelikle bu işlemleri makineye bağlanıp tek tek çalıştırmamıza gerek kalmadan AWS bizim için makine kurulum sırasında hallediyor olacak.

Eğer On-prem bir yapı kurllanıyorsanız komutları cli üzerinden tek tek çalıştırarark kurabilirsiniz.

AWS Security group (Firwall)

Firwall üzerinde yada AWS Security Group üzerinden aşağıdaki portların açık olması gerekmektedir .

Port: 8080,8081,8082,8083,9000,22,8

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 5

Jenkins Configuration

http://jenkins-server-ip:8080

adresine giderek sunucumuza bağlanıyoruz aşağıdaki sayfa bizi karşılayacak.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 6

cat /var/lib/jenkins/secrets/initialAdminPassword

Yukarıdaki komutla jenkins için oluşturulmuş parolayı alıp Jenkinsimize login oluyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 7

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 8

install Suggested Plugin seçeneği ile devam ediyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 9

Kendime bir admin hesabı oluşturacağım ekran geliyor buraya hesap bilgilerimi giriyorum.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 10

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 11

Paket Versiyon Check

birçok paket kurulumu yaptık aşağıdaki komutlarla jenkins serverımıza yüklediğimiz paketlerin kontrolünü yapıyoruz.

docker -v
docker compose --version
trivy --version
terraform --version
/usr/bin/java --version
jenkins --version
aws --version
kubectl version --client
eksctl version

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 12

docker ps -a

Bu komutla aktif durumda olan containerlarımı görüntülüyorum göründüğü gibi sonarqube serverım da container olarak çalışır durumda.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 13

Docker-Scout

Docker Inc. tarafından geliştirilen ve yazılım konteynerleri ile ilgili güvenlik, uyumluluk ve yazılım tedarik zinciri risklerini analiz etmeye odaklanan bir araçtır.

Docker Scout, özellikle Docker konteynerleri için yazılım bileşenlerini tarar ve potansiyel güvenlik açıklarını, lisans sorunlarını veya diğer riskleri belirler.

Süreçlerimizde ek bir güvenlik analiz aracı olarak süreçlerimize bu aracı da entegre edeceğiz bunun için aşağıdaki komutları kullanarak “ubuntu” userımızla komutlarımızı çalıştırıyoruz burada user “ubuntu” olmalı burayı atlarsanız CICD sürecinde docker scout u çalıştırmada sorun yaşarsınız.

#Docker hub portalımıza cli üzerinden login oluyoruz.
docker login       `Give Dockerhub credentials here`
curl -fsSL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh -o install-scout.sh
sh install-scout.sh

Yukarıdaki komutlar sonrası çıktımız aşağıdaki gibi olacaktır.

Username: serdarbayram
Password: ************
WARNING! Your password will be stored unencrypted in /home/ubuntu/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
ubuntu@ip-172-31-43-76:~$ curl -fsSL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh -o install-scout.sh
sh install-scout.sh

Sonarqube Login

http://jenkins-server-ip:9000

adresine girerek sonarqube serverımıza bağlanıyoruz.

user name :admin
Password  :admin

Yeni parola belirliyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 14

Login olduktan sonra bizi Sonarqube ekranımız karşılıyor.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 15

Sonarqube ilk adım bu kadar.

Jenkins Eklenti Kurulumları

Labımız için jenkins serverda olması gereken eklentilerin kurulumlarını yapıyoruz.

Manage Jenkins→Plugin yolunu takip ederek aşağıdaki pluginleri yüklüyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 16

  • OWASP Dependency-Check
  • Eclipse Temurin
  • Sonarqube Scanner
  • Pipeline: Stage View
  • Blue Ocean

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 17

install diyerek kurulumu başlatıyorum.

Jenkins Tools Configuration

Jenkins Manage →Tools →Jdk

jdk17” adını veriyoruz burada verdiğimiz isim oldukça önemli çünkü pipeline yazarken bu isimleri kullanacağız.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 18

OWASP Dependency Check Plugins

Jenkins Manage →Tools→Dependency-Check installations

“DP-check” adını veriyoruz burada verdiğimiz isim oldukça önemli çünkü pipeline yazarken bu isimleri kullanacağız.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 19

SonarQube Scanner Config

Jenkins Manage →Tools→SonarQube Scanner installations

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 20

“sonar-scanner” adını veriyoruz burada verdiğimiz isim oldukça önemli bir sonraki adımda sonar qube serverımızın tanımlarını yaparken bu adı kullanacağız.

Sonarqube Configuration

http://jenkins-server-ip:9000 adresine giderek sonarqube serverımıza bağlanıyoruz.

Sağ üst bölümdeki “Administrator” →My Account yolunu takip ediyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 21

“Security” bölümüne geliyoruz ve jenkins serverımızın sonarqube ile bağlantı kurup analizler için kullanacağı “jenkins” adında token credentialı “Generate” diyerek oluşturuyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 22

Bize vermiş olduğu keyi bir yere not ediyoruz bunu daha sonra kullanacağız.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 23

Webhook Configuration

SonarQube webhook’ları, bir yazılım projesinin kod kalitesi analizinin tamamlandığına dair bir web adresine bildirim göndermek için kullanılan bir mekanizmadır. Bu bildirimler, genellikle bir HTTP POST isteği şeklinde gönderilir ve içerisinde analiz sonuçlarına dair JSON formatında veriler bulunur. Bu sayede, SonarQube’da gerçekleştirilen analizlerin sonuçları, başka sistemlere veya araçlara anında iletilebilir ve otomatik işlemler tetiklenebilir.

Administration→ Configuration→Webhooks

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 24

Create Diyerek webhook umuzu oluşturuyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 25

Jenkins serverımızın public ip adresini bu alana yazarak aşağıdaki formatta giriyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 26

#in url section of quality gate
http://jenkins-public-ip:8080/sonarqube-webhook/

Jenkins Sonarqube credential

Jenkins Manage → Credential” Menüsüne gidiyoruz.

Global seçeneğini seçerek Devam ediyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 27

“Secret txt” seçeneğini seçiyoruz ve sonarqube için oluşturduğumuz token bilgisini buraya giriyoruz.

ID bölümünü “sonar-cred” olarak giriyoruz burası oldukça önemli çünkü pipeline bölümünde bu isimle çağıracağız.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 28

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 29

TMBD API yapılandırma

https://www.themoviedb.org/

The Movie Database (TMDb), filmler, diziler ve bu yapımlarla ilgili oyuncular, yönetmenler ve yapım ekipleri hakkında kapsamlı bilgiler sunan kullanıcı katkılı bir çevrimiçi platformdur. İçeriklerin fragmanlarından posterlere, oyuncu kadrolarından hikâye özetlerine kadar pek çok detay sunar.

Sunduğu API sayesinde geliştiriciler, uygulama ve web sitelerinde TMDb veritabanındaki bilgileri kullanabilir.

Bizde burada elimizdeki Netflix clonu için bu Platformda bir hesap yaratıp API Keyi alacağız ve kodumuzu dockerize ederken bu api keyi kullanacağız.

Mail hesabınızla kayıt olup login olduğunuzda aşağıdaki gibi bir sayfa sizi karşılayacak.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 30

Yukarıdaki ekranda profil resminize takılayıp Setting menüsüne gidiyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 31

Karşımıza gelen sayfada API sekmesini bulup buradaki “API key” bir yere not ediyoruz.

Bu aldığımız API key’i Docker imajı yaratırken Environment parametresi olarak kullanacağız.

Bu portaldan alacağımız bilgiler bu kadar.

Jenkins sonarqube integration

Jenkins Manage → System” Menüsüne gidiyoruz.

“Add sonarqube” diyerek sonarqube serverımıza ait yukarıda tanımladığımız bilgileri giriyoruz.

Name =”sonar-server” olarak giriyoruz.

Server URL = http://localhost:9000 # şeklinde girdim çünkü sonarqube ile jenkins serverım aynı makine, Jenkins localhost u 9000 portundan çağırdığında direk sonarqube containerına gidecek.

server authentication token : buraya credential bölümünde girdiğimiz “sonar-cred” hesabını seçiyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 32

Kaydedip çıkıyoruz.

Step2 → Projeyi Oluşturma

Dashboard → New Item“ yolunu izleyerek aşağıdaki ekranda Projemize bir isim veriyoruz “Netflix” ve pipeline ı seçerek projemizi yaratıyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 33

pipeline{
    agent any
    tools{
        jdk 'jdk17'
    }
    environment {
        SCANNER_HOME=tool 'sonar-scanner'
    }
    stages {
        stage('clean workspace'){
            steps{
                cleanWs()
            }
        }
        stage('Checkout From Git'){
            steps{
                git branch: 'main', url: 'https://github.com/serdarbayram01/Netflix.git'
            }
        }
        stage("Sonarqube Analysis "){
            steps{
                withSonarQubeEnv('sonar-server') {
                    sh ''' $SCANNER_HOME/bin/sonar-scanner -Dsonar.projectName=Netflix \
                    -Dsonar.projectKey=Netflix '''
                }
            }
        }
        stage("quality gate"){
          steps {
                script {
                    waitForQualityGate abortPipeline: false, credentialsId: 'sonar-cred'
                }
            }
        }
        stage("TRIVY File scan"){
            steps{
                sh "trivy fs . > trivy-fs_report.txt"
            }
        }

        stage('Docker Scout FS') {

           steps {

               script{

                  withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker'){

                      sh 'docker-scout quickview fs://. > scout_quickview_file_report.html'

                      sh 'docker-scout cves fs://. > scout_cves__file_report.txt'

                  }

               }  

           }

       }


        stage("OWASP Dependency Check"){
            steps{
                dependencyCheck additionalArguments: '--scan ./ --format XML ', odcInstallation: 'DP-check'
                dependencyCheckPublisher pattern: '**/dependency-check-report.xml'
            }
        }
    }
}

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 34

işlem sonucu Sonarqube baktığımızda aşağıdaki gibi bir analiz ekranı görüyor olacağız.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 35

ilk çalıştırdığınızda bu işlem yaklaşık 30~60 dk arası sürecektir. Owasp DB sini indirmek bağlantı hızı ve makine performansınıza göre değişmektedir.

Step 3 → Docker Image Build and Push

Sistemimize Docker aracını yüklememiz gerekiyor, Dashboard → Manage Plugins → Available plugins→ Docker‘ı arayın ve bu eklentileri yükleyin

  • Docker
  • Docker Commons
  • Docker Pipeline
  • Docker API
  • docker-build-step

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 36

Dashboard → Manage Jenkins → Tools
Menüsüne gidiyoruz ve docker’ın hangi versiyonla çalıştırılacağını(latest) belirliyoruz. DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 37

Docker hub (https://hub.docker.com/) hesabımızı Jenkins serverımıza tanımlıyoruz.

Dashboard → Manage Jenkins → Credential → (Global)

Burada docker hub hesap bilgilerimi girerek “docker-cred” adıyla kayıt ediyorum.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 38

Jobımıza giderek config menüsünü açıyoruz ve aşağıdaki kodları kendi repo ve hesap bilgilerinize göre düzenleyerek pipeline’ımıza ekliyoruz.

Dahsboard→ Netflix→Configure

stage('Docker Build & Push') {
            steps {
                script {
                    withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker') {
                        sh '''
                        docker build --build-arg TMDB_V3_API_KEY=d79a2ee6fafe35d7126de38adcf1df08 \
                            -t serdarbayram/netflix:latest .
                        docker push serdarbayram/netflix:latest
                        '''
                    }
                }
            }
        }

Yukarıdaki kodu incelediğinizde aşağıdaki satırda “TMDB_V3_API_KEY=” yazan yerede TMBD den aldığımız API key’i giriyoruz. Böylece uygulamamız içerikleri TMBD den çekerek güncelleyebilecek.

docker build --build-arg TMDB_V3_API_KEY=d79a2ee6fafe35d7126de38adcf1df08 -t serdarbayram/netflix:latest .

Kodumuzu çalıştırdığımızda imajımız “serdarbayram/netflix:latest” adında oluşturulmuş olacak. Tüm işlemleri başarıyla tamamladığınızda aşağıdaki gibi tamamlanmış pipline ı göreceksiniz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 39

aşağıdaki şekilde imajımızın hazır hale geldiğini görebilirsiniz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 40

Docker İmage Security Check

Buraya kadar olan bölümde uygulamamızdaki kodları güvenlik analizden geçirdik şimdi Docker imajımızı Güvenlik analizinden geçirmeye geldi.

Bunun için opensource olan “Trivy” ve ”Docker-Scout” uygulamalarını kullanacağız.

Jenkins serverımızı kurarken “Trivy” aracını otomatik kuruluma eklemiştik bunun için birşey yapmayacağız fakat Docker-scout içinde makalenin başında kurulum adımlarını anlatmıştım. Bu yüzden şu an yapmamız gereken tek şey pipeline a bu config eklemesini yapmak olacak.

stage('Trivy Image Scan') {
            steps {
                script {
                    sh '''
                    echo "Trivy ile serdarbayram/netflix:latest imajı taranıyor..."
                    trivy image serdarbayram/netflix:latest
                    '''
                }
            }
        }
        stage('Docker Scout Image') {
            steps {
                script {
                    withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker') {
                        sh 'docker-scout quickview serdarbayram/netflix:latest > scout_quickview_report.txt'
                        sh 'docker-scout cves serdarbayram/netflix:latest > scout_cves_report.txt'
                        sh 'docker-scout recommendations serdarbayram/netflix:latest > scout_recommendations_report.txt'
                        
                    }
                }
            }
        }

Yukarıdaki kodu pipeline a ekleyip job umuzu çalıştırdığımızda aşağıdaki şekilde işlemimiz in başarıyla tamamlandığını göreceğiz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 41

Yapılan “Docker Scout” analizinin dosyalarını aşağıdaki dizinde bulabilirsiniz.

# /var/lib/jenkins/workspace/<Project Name>
cd /var/lib/jenkins/workspace/Netflix

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 42

Nexus repository Kurulumu

Nexus Repository, Sonatype tarafından geliştirilmiş bir binaries repository manager (ikili depo yöneticisi) olup, yazılım geliştirme ekiplerinin bağımlılıkları, artefaktları ve Docker imajları gibi verileri merkezi olarak depolayıp yönetmesini sağlar.

Maven, Gradle, npm, PyPI, Docker, Helm, Yum gibi popüler formatlardaki verileri destekleyen Nexus, bağımlılıkların önbelleğe alınmasını, güvenliğini ve dağıtımını kolaylaştırır. Harici depolar için proxy işlevi sunarak ağ trafiğini optimize eden Nexus, CI/CD süreçleriyle entegre çalışarak yazılım geliştirme sürecini hızlandırır ve güvenli hale getirir. Hem açık kaynaklı hem de ticari sürüm (Pro) seçenekleriyle sunulan Nexus, açık kaynak dünyasında güçlü repo çözümlerinden biridir.

Biz bu projede Nexus’u local repostory olarak kullanıp docher hub dışında 2. bir repoya daha imajlarımızı göndereceğiz. Böylelikle imajlarımızı localde de kullanabilme esnekliğine kavuşacağız.

Bu projede makalenin çok uzamaması için nexus u docker container olarak kuracağım eğer production ortamında kullanmak istiyorsanız bunu ayrı bir VM üzerinde konumlandırmanızı tavsiye ederim.

Aşağıdaki komutu çalıştırarak Jenkins serveırmız üzerine Nexus3 kurulumunu yapıyoruz.

docker run -d --name nexus \
    -p 8081:8081 \
    -p 8083:8083 \
    --restart always \
    sonatype/nexus3

Nexus serverımız 8081 portundan yayın yapacak fakat bu proje için oluşturacağım repoya 8083 portundan erişim sağlayacağım bu yüzden bu portu açtım.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 43

Son çıktımız yukarıdaki gibi olacak nexus serverıma http://jenkinsServerIp:8081 yazarak erişim sağlıyorum.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 44

Aşağıdaki komutla nexus sıfırlama parolasını alıyoruz username“ admin” pass:”**” aldığımız parola . Parolamızla giriş yaptıktan sonra login oluyoruz ve kendimize ait admin parolamızı belirliyoruz.

docker exec nexus cat /nexus-data/admin.password

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 45

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 46

Nexus Repostory Yaratma

Yukarıdaki çarka tıklıyoruz ve Create repostory diyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 47

Biz docker image yükleyeceğiz (docker hosted) ı seçiyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 48

Aşağıdaki bölümleri doldurarak

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 49

Name:Netflix
Http:8083
Enable Docker Vi API:

Seçenekelerini doldurarak kayıt edip repomuzu yaratıyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 50

Sol Menüden “Realm” menüsüne geliyoruz ve “docker Bearer Token Realm” seçeneğini sağ tarafa atıyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 51

Nexus Serverdaki config işlemlerimiz bu kadar.

Jenkins ve Docker hostumuz aynı makine docker repostory’nin nexus serverımıza ulaşabilmesi için bu reponun güvenilir bir adres olması gerekiyor bunun içinde Nexus serverın ssl sertifika ile https üzerinden yayın yapması gerek fakat bu makalenin konusu bu olmadığ için biz nexus serverımızı Docker repostorysine ip adresi olarak güvenlilen repolara ekleyeceğiz Böylece Docker üzerinde oluşturduğumuz imajları nexus serverımıza yollayabilir olacağız.

Aşağıdaki komutla dosyamızı yaratıyoruz.

sudo nano /etc/docker/daemon.json

Aşağıdaki satırları yapıştırıyoruz buradaki ip adreslerini nexus serverımızın ip adresi ile değiştirmeniz gerekiyor.

{
  "insecure-registries": [
    "34.242.253.35:8083",
    "34.242.253.35:8081"
  ]
}

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 52

Bu işlem sonrası docker deamon servisimizi restart ediyoruz.

sudo systemctl restart docker

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 53

şimdi Nexus serverımıza CLI üzerinden bir bağlantı yaparak az önce açtığımız 8083 portu üzerinden bağlantı kontrolü yapıyoruz.

#sudo docker login -u admin nexus_public_dns_name:8085
sudo docker login -u admin 34.242.253.35:8083

Nexus parolamı girdiğimde aşağıdaki gibi Login succeeded bilgisini alacağız.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 54

Eğer buraya kadar hata almadan geldiysek artık Nexus repostory mize push işlemi gerçekleştirebiliriz.

image Build

Eğer kodunuzu manual şekilde derleyip build edecekseniz aşağıdaki komutu kullanabilirsiniz.

#sudo docker build . -t nexus_public_dns_name:8085/Netflix
sudo docker build . -t 34.242.253.35:8083/Netflix

imaj Tag

Fakat biz yukarıdaki adımlarda zaten imajımızı dockerhub a gönderirken “serdarbayram/netflix:latest” olarak yaratmıştık bu işlem için imajımızı yeniden tag leyeceğiz ve aşağıdaki komutu kullanacağız.

docker tag serdarbayram/netflix 34.242.253.35:8083/netflix:latest

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 55

image push

Nexus repoya Manuel ogin oluyoruz karşımıza gelen ekranda “admin”,”password” bölümlerini gidiyoruz.

docker login 34.242.253.35:8083

succeeded logunu gördüysek portumuz çalışıyor ve repomuza login olabilmişiz demektir artık imajımızı aşağıdaki komutu girerek push edebiliriz.

docker push 34.242.253.35:8083/netflix:latest

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 56

komutumuz çalıştıktan sonra yukarıdaki gibi imajımızı pushladığını görebilirsiniz. Nexus panelimize gidip kontrol sağladığımızda imajımızı aşağıdaki şekilde görüntüleyeceksiniz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 57

Nexus Jenking integration

Nexus sunucumuza başarılı bir şekilde imajlarımızı gönderebiliyoruz bunu güvenli şekilde Jenkins pipeline eklememiz gerekiyor bunun için Jenkins serverımızda Manage→Credential altında jenkins hesap bilgilerimizi giriyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 58

Jenkins üzerinde yarattığımız hesaplar aşağıdaki gibi görünüyor olmalı.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 59

Jenkins Netflix porjesine gidiyoruz ve pipeline a aşağıdaki kodu ekliyoruz.

Burada dikket etmeniz gereken yer “34.242.253.35:8083” olarak kendi nexus serverımın adresini girdiğim bölümleri değiştirmelisiniz.

stage('Nexus Image Push') {
            steps {
                script {
                    withCredentials([usernamePassword(credentialsId: 'nexus-cred', usernameVariable: 'NEXUS_USER', passwordVariable: 'NEXUS_PASS')]) {
                        sh """
                            echo $NEXUS_PASS | docker login -u $NEXUS_USER --password-stdin https://54.217.41.64:8083
                            docker tag serdarbayram/netflix 54.217.41.64:8083/netflix:latest
                            docker push 54.217.41.64:8083/netflix:latest
                        """
                    }
                }
            }
        }

Bu düzenleme sonrası job umuzu çalıştırdığımızda pipelinemızın başarıyla tamamlandığını görebilirsiniz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 60

Nexus serverımıza baktığımızda imajımızın push olduğunu ve saat bilgisini görebilirsiniz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 61

Step 4 → Public Erişim

Aşağıda sarı ile belirttiğim portların SG üzerinde açık olup olmadığının kontrollerini yaptıktan sonra web sayfamıza erişim sağlayabiliriz .

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 62

Docker imaj Deploy

Yukarıdaki tüm adımlar bir uygulamanın imaj haline gelitirlmesi,Kod güvenlik analizi, imaj güvenlik analizi ve Ayrı bir repostory e aktarılması adımlarını içeriyordu artık imajımızın analizler sonrası güvenli olduğunu biliyoruz ve imajımızı docker hostumuz üzerinde deploy edeceğiz.

Bunun için jenkins pipeline a aşağıdaki komutları ekyerek uygulamamızı 8082 portundan publish edeceğiz

stage('Deploy to Container') {
            steps {
                sh 'docker rm -f netflix'
                sh 'docker run -d --name netflix -p 8082:80 serdarbayram/netflix:latest'
            }
        }

 

işlem tamamlandığında aşağıdaki şekilde pipeline ımızı görüntüleyebiliriz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 63

docker containerlarımı kontrol ettiğimde netflix imajımın yayınlandığını görebiliyorum.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 64

http://jenkinsServerIp:8082 portundan sayfayı çağırdığımda aşağıdaki şekilde uygulamamı görüntülüyorum.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 65

Email Notification

Pipelinedaki işlemlerimiz uzun süler alabilir yada her işlem sonrası alınan aksiyondan haberdar olmak isteyebilirsiniz bunun için jenkis job’umuz tamamlandığında sistemin bize mail göndererek Mail atmasını sağlayacağız.

Security Group Conf

Bu işlemi de Gmail hesabımız üzerinden yapacağız, gmail SMTS 465 portu üzerinden haberleşir bu sebeple jenkins serverımızında 465 portundan gelen isteklere yanıt vermesi gerekiyor Serverımızın dahil olduğu Security Group a 465 portunu ekliyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 66

Gmail Account Config

Gmail hesabımızı açıyourz ve sağ üst bölümde ismimizin baş harfinin yer aldığı ikona tıklayıp ayarlara giriyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 67

Soldan Security sağda açılan sayfada 2-step-Verification seçeneğine tıklayarak devam ediyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 68

Not: Gmail Device application pass özelliğini kullanabilmeniz için hesabınızda 2 factor doğrulama ayarlarının yapılmış olması gerekiyor, Eğer sadece parola ile login seçeneği varsa bu fonksiyon karşınıza gelmeyecek yada sonraki menüleri getirmeyecektir .

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 69

Yukarıdaki ekranı en alta indirdiinizde “Application Password” Menüsü gelecek. Bir cihaz adı veriyoruz “Jenkins” verdim ben sonrasında aşağıdaki gibi bir kod veriyor sistem bize bu kodu bir yere not ediyoruz. Bu kodu şifre olarak kullanacağız.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 70

Jenkins configuration

E-mail göndermek için “Email Extension Template” jenkins eklentisine ihtiyacımız var. Manage→Plugin bölümüne gidip indiriyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 71

Manage→Credential Menüsüne giderek “Global” altında gmail hesabımız için hesap bilgilerini giriyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 72

Hesap tanımı sonrası hesap listemi aşağıdaki şekilde olacak.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 73

Manage→System Menüsüne

gidiyoruz.“Extended E-mail Notification” bölümüne geliyoruz ve aşağıdaki şekilde sunucu bilgileri ve mail hesap bilgilerini giriyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 74

E-mail Notification” bölümüne geliyoruz.

buradaki bilgileri aşağıdaki şekilde dolduruyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 75

Email Test

girdiğimiz configleri doğrulamak için bir test yapıyoruz. mail adresimizi girerek “Test config” butonuna basıyoruz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 76

Test sonrası aşağıdaki gibi bir mail posta kutunuza gelecek

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 77

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 78

son olarak default Trigger altındaki aşağıdaki ayarlarıda aktif hale getiyoruz. Başrılı ve başarısız joblarda da bize mail atacak sistem.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 79

Jenkins pipeline a aşağıdaki komut bloğunu ekliyoruz.

post {
        always {
            emailext(
                attachLog: true,
                subject: "'${currentBuild.result}'",
                body: """
                    <html>
                    <body>
                        <div style="background-color: #FFA07A; padding: 10px; margin-bottom: 10px;">
                            <p style="color: white; font-weight: bold;">Project: ${env.JOB_NAME}</p>
                        </div>
                        <div style="background-color: #90EE90; padding: 10px; margin-bottom: 10px;">
                            <p style="color: white; font-weight: bold;">Build Number: ${env.BUILD_NUMBER}</p>
                        </div>
                        <div style="background-color: #87CEEB; padding: 10px; margin-bottom: 10px;">
                            <p style="color: white; font-weight: bold;">URL: ${env.BUILD_URL}</p>
                        </div>
                    </body>
                    </html>
                """,
                to: 'AlicininMailAdresi@gmail.com',
                mimeType: 'text/html',
                attachmentsPattern: 'trivy-fs_report.txt'
            )
        }

Burada “}” işaretlerine dikkat ediyoruz son kodu ekledikten sonra hemen altında 2 adet } işareti kalacak.

Job umuzu çalıştırdıktan sonra “Declarative Post Action” staging de success bir şekilde tamamlandığını görebilirsiniz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 80

gelen mail aşağıdaki gibi görünecektir.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 81

trivy analiz ekini açtığınızda sonucu bu şekilde görüntüleyebilirsiniz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 82

Step 5 → EKS kurulumu

AWS console login

Cluster Kurulumunu cli üzerinden yapacağız ve tüm komutları “ubuntu” user hesabı üzerinden yapıyor olacağız bu adımdan sonraki kısımlarda “root” hesabında işlem yapmıyoruz çünkü bir sonraki adımda root hesabında yapılan AWS tanımı jenkins job üzerinde bize sorun çıkarıyor.

Ubuntu hesabına geçiyoruz.

sudo ubuntu

AWS cli ile yetkili bir hesapla login oluyoruz.

aws configure

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 83

Setup EKS

Step 01: Create EKS Cluster using eksctl

 # Create Cluster
eksctl create cluster --name=Lab-Cluster-1 \
                      --region=eu-west-1 \
                      --zones=eu-west-1a,eu-west-1b \
                      --without-nodegroup

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 84

# Get List of clusters 
eksctl get cluster

işlem tamamlandığında EKS panelimizde clusterımızı aşağıdaki gibi görünür olacak.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 85

Step 02: Create & Associate IAM OIDC Provider for our EKS Cluster

eksctl utils associate-iam-oidc-provider \
   --region eu-west-1 \
   --cluster Lab-Cluster-1 \
   --approve

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 86

Step 03: Create EC2 Keypair

Sanal Makineler için oluşturduğumuz bir keypair varsa bunu kullanabilirsiniz eğer yoksa yada yeni farklı birşey kullanmak isiyorsanız EC2 paneline gidip yeni bir key pair oluşturun. Oluşturduğunuz keypair EKS node makinelere gerektiğinde bağlantı için kullanılacak bu sebeple bir sonraki adımda bu key’i komut içerisinde belirteceğiz.

Ben oluşturmuş olduğum “Lab.pem” isimli key i kullanacağım

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 87

Step 04: Create Node Group with additional Add-Ons in Public Subnets

eksctl create nodegroup --cluster=Lab-Cluster-1 \
                      --region=eu-west-1 \
                      --name=Lab-cluster1-ng \
                      --node-type=t3.medium \
                      --nodes=2 \
                      --nodes-min=2 \
                      --nodes-max=4 \
                      --node-volume-size=20 \
                      --ssh-access \
                      --ssh-public-key=Lab \
                      --managed \
                      --asg-access \
                      --external-dns-access \
                      --full-ecr-access \
                      --appmesh-access \
                      --alb-ingress-access

Yukarıdaki komutu çalıştırdığımızda kuruluşumuz aşağıdaki gibi tamamlanmış olacak.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 88

Step 05: Verify Cluster & Nodes

# List EKS clusters
eksctl get cluster

# List NodeGroups in a cluster
eksctl get nodegroup --cluster=<clusterName>
eksctl get nodegroup --cluster=Lab-Cluster-1

# List Nodes in current kubernetes cluster
kubectl get nodes -o wide

# Our kubectl context should be automatically changed to new cluster
kubectl config view --minify

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 89

AWS Contex

AWS Contex bilgisini aşağıdaki komutla alıyoruz biz 1 EKS e bağlanacağımız ve “ubuntu”user hesabımız yetkili olduğu için aşağıdaki context bilgisini bir yerde kullanmayacağız bunu bilgi olarak ilerde lazım olursa diye not olarak ekledim.

kubectl config get-contexts

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 90

Tüm contex bilgisini görüntülemek için aşağıdaki komutu kullanabilirsiniz.

cat ~/.kube/config

Ubuntu user Config to Jenkins

yukarıdaki işlemlerde aws cli ı çalıştırırken ubuntu hesabını kurduk fakat jenkins root hesabı ile kuruldu dolayısıyla jenkins servisi kendi oluşturduğu “Jenkins” user’ı ile çalışıyor bunu ubuntu user ile değiştirmeliyiz ki Jenkins serverisi aws configlerini ubuntu user profili altından okuyabilsin.

Aşağıdaki komutla jenkins servisini hangi hesabın çalıştırdığını kontrol ediyoruz.

ps -awux | grep jenkins

Çıktı sonucunda da gördündüğü gibi jenkins hesabı görünüyor

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 91

Aşağıdaki dosyayı edtliyoruz “jenkins” yazan bölümleri “ubuntu” yapıyoruz.

nano /lib/systemd/system/jenkins.service

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 92

Aşağıdaki komutları çalıştırarak “ubuntu” kullanıcısına jenkins doysalarına erişmesi için gereken izinleri veriyoruz.

sudo chown -R ubuntu:ubuntu /var/lib/jenkins
sudo chown -R ubuntu:ubuntu /var/cache/jenkins
sudo chown -R ubuntu:ubuntu /var/log/jenkins
sudo chown -R ubuntu:ubuntu /usr/share/jenkins
sudo chown -R ubuntu:ubuntu /run/jenkins

Jenkins servisimizi restart ediyoruz.

sudo systemctl daemon-reload
sudo systemctl restart jenkins

Servisimiz başladıktan sonra jenkins servisimizi tekrar kontrol ettiğimizde artık “ubuntu” hesabıyla çalıştığını görüyor olmalıyız.

ps -awux | grep jenkins

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 93

Jenkins pipeline a aşağıdaki kodları “Deploy to Container” stag ten hemen sonra ekliyoruz böylece tüm pipeline tamamlanınca “Declerative Post Action” bize tüm aşamaların raporunu atacak.

stage('Deploy to k8s') {
           steps {
               dir('Kubernetes') {
                   sh 'kubectl apply -f deployment.yaml'
                   sh 'kubectl apply -f service.yaml'
                   sh 'kubectl apply -f ingress.yaml'
                   sh 'kubectl get svc'
               }
           }
       }
   }

Bu düzenlemeden sonra pipeline ımızı çalıştırdığımızda aşağıdaki şekilde tüm aşamaların başarıyla tamamlandığını görebilirsiniz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 94

Mail adresinizi kontrol ettiğinizde tüm aşamaların çıktılarının mailinizin ekinde olduğunu görebilirsiniz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 95

EKS üzerinde aldığımız Loadbalance adresimize gittiğimizde sayfanın aşağıdaki gibi görüntülendiğini görebilirsiniz.

DevSecOps Deploying a Netflix Clone CI/CD Project on AWS EKS 96

Jenkins File

pipeline {
    agent any
    tools {
        jdk 'jdk17'
    }
    environment {
        SCANNER_HOME = tool 'sonar-scanner'
    }
    stages {
        stage('Clean Workspace') {
            steps {
                cleanWs()
            }
        }
        stage('Checkout From Git') {
            steps {
                git branch: 'main', url: 'https://github.com/serdarbayram01/Netflix.git'
            }
        }
        stage('SonarQube Analysis') {
            steps {
                withSonarQubeEnv('sonar-server') {
                    sh """
                        $SCANNER_HOME/bin/sonar-scanner \
                        -Dsonar.projectName=Netflix \
                        -Dsonar.projectKey=Netflix
                    """
                }
            }
        }
        stage('Quality Gate') {
            steps {
                script {
                    timeout(time: 300, unit: 'SECONDS') {
                        def qg = waitForQualityGate()
                        if (qg.status != 'OK') {
                            error "SonarQube Quality Gate failed: ${qg.status}"
                        }
                    }
                }
            }
        }
        stage('Trivy File Scan') {
            steps {
                sh "trivy fs . > trivy-fs_report.txt"
            }
        }
        stage('Docker Scout FS') {
            steps {
                script {
                    withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker') {
                        sh 'docker-scout quickview fs://. > scout_quickview_file_report.html'
                        sh 'docker-scout cves fs://. > scout_cves__file_report.txt'
                    }
                }   
            }
        }
        stage('OWASP Dependency Check') {
            steps {
                dependencyCheck additionalArguments: '--scan ./ --format XML', odcInstallation: 'DP-check'
                dependencyCheckPublisher pattern: '**/dependency-check-report.xml'
            }
        }
        
        stage('Docker Build & Push') {
            steps {
                script {
                    withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker') {
                        sh """
                            docker build --build-arg TMDB_V3_API_KEY=d79a2ee6fafe35d7126de38adcf1df08 \
                                -t serdarbayram/netflix:latest .
                            docker push serdarbayram/netflix:latest
                        """
                    }
                }
            }
        }
        stage('Trivy Image Scan') {
            steps {
                sh """
                    echo "Trivy ile serdarbayram/netflix:latest imajı taranıyor..."
                    trivy image --format table -o trivy_image_scan_report.txt serdarbayram/netflix:latest
                """
            }
        }
        stage('Docker Scout Image') {
            steps {
                script {
                    withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker') {
                        sh """
                            docker-scout quickview serdarbayram/netflix:latest > scout_quickview_report.txt
                            docker-scout cves serdarbayram/netflix:latest > scout_cves_report.txt
                            docker-scout recommendations serdarbayram/netflix:latest > scout_recommendations_report.txt
                        """
                    }
                }
            }
        }
        stage('Nexus Image Push') {
            steps {
                script {
                    withCredentials([usernamePassword(credentialsId: 'nexus-cred', usernameVariable: 'NEXUS_USER', passwordVariable: 'NEXUS_PASS')]) {
                        sh """
                            echo $NEXUS_PASS | docker login -u $NEXUS_USER --password-stdin https://3.250.171.35:8083
                            docker tag serdarbayram/netflix 3.250.171.35:8083/netflix:latest
                            docker push 3.250.171.35:8083/netflix:latest
                        """
                    }
                }
            }
        }
        stage('Deploy to Container') {
            steps {
                sh 'docker rm -f netflix || true'
                sh 'docker run -d --name netflix -p 8082:80 serdarbayram/netflix:latest'
            }
        }
        stage('Deploy to k8s') {
            steps {
                dir('Kubernetes') {
                    sh 'kubectl apply -f deployment.yaml'
                    sh 'kubectl apply -f service.yaml'
                    sh 'kubectl get svc'
                }
            }
        }
    }
    post {
        always {
            emailext(
                attachLog: true,
                subject: "'${currentBuild.result}'",
                body: """
                    <html>
                    <body>
                        <div style="background-color: #FFA07A; padding: 10px; margin-bottom: 10px;">
                            <p style="color: white; font-weight: bold;">Project: ${env.JOB_NAME}</p>
                        </div>
                        <div style="background-color: #90EE90; padding: 10px; margin-bottom: 10px;">
                            <p style="color: white; font-weight: bold;">Build Number: ${env.BUILD_NUMBER}</p>
                        </div>
                        <div style="background-color: #87CEEB; padding: 10px; margin-bottom: 10px;">
                            <p style="color: white; font-weight: bold;">URL: ${env.BUILD_URL}</p>
                        </div>
                    </body>
                    </html>
                """,
                to: 'serdarbayram01@gmail.com',
                mimeType: 'text/html',
                attachmentsPattern: 'trivy*,scout*,dependency-check-report.xml'
            )
        }
    }
}

Serdar Bayram

Bu yazı blog üzerinde Serdar Bayram tarafından hazırlanıp paylaşılmıştır. 2009 yılında açılan blogum kısa zaman içerisinde paylasımları ile dikkat cekip büyük bir izleyici kitlesine sahip olmuştur.

İlgili Makaleler

Bir yanıt yazın

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

Başa dön tuşu