iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0
DevOps

第一次參賽就學 Kubernetes系列 第 29

[Day 29] 使用 Jenkins 建置 CI/CD Pipeline 專案 (二)

  • 分享至 

  • xImage
  •  

再貼一次流程。

流程

相關流程如下。

  1. Fork 專案
  2. 建立 AWS EC2
  3. 安裝 Jenkins
  4. 設定 Sonar Server
  5. 安裝 Docker
  6. 啟動 minikube
  7. 安裝 Argo CD Operator
  8. JenkinsFile 說明
  9. Build Pipeline
  10. 設定 Argo CD 自動部署

6. 啟動 minikube

在本機安裝 minikube 相關安裝方法請參考官方網站

開啟終端器啟動 minikube。

minikube start

7. 安裝 Argo CD Operator

透過 Operators 在叢集上安裝 Argo CD Operator。前往 OperatorHub 下載 Argo CD Operator。

使用 Argo CD Operator 來管理 Argo CD 與其元件的生命週期,包含安裝、升級 (upgrade)、備份和 Autoscale 等。

這邊只要照著 Install 指示下載 Argo CD。

8. JenkinsFile 說明

講解 clone 這份專案後,其中的 https://github.com/iam-veeramalla/Jenkins-Zero-To-Hero/blob/main/java-maven-sonar-argocd-helm-k8s/spring-boot-app/JenkinsFile 檔案,Jenkins 會參照這份檔案來執行作業。

pipeline {
  agent {
    docker {
      image 'abhishekf5/maven-abhishek-docker-agent:v1'
      args '--user root -v /var/run/docker.sock:/var/run/docker.sock' // mount Docker socket to access the host's Docker daemon
    }
  }
  stages {
    stage('Checkout') {
      steps {
        sh 'echo passed'
        // git branch: 'main', url: 'https://github.com/your-username/Jenkins-Zero-To-Hero.git'
      }
    }
    stage('Build and Test') {
      steps {
        sh 'ls -ltr'
        // build the project and create a JAR file
        sh 'cd java-maven-sonar-argocd-helm-k8s/spring-boot-app && mvn clean package'
      }
    }
    stage('Static Code Analysis') {
      environment {
        SONAR_URL = "http://ec2-public-ip-address:9000"
      }
      steps {
        withCredentials([string(credentialsId: 'sonarqube', variable: 'SONAR_AUTH_TOKEN')]) {
          sh 'cd java-maven-sonar-argocd-helm-k8s/spring-boot-app && mvn sonar:sonar -Dsonar.login=$SONAR_AUTH_TOKEN -Dsonar.host.url=${SONAR_URL}'
        }
      }
    }
    stage('Build and Push Docker Image') {
      environment {
        DOCKER_IMAGE = "your-dockerhub-username/ultimate-cicd:${BUILD_NUMBER}"
        // DOCKERFILE_LOCATION = "java-maven-sonar-argocd-helm-k8s/spring-boot-app/Dockerfile"
        REGISTRY_CREDENTIALS = credentials('docker-cred')
      }
      steps {
        script {
            sh 'cd java-maven-sonar-argocd-helm-k8s/spring-boot-app && docker build -t ${DOCKER_IMAGE} .'
            def dockerImage = docker.image("${DOCKER_IMAGE}")
            docker.withRegistry('https://index.docker.io/v1/', "docker-cred") {
                dockerImage.push()
            }
        }
      }
    }
    stage('Update Deployment File') {
        environment {
            GIT_REPO_NAME = "Jenkins-Zero-To-Hero"
            GIT_USER_NAME = "your-github-username"
        }
        steps {
            // GitHub credentials
            withCredentials([string(credentialsId: 'github', variable: 'GITHUB_TOKEN')]) {
                sh '''
                    git config user.email "your-email@gmail.com"
                    git config user.name "your-github-username"
                    BUILD_NUMBER=${BUILD_NUMBER}
                    sed -i "s/replaceImageTag/${BUILD_NUMBER}/g" java-maven-sonar-argocd-helm-k8s/spring-boot-app-manifests/deployment.yml
                    git add java-maven-sonar-argocd-helm-k8s/spring-boot-app-manifests/deployment.yml
                    git commit -m "Update deployment image to version ${BUILD_NUMBER}"
                    git push https://${GITHUB_TOKEN}@github.com/${GIT_USER_NAME}/${GIT_REPO_NAME} HEAD:main
                '''
            }
        }
    }
  }
}

