《Python实战进阶》No26: CI/CD 流水线:GitHub Actions 与 Jenkins 集成

news/2025/3/26 1:27:00/

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 文件定义流水线。其主要特点包括:

  • 支持多种事件触发(如 pushpull_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
被测函数
python"># src/math_operations.py
def add(a, b):return a + bdef subtract(a, b):return a - b
测试代码
python"># 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 应用
python"># 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"]
完整流程
  1. GitHub Actions 运行单元测试。
  2. Jenkins 构建 Docker 镜像并部署到云服务器。
  3. 通过 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. 部署验证

  1. 访问应用
    在浏览器输入 http://<云服务器IP>:5000,应显示 “Hello, CI/CD!”。

  2. 查看容器日志

    docker logs flask-app
    

6. 常见问题与解决

问题 1:权限不足
  • 现象:Jenkins 无法执行 Docker 命令。
  • 解决:确保 Jenkins 用户已加入 docker 组:
    sudo usermod -aG docker jenkins
    sudo systemctl restart jenkins
    
问题 2:SSH 连接失败
  • 现象:Jenkins 无法连接到云服务器。
  • 解决
    1. 检查云服务器安全组是否开放 SSH 端口(默认 22)。
    2. 检查 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 官方文档

http://www.ppmy.cn/news/1583099.html

相关文章

1 存储过程学习: 使用DMSQL程序的优点

DMSQL程序具有以下优点&#xff1a; 与SQL语言的完美结合 SQL语言已成为数据库的标准语言&#xff0c;DMSQL程序支持所有SQL数据类型和所有SQL函数&#xff0c;同时支持所有DM对象类型。在DMSQL程序中可以使用SELECT、INSERT、DELETE、UPDATE数据操作语句&#xff0c;事务控制…

“张江引擎 人形启程”,AI 机器人开启上海进化新范式

当AI从虚拟算法跃入物理世界&#xff0c;机器人正以技术攻关、产品迭代、场景落地为着力点&#xff0c;为上海塑造现代化产业体系提供重要支撑。 在张江机器人谷这片创新热土上&#xff0c;青龙机械臂在产线精准起舞&#xff0c;开普勒物流机器人走出仓库化身“物流小哥”&…

AI加速,制造企业如何用数据驱动质量管理数字化变革?

2025年是“十四五”规划收官之年&#xff0c;政府工作报告提出持续推进“人工智能”行动&#xff0c;将数字技术与制造业优势、市场优势结合&#xff0c;推动人工智能在实体经济领域的深度应用。根据工信部规划&#xff0c;“人工智能制造”行动将聚焦行业大模型研发、生产流程…

项目日记 -云备份 -服务端配置信息模块

博客主页&#xff1a;【夜泉_ly】 本文专栏&#xff1a;【项目日记-云备份】 欢迎点赞&#x1f44d;收藏⭐关注❤️ 代码已上传 gitee 目录 前言配置信息文件文件配置类getInstance 获得实例readConfigFile 读取配置信息文件 测试补充 #mermaid-svg-wxyW2tnvC3hMEro7 {font-fam…

什么是索引?为什么要使用B树作为索引数据结构?

MySQL的事务特性 1.原子性:原子性就是这个事件要么执行完,要么没执行,不会存在中间状态,与C中华那个加锁避免多线程竞争是一个道理; 2.一致性:保持事件的操作对象双方某数据之和是不变的,就以转账为例,A转给B100块,那么A的余额多100,B的余额就必须少100; 3.隔离性:隔离就是独…

45.图论3

孤岛面积 #include<iostream> using namespace std; int N,M; int quex[100000]; int quey[100000]; int hh-1,tt-1; int gra[60][60]; int visited[60][60]; int res0; int dir[4][2]{0,1,0,-1,-1,0,1,0}; void bfs(int x,int y){hhtt;tt;quex[tt]x;quey[tt]y;while(hh…

Qt进程间通信:QSharedMemory 使用详解

1. 什么是 QSharedMemory&#xff1f; QSharedMemory 是 Qt 中用于进程间共享内存的类。它允许多个进程共享一块内存区域&#xff0c;从而避免数据传输时的 IO 操作&#xff0c;提高通信速度。通过共享内存&#xff0c;多个进程可以直接读写这块内存&#xff0c;而无需经过文件…

云服务器怎么防御ddos攻击呢?

防御DDoS攻击是保障云服务器稳定运行的关键措施&#xff0c;以下是综合多种防护策略的详细方案&#xff1a; 1. 启用云服务商提供的DDoS防护服务 高防IP/流量清洗&#xff1a; 将业务流量接入云服务商的高防IP&#xff0c;由专业清洗中心过滤恶意流量&#xff0c;仅放行正常请求…