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

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 + b

def 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 配置
yaml 复制代码
# .github/workflows/ci.yml
name: CI Pipeline

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.9'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install pytest

      - name: Run tests
        run: pytest tests/
运行结果

当代码推送到 main 分支时,GitHub Actions 将自动运行测试并生成报告:

复制代码
============================= test session starts =============================
collected 6 items

tests/test_math_operations.py ......                                    [100%]

============================== 6 passed in 0.03s ==============================

2. 使用 Jenkins 部署 Flask 应用到云服务器

Flask 应用
python 复制代码
# app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return "Hello, CI/CD!"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
Jenkins Pipeline
groovy 复制代码
pipeline {
    agent any

    stages {
        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 || true
                docker rm flask-app || true
                docker run -d --name flask-app -p 5000:5000 flask-app
                '''
            }
        }
    }
}
运行结果
  • Jenkins 将拉取代码、构建 Docker 镜像、运行测试并部署应用。
  • 访问 http://<server-ip>:5000 可看到 "Hello, CI/CD!"。

3. 集成 Docker 容器化应用的 CI/CD 流程

Dockerfile
dockerfile 复制代码
FROM python:3.9-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

CMD ["python", "app.py"]
完整流程
  1. GitHub Actions 运行单元测试。
  2. Jenkins 构建 Docker 镜像并部署到云服务器。
  3. 通过 Docker 实现跨环境一致性。


部署的细节与详细操作流程


1. Jenkins 安装与配置

步骤 1:在云服务器安装 Jenkins
bash 复制代码
# 更新包列表
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
bash 复制代码
# 安装 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 免密登录:

bash 复制代码
# 在 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 脚本优化
groovy 复制代码
pipeline {
    agent any

    environment {
        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. 查看容器日志

    bash 复制代码
    docker logs flask-app

6. 常见问题与解决

问题 1:权限不足
  • 现象:Jenkins 无法执行 Docker 命令。

  • 解决 :确保 Jenkins 用户已加入 docker 组:

    bash 复制代码
    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 配置文件,确保其适应团队需求。

附录:相关资源

相关推荐
Loo国昌2 分钟前
【LangChain1.0】第九阶段:文档处理工程 (LlamaIndex)
人工智能·后端·python·算法·langchain
抠头专注python环境配置36 分钟前
基于Python与深度学习的智能垃圾分类系统设计与实现
pytorch·python·深度学习·分类·垃圾分类·vgg·densenet
愈努力俞幸运1 小时前
flask 入门 token, headers,cookie
后端·python·flask
梦想是成为算法高手1 小时前
带你从入门到精通——知识图谱(一. 知识图谱入门)
人工智能·pytorch·python·深度学习·神经网络·知识图谱
用什么都重名1 小时前
Conda 虚拟环境安装配置路径详解
windows·python·conda
阿也在北京1 小时前
基于Neo4j和TuGraph的知识图谱与问答系统搭建——胡歌的导演演员人际圈
python·阿里云·知识图谱·neo4j
计算机徐师兄1 小时前
Python基于知识图谱的胆囊炎医疗问答系统(附源码,文档说明)
python·知识图谱·胆囊炎医疗问答系统·python胆囊炎医疗问答系统·知识图谱的胆囊炎医疗问答系统·python知识图谱·医疗问答系统
北冥码鲲1 小时前
【保姆级教程】从零入手:Python + Neo4j 构建你的第一个知识图谱
python·知识图谱·neo4j
B站计算机毕业设计超人1 小时前
计算机毕业设计Python+大模型音乐推荐系统 音乐数据分析 音乐可视化 音乐爬虫 知识图谱 大数据毕业设计
人工智能·hadoop·爬虫·python·数据分析·知识图谱·课程设计