說明

  1. stage('Checkout'): 是當 JenkinsFile 與 repo 不同地方時使用,因為都放在同個地方,所以這邊單純顯示文字。
  2. stage('Build and Test'): 這裡會下載 packages、build JAR 檔,另 maven 已安裝在 abhishekf5/maven-abhishek-docker-agent 這個 image 裡。
  3. stage('Static Code Analysis'): 這裡需要修改 SONAR_URL,替換成 ec2 的 IP address,使 Jenkins 可以將通知傳給 Sonarqube server。其中會使用到先前在 Jenkins 加入的 SonarQube Credentials。
  4. stage('Build and Push Docker Image'): 這裡會需要將 build 好的 image 上傳到 DockerHub,並讓 Argo CD 可以部署至叢集,會須需要一個 docker credential。
    • 修改 DOCKER_IMAGE = "your-dockerhub-username/ultimate-cicd:${BUILD_NUMBER}"
    • 這裡需要 DockerHub credentials 來更新不同版本的 image (在 ec2 build image 並上傳至 DockerHub)。
  5. stage('Update Deployment File'): 這邊輸入 GIT_REPO_NAME、GIT_USER_NAME 可以是與原先不同的 GitHub repo,修改 GIT_USER_NAME = "your-github-username"
    • 開啟 repo 上 java-maven-sonar-argocd-helm-k8s/spring-boot-app-manifests/deployment.yml 檔案,修改內容如下。

      image: your-dockerhub-username/ultimate-cicd:replaceImageTag
      
    • deployment.yaml 被異動後,Argo CD 會重新拉一版替換並自動部署至叢集上。

    • 這邊會需要 GitHub credential 來更新 repo,故要修改 user.emailuser.name


以上內容修改好後,回到 Jenkins 中加入 2 個 Global credentials。

  1. DokcerHub credential
    • Kind: Username with password
    • 輸入帳號密碼
    • ID: docker-cred
  2. GitHub credential
    • Kind: Secret text
    • 前往 GitHub → Settings → Developer Settings → Personal access tokens → Tokens(classic) → 建立 personal access token → 輸入 Note、選擇 scopes
    • 輸入 Secret
    • ID: github

確認修改 SONAR_URL 後,重新啟動 Jenkins。

前往網址 http://ec2-public-ip-address:8080/restart,重新啟動 Jenkins。

接著確認剛拉下來的 Argo CD 是否有 running,如果 ok 就可以到 Jenkins 上開始 build pipeline。

kubectl get po -n operators

NAME                                                 READY   STATUS    RESTARTS        AGE
argocd-operator-controller-manager-9fb5d5689-lq76k   2/2     Running   5 (7m18s ago)   22h

9. Build Pipeline

到 Jenkins 上的作業按下「馬上建置」,點擊 #1 查看 Console Output。

  • mvn clean packages 下載 packages、建立 JAR 檔。
  • mvn sonar:sonar 將分析報告送至 SonarQube Server,可以前往 server 上查看。
  • 接著會在本地建立 image,並上傳至 DockerHub,可以觀察 ec2 及 DockerHub 上的 image、${BUILD_NUMBER}(Tag)。

在 ec2 輸入以下指令查看 image。

docker images

REPOSITORY                               TAG       IMAGE ID       CREATED          SIZE
your-dockerhub-username/ultimate-cicd                  2         8613aeb0622f   11 minutes ago   170MB
abhishekf5/maven-abhishek-docker-agent   v1        3fb9145e2467   6 months ago     913MB

