在當今快節奏的軟體開發環境中,實施 DevOps 實踐對於追求敏捷性、效率和高品質軟體交付的組織至關重要。此專案示範如何使用Jenkins實現強大的持續整合/持續部署 (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 EC2 執行個體配備了各種 DevOps 工具:
🔹 Kubernetes 主節點:管理叢集狀態、調度和協調。
🔹 Kubernetes 工作節點(2) :託管並執行容器化應用程式。
🔹SonarQube 伺服器:執行靜態程式碼分析,確保程式碼品質。
🔹 Nexus Repository Manager :管理建置工件、依賴項和 Docker 映像。
🔹 Jenkins 伺服器:協調 CI/CD 流程並整合 DevOps 工具。
🔹監控伺服器:執行Prometheus 和 Grafana進行即時系統監控。
每個實例都配置了必要的 CPU、記憶體和儲存資源。採用存取控制和網路配置等安全最佳實務來保護基礎架構。
具有sudo 權限的Ubuntu 作業系統(Xenial 或更高版本)
t2.medium實例類型或更高版本
網路存取
確保所有 AWS 執行個體都位於相同安全性群組中
開啟連接埠 6443以允許工作節點加入集群
在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
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
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-*
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
執行從主節點取得的加入命令:
sudo kubeadm join <master-ip>:6443 --token <your-token> --discovery-token-ca-cert-hash sha256:<hash> --v=5
在主節點上驗證叢集狀態:
kubectl get nodes
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
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
docker run -d --name nexus -p 8081:8081 sonatype/nexus3:latest
檢索 Nexus管理員密碼:
docker exec -it <container_id> cat /nexus-data/admin.password
請依照下列步驟建立私有 Git 儲存庫,產生個人存取令牌,連接到儲存庫並安全地推送程式碼。
登入您喜歡的 Git 託管平台(例如,GitHub、GitLab、Bitbucket)。
導航到“存儲庫”部分。
按一下「新儲存庫」並將其可見性設為「私人」 。
複製儲存庫 URL 以供稍後使用。
前往您的帳戶設定。
找到開發人員設定(GitHub)或存取令牌部分(GitLab、Bitbucket)。
產生具有所需權限的新個人存取權杖 (PAT) ,例如:
repo (用於完全存取儲存庫)
讀取:包(如果存取包)
複製並安全地保存令牌,因為它不會再次顯示。
打開終端機或 Git Bash。
導航到您想要儲存儲存庫的目錄。
執行以下命令,將<repository_URL>
替換為您的實際儲存庫連結:
git clone <repository_URL>
cd <repository_name>
git add .
git commit -m "Initial commit: Added project files"
git push
git push -u origin main
(如果適用,請將main
替換為master
或任何其他分支名稱。)
當系統提示輸入憑證時:
使用者名稱:輸入您的 GitHub/GitLab/Bitbucket 使用者名稱。
密碼:使用個人存取權令牌(PAT)而不是您的密碼。
前往您的 Git 託管平台並開啟儲存庫。
您應該會看到提交的文件已成功上傳。
在設定 CI/CD 管道之前,請安裝以下 Jenkins 外掛程式:
使 Jenkins 安裝和設定 Eclipse Temurin JDK (以前稱為 AdoptOpenJDK)。
前往Jenkins 儀表板 → 管理 Jenkins → 管理外掛程式 → 可用標籤。
搜尋Eclipse Temurin Installer ,選擇它,然後點擊Install without restart 。
為 Jenkins Pipelines 加入 Maven 支持,允許在腳本中使用 Maven 命令。
透過在外掛程式管理器中搜尋Pipeline Maven Integration來安裝它。
允許在 Jenkins 中集中儲存設定檔(屬性、XML、JSON)。
透過插件管理器安裝。
整合 SonarQube 以便在建置期間進行程式碼品質和安全分析。
在插件管理器中搜尋SonarQube Scanner並安裝它。
使 Jenkins 能夠使用kubectl
與 Kubernetes 叢集互動。
從插件管理器安裝它。
允許 Jenkins 代理程式作為 Kubernetes pod 執行,實現動態擴展。
透過插件管理器安裝。
使 Jenkins 能夠與 Docker 互動以建置和管理容器。
從插件管理器安裝它。
透過建置、發布和管理 Docker 容器的步驟來擴展 Jenkins Pipeline。
透過插件管理器安裝它。
安裝後,在管理 Jenkins → 全域工具配置中配置這些插件,並在需要時設定憑證。
安裝插件後,在 Jenkins 中建立一個新的Pipeline作業並使用以下腳本:
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'
)
}
}
}
}
kubectl
將應用程式部署到 Kubernetes 叢集。解壓縮下載的.tar.gz
檔。
導航到解壓縮的目錄並執行:
./prometheus &
預設情況下,Prometheus 在連接埠 9090上執行。
在瀏覽器中存取:
http://<instance_IP>:9090
提取 Blackbox Exporter .tar.gz
檔。
導航到解壓縮的目錄並執行:
./blackbox_exporter &
在監控虛擬機器上執行以下命令:
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
sudo /bin/systemctl start grafana-server
Grafana 預設在連接埠 3000上運作。
在瀏覽器中存取:
http://<instance_IP>:3000
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 位址。 pgrep prometheus
登入 Grafana ( http://<instance_IP>:3000
)。
導航至設定 → 資料來源 → 新增資料來源。
選擇Prometheus作為源。
輸入Prometheus 伺服器 URL ( http://<instance_IP>:9090
)。
儲存並測試連接。
從 Grafana 的公共儀表板庫導入Prometheus 儀表板。
🚀您使用 Prometheus 和 Grafana 的監控設定現已準備就緒!
DevOps CI/CD管線專案的成功實施,是提升軟體交付流程效率、可靠性和品質的重要里程碑。透過自動化軟體開發生命週期的關鍵環節(包括編譯、測試、部署和監控),該專案實現了快速、一致地交付軟體版本,有助於縮短產品上市時間並提高客戶滿意度。
我要對DevOps Shack的出色專案和實施指南表示感謝。
展望未來,該專案的影響不僅限於其直接利益,還為軟體開發實踐的持續改進和創新鋪平了道路。透過採用 DevOps 原則並利用尖端工具和技術,我們為未來專案的發展奠定了堅實的基礎。 CI/CD 管道的可擴展性、靈活性和彈性確保了它能夠適應不斷變化的需求和技術進步,使我們的組織在競爭激烈的市場環境中獲得長期成功。
Jenkins 文件: https://www.jenkins.io/doc/
SonarQube 文件: https://docs.sonarqube.org/latest/
Trivy 文件: https://github.com/aquasecurity/trivy
Nexus 儲存庫管理器文件: https://help.sonatype.com/repomanager3
Docker 文件: https://docs.docker.com/
Kubernetes 文件: https://kubernetes.io/docs/
Prometheus 文件: https://prometheus.io/docs/
Grafana 文件: https://grafana.com/docs/
這些資源在整個專案生命週期中提供了寶貴的見解、指導和支持,使我們能夠有效地實現目標。
此專案由Harshhaa 💡 製作。
我很樂意聽到您的回饋!請隨意分享您的想法。