阿川私房教材:
學 JavaScript 前端,帶作品集去面試!

63 個專案實戰,寫出作品集,讓面試官眼前一亮!

立即開始免費試讀!

專案橫幅

介紹

在當今快節奏的軟體開發環境中,實施 DevOps 實踐對於追求敏捷性、效率和高品質軟體交付的組織至關重要。此專案示範如何使用Jenkins實現強大的持續整合/持續部署 (CI/CD)管線,從而自動化從開發到部署的整個軟體生命週期。

建築學

CI/CD 架構

目標

該計畫的主要目標是實現軟體交付自動化,提高速度、可靠性和效率,同時最大限度地減少人工幹預。主要目標包括:

  • 自動化 CI/CD 管道:實施基於 Jenkins 的無縫 CI/CD 管道,以簡化建置、測試和部署流程。

  • DevOps 工具的整合:利用Maven、SonarQube、Trivy、Nexus Repository、Docker、Kubernetes、Prometheus 和 Grafana實現端對端自動化。

  • 程式碼品質和安全性:透過靜態程式碼分析(SonarQube)安全漏洞掃描(Trivy)來提高軟體品質。

  • 可擴充部署:確保Kubernetes 叢集上的部署可靠、可擴充且負載平衡

  • 自動通知:啟用建置和部署狀態的電子郵件警報

  • 強大的監控和警報:實施Prometheus 和 Grafana進行即時系統健康監控和效能分析。

使用的工具和技術

|工具|目的|

|----------|------------|

|詹金斯| CI/CD 管道編排 |

| Maven |建置自動化與依賴管理 |

| SonarQube |靜態程式碼分析以確保品質 |

|瑣事| Docker 映像漏洞掃描 |

| Nexus 儲存庫|工件管理與版本控制 |

| Docker |容器化以實現一致性和可移植性 |

| Kubernetes |用於可擴充部署的容器編排 |

| Gmail 整合|建置與部署更新的電子郵件通知 |

| Prometheus 和 Grafana |系統指標的監控和視覺化 |

| AWS EC2 |基礎架構配置與託管 |


基礎架構設定:AWS 上的虛擬機

為了支援此管道, AWS EC2 執行個體配備了各種 DevOps 工具:

🔹 Kubernetes 主節點:管理叢集狀態、調度和協調。

🔹 Kubernetes 工作節點(2) :託管並執行容器化應用程式。

🔹SonarQube 伺服器:執行靜態程式碼分析,確保程式碼品質。

🔹 Nexus Repository Manager :管理建置工件、依賴項和 Docker 映像。

🔹 Jenkins 伺服器:協調 CI/CD 流程並整合 DevOps 工具。

🔹監控伺服器:執行Prometheus 和 Grafana進行即時系統監控。

每個實例都配置了必要的 CPU、記憶體和儲存資源。採用存取控制和網路配置等安全最佳實務來保護基礎架構。

EC2 執行個體:

安全群組:


使用 Kubeadm 設定 Kubernetes 集群

先決條件

  • 具有sudo 權限Ubuntu 作業系統(Xenial 或更高版本)

  • t2.medium實例類型或更高版本

  • 網路存取

  • 確保所有 AWS 執行個體都位於相同安全性群組

  • 開啟連接埠 6443以允許工作節點加入集群


1️⃣ 準備 Kubernetes 安裝節點

Master 節點和 Worker 節點上分別執行下列命令:

# Disable swap
sudo swapoff -a

載入所需的核心模組:

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

設定sysctl參數:

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF

sudo sysctl --system

2️⃣ 安裝 CRI-O 執行階段

sudo apt-get update -y
sudo apt-get install -y software-properties-common curl apt-transport-https ca-certificates gpg

sudo curl -fsSL https://pkgs.k8s.io/addons:/crio:/prerelease:/main/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/cri-o-apt-keyring.gpg

echo "deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg] https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/ /" | sudo tee /etc/apt/sources.list.d/cri-o.list

sudo apt-get update -y
sudo apt-get install -y cri-o
sudo systemctl enable crio --now

3️⃣ 安裝 Kubernetes 軟體包

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update -y
sudo apt-get install -y kubelet=1.29.0-* kubectl=1.29.0-* kubeadm=1.29.0-*

4️⃣ 在主節點上初始化 Kubernetes 集群

sudo kubeadm config images pull
sudo kubeadm init

mkdir -p "$HOME"/.kube
sudo cp -i /etc/kubernetes/admin.conf "$HOME"/.kube/config
sudo chown "$(id -u)":"$(id -g)" "$HOME"/.kube/config

安裝Calico作為網頁外掛:

kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.0/manifests/calico.yaml

檢索工作節點的加入指令

kubeadm token create --print-join-command

5️⃣加入工作節點