在 DockerHub 上查看。

https://ithelp.ithome.com.tw/upload/images/20231027/20162511r74CkBFzzr.png

另外以上的 Tag 是 Jenkins 上的建置 # 編號,在 image 上就會顯示 ultimate-cicd:13。

https://ithelp.ithome.com.tw/upload/images/20231027/20162511OnzyZzq6fw.png

在 SonarQube Server 上查看。

https://ithelp.ithome.com.tw/upload/images/20231027/201625119Zv5x8abGP.png

10. 設定 Argo CD 自動部署

當 Argo CD Operator 安裝好後,部署一個 Argo CD 的叢集 argo.yaml

vim argo.yaml
apiVersion: argoproj.io/v1alpha1
kind: ArgoCD
metadata:
  name: example-argocd
spec: {}

建立 pod。

kubectl apply -f argo.yaml

argocd.argoproj.io/example-argocd created

顯示 Argo CD 相關元件。

kubectl get pods

NAME                                          READY   STATUS    RESTARTS        AGE
example-argocd-application-controller-0       1/1     Running   2 (3m25s ago)   21h
example-argocd-redis-6b8667cdb8-j96mq         1/1     Running   2 (3m25s ago)   21h
example-argocd-repo-server-5d547c6f69-4tgpd   1/1     Running   2 (3m25s ago)   21h
example-argocd-server-bbdf5fdff-jnhws         1/1     Running   4 (3m25s ago)   21h

接著要存取 Argo CD 的 Web UI,修改 Argo CD 的 service 以便從瀏覽器存取,將 ClusterIP 修改成 NodePort

kubectl get svc

NAME                            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
example-argocd-metrics          ClusterIP   10.102.219.168   <none>        8082/TCP            20s
example-argocd-redis            ClusterIP   10.109.174.6     <none>        6379/TCP            20s
example-argocd-repo-server      ClusterIP   10.108.105.154   <none>        8081/TCP,8084/TCP   19s
example-argocd-server           ClusterIP   10.105.249.197   <none>        80/TCP,443/TCP      19s
example-argocd-server-metrics   ClusterIP   10.101.3.153     <none>        8083/TCP            19s
kubernetes                      ClusterIP   10.96.0.1        <none>        443/TCP             32d
kubectl edit svc example-argocd-server

service/example-argocd-server edited

查看修改後的 service。

kubectl get svc

NAME                            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
example-argocd-metrics          ClusterIP   10.102.219.168   <none>        8082/TCP                     22h
example-argocd-redis            ClusterIP   10.109.174.6     <none>        6379/TCP                     22h
example-argocd-repo-server      ClusterIP   10.108.105.154   <none>        8081/TCP,8084/TCP            22h
example-argocd-server           NodePort    10.105.249.197   <none>        80:30597/TCP,443:32436/TCP   22h
example-argocd-server-metrics   ClusterIP   10.101.3.153     <none>        8083/TCP                     22h
kubernetes                      ClusterIP   10.96.0.1        <none>        443/TCP                      33d

minikube 可以透過 minikube service <service-name> 指令回傳一個 url、使用瀏覽器來存取。

minikube service example-argocd-server --url

http://127.0.0.1:50732
http://127.0.0.1:50733
❗  Because you are using a Docker driver on darwin, the terminal needs to be open to run it.

