jenkins打包制作Python镜像,并推送至docker仓库,部署到k8s

一、背景

随着AI大模型的应用越来越广泛,编程语言Python也更显得更加实用。

许多对接AI的库都是先在python中应用,才逐步推广至其他编程语言。

接下来,我们将介绍python编程的CI/CD流程及其实现。

包括以下几个部分:

  • jenkins pod template配置
  • jenkins jenkinsfile文件
  • jenkins job配置
  • docker私有仓库
  • k8s的deployment和service(略)

限于篇幅,将按CI/CD分为两部分,本文阐述CI部分,有了docker镜像,想要部署到k8s就容易了。(换句话说,k8s部署本身是不区分语言,java还是python,或者go等等)

二、pod template

1、新增pod template


输入Pod模板的名称和命名空间。

2、新增容器jnlp

jenkins集群是采用k8s动态扩展,每运行一个job,就是创建一个k8s pod节点,所以job之间互不干扰。

jnlp镜像是我自己私库的地址,你可以使用外网的,更倾向于使用私库的。

3、新增容器docker

制作docker镜像,推送至仓库

4、配置pod环境变量

5、添加卷

docker镜像必须要添加Host Path Volume,主机路径和挂载路径均为/var/run/docker.sock

6、拉取镜像的Secret

7、节点选择器

保证pod是在worker角色的节点上创建。node-role.kubernetes.io/worker=worker

三、jenkinsfile

docker构建并推送至私库,封装在类docker.groovy里

  • 版本号默认写在项目的根目录的.version文件里
  • 项目的根目录还需要编写自己的Dockerfile文件,用于构建docker镜像

因为编译打包的过程都在Dockerfile中,所以整个jenkinsfile的流程就三步:

  • 第一步,拉取git代码
  • 第二步,读取程序的版本号
  • 第三步,构建docker镜像,并推送

对项目的要求,见下图:

bash 复制代码
#!groovy

@Library('jenkinslib') _

// gitlab的ssh密钥,修改为你自己的
String gitlabCredentialsId = "xxx"

def tools = new com.xxx.devops.tools()
def docker = new com.xxx.devops.docker()

// 服务名称
String serviceName = "${env.serviceName}".trim()

//git代码地址
String codeUrl = "${env.codeUrl}".trim()

//git代码分支
String branch = "${env.branch}".trim()

// 版本号
String appVersion = ""
// 版本号文件
String versionFileName = "${env.versionFile}".trim()

if (versionFileName == "" || versionFileName == "null") {
    versionFileName = ".version"
}

// 默认读取项目工作空间中的Dockerfile
String dockerfileName = "Dockerfile"

pipeline {
    agent {
        kubernetes {
            inheritFrom 'jnlp-python'
        }
    }

    options {
        timestamps()  //日志会有时间
        skipDefaultCheckout()  //删除隐式checkout scm语句
        disableConcurrentBuilds() //禁止并行
        timeout(time: 1, unit: 'HOURS')  //流水线超时设置1h
    }

    stages {
        stage('Pull Code') {
            steps {
                script {
                    tools.PrintMes("pull code!!!", "green")
                    git branch: "$branch", credentialsId: "$gitlabCredentialsId", url: "$codeUrl"
                }
            }
            post {
                failure {
                    //当此Pipeline失败时打印消息
                    script {
                        tools.PrintMes("pull code failure!!!", "red")
                    }
                }
            }
        }

        stage('Get Version') {
            steps {
                script {
                    tools.PrintMes("Get Version!!!", "green")

                    dir("${env.WORKSPACE}") {
                        sh "cat ${versionFileName}"

                        String version = sh returnStdout: true,
                                script: """
                                            cat ${versionFileName}
                                            """
                        // trim()
                        appVersion = version.trim()
                    }

                    // 输出程序的版本号
                    tools.PrintMes("get version: ${appVersion}", "green")
                }
            }
            post {
                failure {
                    //当此Pipeline失败时打印消息
                    script {
                        tools.PrintMes("Get Version failure!!!", "red")
                    }
                }
            }
        }

        stage('Push Docker Image') {
            steps {
                script {
                    tools.PrintMes("Push Docker Image!!!", "green")

                    container('docker') {
                        dir("${env.WORKSPACE}") {
                            if ("PROD" == buildEnv) {
                                docker.pushToAly(serviceName, appVersion, dockerfileName)
                            } else {
                                docker.pushToNexus(serviceName, null, appVersion, null, dockerfileName, "python")
                            }
                        }
                    }
                }
            }
            post {
                failure {
                    //当此Pipeline失败时打印消息
                    script {
                        tools.PrintMes("Push Docker Image failure!!!", "red")
                    }
                }
            }
        }
    }

    post {
        success {
            //当此Pipeline成功时打印消息
            script {
                tools.PrintMes("archive zip, send the message of build successfully to user", "green")
                dir("${env.WORKSPACE}") {
                    sh "echo ${appVersion} > .version"

                    archiveArtifacts artifacts: '.version', followSymlinks: false
                }
            }
        }
        failure {
            //当此Pipeline失败时打印消息
            echo 'failure'
        }
        unstable {
            //当此Pipeline 为不稳定时打印消息
            echo 'unstable'
        }
        aborted {
            //当此Pipeline 终止时打印消息
            echo 'aborted'
        }
        changed {
            //当pipeline的状态与上一次build状态不同时打印消息
            echo 'changed'
        }
    }
}

三、jenkins job配置

围绕上文的jenkinfile,输入变量主要是三个:

  • serviceName: 服务名,docker镜像名
  • codeUrl: git项目地址
  • branch:代码分支

这里还支持版本号写在别的文件里。

  • versionFile 版本文件名,默认是.version,如果是其他,则需要输入

jenkins job 除了配置变量外,关键是配置jenkinsfile所在的git地址、分支以及相对路径。

四、docker私有仓库

  • 1、构建docker镜像
  • 2、登录docker私服
  • 3、给本地docker镜像打标签
  • 4、把本地docker镜像推送到私库
  • 5、删除本地docker镜像

下面截图,省略docker build过程,因为它比较耗时,也是Jenkins CI的核心过程。

1、研发环境


2、生产环境

阿里云容器镜像服务,先创建镜像仓库。

jenkins推送docker镜像到阿里云镜像仓库

相关推荐
weixin_457760001 小时前
GIOU (Generalized Intersection over Union) 详解
pytorch·python
汐ya~1 小时前
Cursor连接异常问题“Model not available/connection failed”解决:IDE内置代理配置,无需全局流量代理与虚拟网卡
python·编辑器·cursor
虚伪的空想家1 小时前
首发:TDengine3.3.6版本使用K8S部署
java·docker·容器·kubernetes·k8s·时序数据库·tdengine
海市公约1 小时前
Python操作SQLite数据库:从基础语法到完整项目实战
数据库·ide·python·程序人生·架构·pycharm·sqlite
轻竹办公PPT1 小时前
学校要求开题报告 PPT,有没有模板?
人工智能·python·powerpoint
辜月十1 小时前
Docker-Compose 【Mysql】
后端
悟空码字1 小时前
SpringBoot实现系统监控:给应用装上“健康手环”
java·后端·监控
GuluGuluWater1 小时前
受够了同事的垃圾代码?我用 Go 写了个自动审查工具
后端
汪小成1 小时前
# 在云服务器上安装与使用Jenkins(基于 CentOS Stream 9)
jenkins