執行從主節點取得的加入命令

sudo kubeadm join <master-ip>:6443 --token <your-token> --discovery-token-ca-cert-hash sha256:<hash> --v=5

在主節點上驗證叢集狀態:

kubectl get nodes


設定 DevOps 工具

Jenkins 安裝

sudo apt install openjdk-17-jre-headless -y
wget -O /usr/share/keyrings/jenkins-keyring.asc https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/" | sudo tee /etc/apt/sources.list.d/jenkins.list
sudo apt-get update
sudo apt-get install jenkins -y

Docker 安裝

sudo apt-get update
sudo apt-get install -y ca-certificates curl

sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io

Nexus 儲存庫設置

docker run -d --name nexus -p 8081:8081 sonatype/nexus3:latest

檢索 Nexus管理員密碼

docker exec -it <container_id> cat /nexus-data/admin.password

第 2 部分:設定私有 Git 儲存庫

請依照下列步驟建立私有 Git 儲存庫,產生個人存取令牌,連接到儲存庫並安全地推送程式碼。

1. 建立私有 Git 儲存庫

  • 登入您喜歡的 Git 託管平台(例如,GitHub、GitLab、Bitbucket)。

  • 導航到“存儲庫”部分。

  • 按一下「新儲存庫」並將其可見性設為「私人」

  • 複製儲存庫 URL 以供稍後使用。

2. 產生個人存取權令牌 (PAT)

  • 前往您的帳戶設定

  • 找到開發人員設定(GitHub)或存取令牌部分(GitLab、Bitbucket)。

  • 產生具有所需權限的新個人存取權杖 (PAT) ,例如:

  • repo (用於完全存取儲存庫)

  • 讀取:包(如果存取包)

  • 複製並安全地保存令牌,因為它不會再次顯示。

3. 本地克隆儲存庫

  • 打開終端機或 Git Bash。

  • 導航到您想要儲存儲存庫的目錄。

  • 執行以下命令,將<repository_URL>替換為您的實際儲存庫連結:

  git clone <repository_URL>
  • 導航到克隆的儲存庫資料夾:
  cd <repository_name>

4. 將程式碼加入儲存庫

  • 在儲存庫目錄內移動或建立專案檔案。

5. 暫存並提交變更

  • 暫存所有文件供提交:
  git add .
  • 使用有意義的訊息提交暫存的變更:
  git commit -m "Initial commit: Added project files"

6. 將變更推送到私有儲存庫

  • 將您的變更推送到遠端儲存庫:
  git push
  • 如果這是你第一次推送,請設定上游分支並推送:
  git push -u origin main

(如果適用,請將main替換為master或任何其他分支名稱。)

7. 使用個人存取權令牌進行身份驗證

  • 當系統提示輸入憑證時:

  • 使用者名稱:輸入您的 GitHub/GitLab/Bitbucket 使用者名稱。

  • 密碼:使用個人存取權令牌(PAT)而不是您的密碼。

8.驗證推播

  • 前往您的 Git 託管平台並開啟儲存庫。

  • 您應該會看到提交的文件已成功上傳。


第 3 部分:Jenkins 中的 CI/CD 設定

安裝所需的 Jenkins 插件

在設定 CI/CD 管道之前,請安裝以下 Jenkins 外掛程式:

  1. Eclipse Temurin 安裝程序
  • 使 Jenkins 安裝和設定 Eclipse Temurin JDK (以前稱為 AdoptOpenJDK)。

  • 前往Jenkins 儀表板 → 管理 Jenkins → 管理外掛程式 → 可用標籤。

  • 搜尋Eclipse Temurin Installer ,選擇它,然後點擊Install without restart

  1. 管道 Maven 集成
  • 為 Jenkins Pipelines 加入 Maven 支持,允許在腳本中使用 Maven 命令。

  • 透過在外掛程式管理器中搜尋Pipeline Maven Integration來安裝它。

  1. 設定檔提供者
  • 允許在 Jenkins 中集中儲存設定檔(屬性、XML、JSON)。

  • 透過插件管理器安裝。

  1. SonarQube 掃描儀
  • 整合 SonarQube 以便在建置期間進行程式碼品質和安全分析。

  • 在插件管理器中搜尋SonarQube Scanner並安裝它。

  1. Kubernetes CLI
  • 使 Jenkins 能夠使用kubectl與 Kubernetes 叢集互動。

  • 從插件管理器安裝它。

  1. Kubernetes 插件
  • 允許 Jenkins 代理程式作為 Kubernetes pod 執行,實現動態擴展。

  • 透過插件管理器安裝。

  1. Docker 插件
  • 使 Jenkins 能夠與 Docker 互動以建置和管理容器。

  • 從插件管理器安裝它。

  1. Docker 管道插件
  • 透過建置、發布和管理 Docker 容器的步驟來擴展 Jenkins Pipeline。

  • 透過插件管理器安裝它。