複製 argocd-server 的 URL (http://127.0.0.1:50733) 至瀏覽器之前,先準備 Argo CD 的 Web UI 帳密。

Argo CD 密碼

進入 Argo CD 要輸入帳密,帳號是 admin,密碼要另外從 secret 取得,取得方式如下。

kubectl get secret

NAME                                         TYPE                 DATA   AGE
argocd-secret                                Opaque               5      6m43s
example-argocd-ca                            kubernetes.io/tls    3      6m44s
example-argocd-cluster                       Opaque               1      6m44s
example-argocd-default-cluster-config        Opaque               4      6m43s
example-argocd-tls                           kubernetes.io/tls    2      6m43s

kubectl edit secret example-argocd-cluster

複製當中的密碼後需要解碼,因為在 Secret 中是以 base64 編碼儲存。

echo eVk5bU9jV1FoZ05xeGJ2a1pDc25UdTVlOEkwTEo3TW8= | base64 -d

回到 Argo CD Web 輸入帳密登入,在 Argo CD 叢集部署一開始提到的應用程式。

輸入以下:

  1. Application Name:ultimate-cicd
  2. Project Name:default
  3. SYNC POLICY:Automatic
  4. SOURCE Repository URL:這邊輸入專案底下的 deploymenthttps://github.com/your-github-username/Jenkins-Zero-To-Hero (GIT)
  5. Path: java-maven-sonar-argocd-helm-k8s/spring-boot-app-manifests(到目錄就好)
  6. DESTINATION Cluster URL:https://kubernetes.default.svc
  7. NAMESPACE: default

→ Create。

Argo CD 會自動取抓 GitHub 上的 repo 並部署在本地的叢集上。若 Argo CD Web 上顯示 Healthy,可以前往叢集查看是否部署成功。

https://ithelp.ithome.com.tw/upload/images/20231027/20162511OFimJBmmB5.png

查看 deployment。

kubectl get deploy

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
example-argocd-redis         1/1     1            1           22h
example-argocd-repo-server   1/1     1            1           22h
example-argocd-server        1/1     1            1           22h
spring-boot-app              2/2     2            2           40s

kkubectl get po

NAME                                          READY   STATUS    RESTARTS      AGE
example-argocd-application-controller-0       1/1     Running   2 (21m ago)   22h
example-argocd-redis-6b8667cdb8-j96mq         1/1     Running   2 (21m ago)   22h
example-argocd-repo-server-5d547c6f69-4tgpd   1/1     Running   2 (21m ago)   22h
example-argocd-server-bbdf5fdff-jnhws         1/1     Running   4 (21m ago)   22h
spring-boot-app-6889fc68f8-5p2xd              1/1     Running   0             58s
spring-boot-app-6889fc68f8-lmr9k              1/1     Running   0             58s

查看自動部署的程式,使用 minikube service spring-boot-app-service --url 產生 url,並用瀏覽器輸入該 url 觀看部署程式。

ku get svc

NAME                            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
example-argocd-metrics          ClusterIP   10.102.219.168   <none>        8082/TCP                     22h
example-argocd-redis            ClusterIP   10.109.174.6     <none>        6379/TCP                     22h
example-argocd-repo-server      ClusterIP   10.108.105.154   <none>        8081/TCP,8084/TCP            22h
example-argocd-server           NodePort    10.105.249.197   <none>        80:30597/TCP,443:32436/TCP   22h
example-argocd-server-metrics   ClusterIP   10.101.3.153     <none>        8083/TCP                     22h
kubernetes                      ClusterIP   10.96.0.1        <none>        443/TCP                      33d
spring-boot-app-service         NodePort    10.100.49.236    <none>        80:32193/TCP                 12m

minikube service spring-boot-app-service --url

http://127.0.0.1:50997
❗  Because you are using a Docker driver on darwin, the terminal needs to be open to run it.

https://ithelp.ithome.com.tw/upload/images/20231029/20162511UDjjh6nuwu.png

修改 GitHub 上的程式、並在 Jenkins 執行建置作業,修改後的程式。

https://ithelp.ithome.com.tw/upload/images/20231029/20162511tuUrIKV3fy.png


照著教學一步步來學習如何使用 Jenkins、SonarQube 和 Argo CD 等多個工具來建置自動化流程,除了讓自己熟悉工具的使用方式,也能瞭解目前有哪些資源可以執行 CI/CD 任務。


上一篇
[Day 28] 使用 Jenkins 建置 CI/CD Pipeline 專案 (一)
下一篇
[Day 30] Kubernetes 學習資源 & 反思
系列文
第一次參賽就學 Kubernetes30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言