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 官方文档