安裝後,在管理 Jenkins → 全域工具配置中配置這些插件,並在需要時設定憑證。


建立 Jenkins CI/CD 管道

安裝插件後,在 Jenkins 中建立一個新的Pipeline作業並使用以下腳本:

Jenkinsfile:用於 Java 應用程式部署的 CI/CD 管道

pipeline {
    environment {
        SCANNER_HOME = tool 'sonar-scanner'
    }
    tools {
        jdk 'jdk17'
        maven 'maven3'
    }
    stages {
        stage('Git Checkout') {
            steps {
                git branch: 'main', credentialsId: 'git-cred', url: 'https://github.com/jaiswaladi246/Boardgame.git'
            }
        }
        stage('Compile') {
            steps {
                sh "mvn compile"
            }
        }
        stage('Run Tests') {
            steps {
                sh "mvn test"
            }
        }
        stage('Trivy File System Scan') {
            steps {
                sh "trivy fs --format table -o trivy-fs-report.html ."
            }
        }
        stage('SonarQube Code Analysis') {
            steps {
                withSonarQubeEnv('sonar') {
                    sh '''
                    $SCANNER_HOME/bin/sonar-scanner -Dsonar.projectName=BoardGame -Dsonar.projectKey=BoardGame -Dsonar.java.binaries=.
                    '''
                }
            }
        }
        stage('Quality Gate Check') {
            steps {
                script {
                    waitForQualityGate abortPipeline: false, credentialsId: 'sonar-token'
                }
            }
        }
        stage('Build Artifact') {
            steps {
                sh "mvn package"
            }
        }
        stage('Publish Artifacts to Nexus') {
            steps {
                withMaven(globalMavenSettingsConfig: 'global-settings', jdk: 'jdk17', maven: 'maven3', traceability: true) {
                    sh "mvn deploy"
                }
            }
        }
        stage('Build and Tag Docker Image') {
            steps {
                script {
                    withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker') {
                        sh "docker build -t jaiswaladi246/Boardgame:latest ."
                    }
                }
            }
        }
        stage('Docker Image Security Scan') {
            steps {
                script {
                    withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker') {
                        sh "trivy image --format table -o trivy-image-report.html jaiswaladi246/Boardgame:latest"
                    }
                }
            }
        }
        stage('Push Docker Image to Registry') {
            steps {
                script {
                    withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker') {
                        sh "docker push jaiswaladi246/Boardgame:latest"
                    }
                }
            }
        }
        stage('Deploy to Kubernetes') {
            steps {
                withKubeConfig(credentialsId: 'k8-cred', namespace: 'webapps', serverUrl: 'https://172.31.8.22:6443') {
                    sh "kubectl apply -f deployment-service.yaml"
                    sh "kubectl get pods -n webapps"
                }
            }
        }
    }
    post {
        always {
            script {
                def jobName = env.JOB_NAME
                def buildNumber = env.BUILD_NUMBER
                def pipelineStatus = currentBuild.result ?: 'UNKNOWN'
                def body = """
                ${jobName} - Build ${buildNumber}
                Pipeline Status: ${pipelineStatus.toUpperCase()}
                Check the console output.
                """
                emailext(
                    subject: "${jobName} - Build ${buildNumber} - ${pipelineStatus.toUpperCase()}",
                    body: body,
                    to: '[email protected]',
                    from: '[email protected]',
                    replyTo: '[email protected]',
                    mimeType: 'text/html',
                    attachmentsPattern: 'trivy-image-report.html'
                )
            }
        }
    }
}

管道故障

  1. Git 簽出
  • 使用憑證從 GitHub 克隆專案。
  1. 建置和測試
  • 使用 Maven 編譯專案並執行測試。
  1. 安全掃描
  • 使用 Trivy 掃描檔案系統和 Docker 映像中是否有漏洞。
  1. SonarQube 程式碼分析
  • 執行 SonarQube 掃描以尋找程式碼品質和安全性問題。
  1. 質量門檢查
  • 確保在繼續之前通過 SonarQube 品質門。
  1. 建置和發布工件
  • 打包應用程式並將其推送至 Nexus。
  1. Docker 映像建置與推送
  • 建立 Docker 映像並將其推送至註冊表。
  1. 部署到 Kubernetes
  • 使用kubectl將應用程式部署到 Kubernetes 叢集。
  1. 通知
  • 發送包含管道狀態和 Trivy 安全報告的電子郵件通知。

第 4 部分:監控設定

Prometheus 安裝和設置

下載 Prometheus 和 Exporters

  • 從以下網址下載 Prometheus、Node Exporter 和 Blackbox Exporter:

