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

发布于:2025-03-19 ⋅ 阅读:(11) ⋅ 点赞:(0)

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
被测函数
# src/math_operations.py
def add(a, b):
    return a + b

def 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 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 应用
# 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
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
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
# 更新包列表
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 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. 查看容器日志

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

附录:相关资源


网站公告

今日签到

点亮在社区的每一天
去签到