No26: CI/CD 流水線:GitHub Actions 與 Jenkins 集成
摘要
持續集成(CI)和持續部署(CD)是現代軟件開發中不可或缺的實踐,能夠顯著提升開發效率、減少錯誤并加速交付流程。本文將探討如何利用 GitHub Actions 和 Jenkins 構建高效的 CI/CD 流水線,并通過實戰案例展示如何自動化構建、測試和部署 Python 應用程序。無論你是個人開發者還是團隊成員,本文都將幫助你掌握 CI/CD 的核心技能,并優化開發工作流。
核心概念和知識點
1. CI/CD 的基本概念與工作原理
- 持續集成(CI):開發人員頻繁地將代碼提交到共享倉庫,每次提交都會觸發自動化構建和測試,以盡早發現集成問題。
- 持續部署(CD):在 CI 的基礎上,進一步將通過測試的代碼自動部署到生產環境或測試環境。
- 關鍵組件:
- 版本控制系統(如 Git)
- 構建工具(如 Docker、Makefile)
- 自動化測試框架(如 pytest)
- 部署工具(如 Ansible、Kubernetes)
2. GitHub Actions 的 YAML 配置文件
GitHub Actions 是一個內置于 GitHub 的 CI/CD 工具,使用 .github/workflows
目錄下的 YAML 文件定義流水線。其主要特點包括:
- 支持多種事件觸發(如
push
、pull_request
)。 - 提供豐富的預定義操作(Actions),可快速實現復雜功能。
- 易于與 GitHub 倉庫集成。
3. Jenkins 的安裝、配置與 Pipeline 構建
Jenkins 是一個開源的 CI/CD 工具,支持高度自定義的流水線構建。其主要特性包括:
- 基于插件的擴展性(如 Git、Docker 插件)。
- 使用 Groovy 腳本定義 Pipeline。
- 支持分布式構建環境。
4. 自動化構建、測試與部署
- 構建:將源代碼編譯為可執行文件或容器鏡像。
- 測試:運行單元測試、集成測試等,確保代碼質量。
- 部署:將應用發布到目標環境(如云服務器、Kubernetes 集群)。
實戰案例
1. 使用 GitHub Actions 自動運行單元測試
以下是一個使用 GitHub Actions 自動運行 pytest 單元測試的示例。
項目結構
my_project/
├── src/
│ ├── math_operations.py
├── tests/
│ ├── test_math_operations.py
├── .github/
│ └── workflows/
│ └── ci.yml
被測函數
# src/math_operations.py
def add(a, b):return a + bdef subtract(a, b):return a - b
測試代碼
# tests/test_math_operations.py
import pytest
from src.math_operations import add, subtract@pytest.mark.parametrize("a, b, expected", [(2, 3, 5),(-1, 1, 0),(0, 0, 0)
])
def test_add(a, b, expected):assert add(a, b) == expected@pytest.mark.parametrize("a, b, expected", [(5, 3, 2),(0, 0, 0),(10, 5, 5)
])
def test_subtract(a, b, expected):assert subtract(a, b) == expected
GitHub Actions 配置
# .github/workflows/ci.yml
name: CI Pipelineon:push:branches:- mainpull_request:branches:- mainjobs:test:runs-on: ubuntu-lateststeps:- name: Checkout codeuses: actions/checkout@v3- name: Set up Pythonuses: actions/setup-python@v4with:python-version: '3.9'- name: Install dependenciesrun: |python -m pip install --upgrade pippip install pytest- name: Run testsrun: pytest tests/
運行結果
當代碼推送到 main
分支時,GitHub Actions 將自動運行測試并生成報告:
============================= test session starts =============================
collected 6 itemstests/test_math_operations.py ...... [100%]============================== 6 passed in 0.03s ==============================
2. 使用 Jenkins 部署 Flask 應用到云服務器
Flask 應用
# app.py
from flask import Flaskapp = Flask(__name__)@app.route('/')
def home():return "Hello, CI/CD!"if __name__ == "__main__":app.run(host="0.0.0.0", port=5000)
Jenkins Pipeline
pipeline {agent anystages {stage('Checkout') {steps {git 'https://github.com/your-repo/flask-app.git'}}stage('Build') {steps {sh 'docker build -t flask-app .'}}stage('Test') {steps {sh 'docker run --rm flask-app pytest'}}stage('Deploy') {steps {sh '''docker stop flask-app || truedocker rm flask-app || truedocker run -d --name flask-app -p 5000:5000 flask-app'''}}}
}
運行結果
- Jenkins 將拉取代碼、構建 Docker 鏡像、運行測試并部署應用。
- 訪問
http://<server-ip>:5000
可看到 “Hello, CI/CD!”。
3. 集成 Docker 容器化應用的 CI/CD 流程
Dockerfile
FROM python:3.9-slimWORKDIR /appCOPY requirements.txt .
RUN pip install -r requirements.txtCOPY . .CMD ["python", "app.py"]
完整流程
- GitHub Actions 運行單元測試。
- Jenkins 構建 Docker 鏡像并部署到云服務器。
- 通過 Docker 實現跨環境一致性。
部署的細節與詳細操作流程
1. Jenkins 安裝與配置
步驟 1:在云服務器安裝 Jenkins
# 更新包列表
sudo apt update# 安裝 Java 運行時環境(Jenkins 依賴)
sudo apt install openjdk-11-jdk -y# 添加 Jenkins 官方倉庫
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo tee \/usr/share/keyrings/jenkins-keyring.asc > /dev/null
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 > /dev/null# 安裝 Jenkins
sudo apt update
sudo apt install jenkins -y# 啟動 Jenkins 服務
sudo systemctl start jenkins# 設置 Jenkins 開機自啟
sudo systemctl enable jenkins
訪問 http://<云服務器IP>:8080
,按照提示完成初始化配置(需從服務器日志獲取初始管理員密碼)。
步驟 2:安裝必要插件
在 Jenkins 控制臺依次安裝以下插件:
- Git:用于拉取代碼倉庫。
- Docker:支持 Docker 構建與部署。
- Pipeline:定義流水線任務。
2. 云服務器準備
步驟 1:安裝 Docker
# 安裝 Docker
sudo apt install docker.io -y# 啟動 Docker 服務
sudo systemctl start docker# 設置 Docker 開機自啟
sudo systemctl enable docker# 將當前用戶加入 Docker 組(避免每次使用 sudo)
sudo usermod -aG docker $USER
newgrp docker # 立即生效
步驟 2:配置 SSH 無密碼登錄
在 Jenkins 服務器與目標云服務器之間配置 SSH 免密登錄:
# 在 Jenkins 服務器生成 SSH 密鑰(如已有可跳過)
ssh-keygen -t rsa -b 4096# 將公鑰復制到云服務器
ssh-copy-id user@<云服務器IP>
3. Jenkins 憑據管理
在 Jenkins 控制臺添加以下憑據:
- SSH 用戶名與私鑰:用于連接云服務器。
- Docker Hub 憑據(可選):用于推送鏡像到 Docker Hub。
4. Jenkins Pipeline 詳細配置
Pipeline 腳本優化
pipeline {agent anyenvironment {SERVER_IP = 'your-server-ip'DOCKER_HUB_REPO = 'your-dockerhub-username/flask-app'}stages {stage('Checkout') {steps {git branch: 'main', url: 'https://github.com/your-repo/flask-app.git'}}stage('Build Docker Image') {steps {script {docker.build("${DOCKER_HUB_REPO}:${env.BUILD_ID}")}}}stage('Push Docker Image') {steps {script {docker.withRegistry('https://registry.hub.docker.com', 'docker-hub-credentials-id') {docker.image("${DOCKER_HUB_REPO}:${env.BUILD_ID}").push()}}}}stage('Deploy to Server') {steps {sshagent(['ssh-credentials-id']) {sh """ssh -o StrictHostKeyChecking=no user@${SERVER_IP} 'docker pull ${DOCKER_HUB_REPO}:${env.BUILD_ID} && \docker stop flask-app || true && \docker rm flask-app || true && \docker run -d --name flask-app -p 5000:5000 ${DOCKER_HUB_REPO}:${env.BUILD_ID}'"""}}}}
}
5. 部署驗證
-
訪問應用
在瀏覽器輸入http://<云服務器IP>:5000
,應顯示 “Hello, CI/CD!”。 -
查看容器日志
docker logs flask-app
6. 常見問題與解決
問題 1:權限不足
- 現象:Jenkins 無法執行 Docker 命令。
- 解決:確保 Jenkins 用戶已加入
docker
組:sudo usermod -aG docker jenkins sudo systemctl restart jenkins
問題 2:SSH 連接失敗
- 現象:Jenkins 無法連接到云服務器。
- 解決:
- 檢查云服務器安全組是否開放 SSH 端口(默認 22)。
- 檢查 SSH 密鑰是否正確配置。
7. 安全加固建議
- 限制 Jenkins 訪問權限:通過 Nginx 反向代理并啟用 HTTPS。
- 定期更新鏡像:在 Pipeline 中加入漏洞掃描步驟(如使用
trivy
)。 - 清理舊鏡像:定期刪除無用的 Docker 鏡像以釋放空間。
通過以上步驟,您可以實現從代碼提交到部署的全自動化流程。如果需要更高級的配置(如藍綠部署、回滾機制),可進一步探索 Jenkins 的高級特性!
總結
本文通過實戰案例展示了如何使用 GitHub Actions 和 Jenkins 構建 CI/CD 流水線。GitHub Actions 適合輕量級的自動化任務,而 Jenkins 提供了更高的靈活性和可擴展性。結合 Docker 容器化技術,可以進一步簡化部署流程并提高應用的一致性。
擴展思考
1. 如何優化 CI/CD 流程以減少資源消耗?
- 使用緩存機制(如 GitHub Actions 的
cache
功能)避免重復安裝依賴。 - 并行化測試任務以縮短構建時間。
- 定期清理過期的 Docker 鏡像和 Jenkins 構建記錄。
2. 探討多團隊協作中的 CI/CD 最佳實踐
- 統一代碼風格和測試標準。
- 使用分支策略(如 GitFlow)管理代碼合并。
- 定期審查 CI/CD 配置文件,確保其適應團隊需求。
附錄:相關資源
- GitHub Actions 官方文檔
- Jenkins 官方文檔
- Docker 官方文檔