👉 Prometheus 下載

安裝並執行 Prometheus

  1. 解壓縮下載的.tar.gz檔。

  2. 導航到解壓縮的目錄並執行:

   ./prometheus &
  1. 預設情況下,Prometheus 在連接埠 9090上執行。

  2. 在瀏覽器中存取:

   http://<instance_IP>:9090

安裝並執行 Blackbox Exporter

  1. 提取 Blackbox Exporter .tar.gz檔。

  2. 導航到解壓縮的目錄並執行:

   ./blackbox_exporter &

Grafana 安裝和設置

下載並安裝 Grafana

  • 從以下位置下載 Grafana:

👉 Grafana 下載

或者,在 Ubuntu 上安裝 Grafana

監控虛擬機器上執行以下命令:

sudo apt-get install -y adduser libfontconfig1 musl
wget https://dl.grafana.com/enterprise/release/grafana-enterprise_10.4.2_amd64.deb
sudo dpkg -i grafana-enterprise_10.4.2_amd64.deb

啟動 Grafana 服務

sudo /bin/systemctl start grafana-server
  • Grafana 預設在連接埠 3000上運作。

  • 在瀏覽器中存取:

  http://<instance_IP>:3000

配置 Prometheus

修改 Prometheus 配置( prometheus.yaml

編輯檔案以包含 Blackbox Exporter:

scrape_configs:
  - job_name: 'blackbox'
    metrics_path: /probe
    params:
      module: [http_2xx]  # Checks for HTTP 200 response
    static_configs:
      - targets:
        - http://prometheus.io  # HTTP Target
        - https://prometheus.io # HTTPS Target
        - http://example.com:8080  # HTTP on port 8080
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: <instance_IP>:9115
  • <instance_IP>替換為您伺服器的 IP 位址。

重新啟動 Prometheus

  1. 尋找 Prometheus 進程 ID:
   pgrep prometheus
  1. 終止現有進程並重新啟動 Prometheus。

在 Grafana 中加入 Prometheus 作為資料來源

  1. 登入 Grafanahttp://<instance_IP>:3000 )。

  2. 導航至設定 → 資料來源 → 新增資料來源

  3. 選擇Prometheus作為源。

  4. 輸入Prometheus 伺服器 URL ( http://<instance_IP>:9090 )。

  5. 儲存並測試連接。

  6. 從 Grafana 的公共儀表板庫導入Prometheus 儀表板

🚀您使用 Prometheus 和 Grafana 的監控設定現已準備就緒!


結果:

詹金斯管道:

普羅米修斯:

黑盒子:

格拉法納:

應用:

結論

DevOps CI/CD管線專案的成功實施,是提升軟體交付流程效率、可靠性和品質的重要里程碑。透過自動化軟體開發生命週期的關鍵環節(包括編譯、測試、部署和監控),該專案實現了快速、一致地交付軟體版本,有助於縮短產品上市時間並提高客戶滿意度。

致謝貢獻

我要對DevOps Shack的出色專案和實施指南表示感謝。

最後的想法

展望未來,該專案的影響不僅限於其直接利益,還為軟體開發實踐的持續改進和創新鋪平了道路。透過採用 DevOps 原則並利用尖端工具和技術,我們為未來專案的發展奠定了堅實的基礎。 CI/CD 管道的可擴展性、靈活性和彈性確保了它能夠適應不斷變化的需求和技術進步,使我們的組織在競爭激烈的市場環境中獲得長期成功。

參考

  1. Jenkins 文件: https://www.jenkins.io/doc/

  2. Maven 文件: https://maven.apache.org/guides/index.html

  3. SonarQube 文件: https://docs.sonarqube.org/latest/

  4. Trivy 文件: https://github.com/aquasecurity/trivy

  5. Nexus 儲存庫管理器文件: https://help.sonatype.com/repomanager3

  6. Docker 文件: https://docs.docker.com/

  7. Kubernetes 文件: https://kubernetes.io/docs/

  8. Prometheus 文件: https://prometheus.io/docs/

  9. Grafana 文件: https://grafana.com/docs/

這些資源在整個專案生命週期中提供了寶貴的見解、指導和支持,使我們能夠有效地實現目標。

🛠️作者與社區

此專案由Harshhaa 💡 製作。

我很樂意聽到您的回饋!請隨意分享您的想法。


📧與我聯絡:

LinkedIn GitHub 電報 開發 哈希節點


📢保持聯繫

跟我來


原文出處:https://dev.to/prodevopsguytech/cicd-devops-pipeline-project-deployment-of-java-application-on-kubernetes-4fi2


共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。

阿川私房教材:
學 JavaScript 前端,帶作品集去面試!

63 個專案實戰,寫出作品集,讓面試官眼前一亮!

立即開始免費試讀!