【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级

结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级

dogfei发布于 今天 10:48

现在这家单位的CICD比较的混乱,然后突发奇想,想改造下,于是就用pipeline做了一个简单的流水线,下面是关于它的一些介绍

写一个简单的流水线

【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级
大概就是这么个流程简单来说就是:拉代码---》编译---》打镜像---》推镜像---》部署到k8s中,下面的pipeline就是在这条主线上进行,根据情况进行增加

pipeline {

agent { label 'pdc&&jdk8' }

environment {

git_addr = "代码仓库地址"

git_auth = "拉代码时的认证ID"

pom_dir = "pom文件的目录位置(相对路径)"

server_name = "服务名"

namespace_name = "服务所在的命名空间"

img_domain = "镜像地址"

img_addr = "${img_domain}/cloudt-safe/${server_name}"

// cluster_name = "集群名"

}

stages {

stage('Clear dir') {

steps {

deleteDir()

}

}

stage('Pull server code and ops code') {

parallel {

stage('Pull server code') {

steps {

script {

checkout(

[

$class: 'GitSCM',

branches: [[name: '${Branch}']],

userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_addr}"]]

]

)

}

}

}

stage('Pull ops code') {

steps {

script {

checkout(

[

$class: 'GitSCM',

branches: [[name: 'pipeline-0.0.1']], //拉取的构建脚本的分支

doGenerateSubmoduleConfigurations: false,

extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'DEPLOYJAVA']], //DEPLOYJAVA: 把代码存放到此目录中

userRemoteConfigs: [[credentialsId: 'chenf-o', url: '构建脚本的仓库地址']]

]

)

}

}

}

}

}

stage('Set Env') {

steps {

script {

date_time = sh(script: "date +%Y%m%d%H%M", returnStdout: true).trim()

git_cm_id = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()

whole_img_addr = "${img_addr}:${date_time}_${git_cm_id}"

}

}

}

stage('Complie Code') {

steps {

script {

withMaven(maven: 'maven_latest_linux') {

sh "mvn -U package -am -amd -P${env_name} -pl ${pom_dir}"

}

}

}

}

stage('Build image') {

steps {

script {

dir("${env.WORKSPACE}/${pom_dir}") {

sh """

echo 'FROM 基础镜像地址' > Dockerfile //由于我这里进行了镜像的优化,只指定一个基础镜像地址即可,后面会详细的说明

"""

withCredentials([usernamePassword(credentialsId: 'faabc5e8-9587-4679-8c7e-54713ab5cd51', passwordVariable: 'img_pwd', usernameVariable: 'img_user')]) {

sh """

docker login -u ${img_user} -p ${img_pwd} ${img_domain}

docker build -t ${img_addr}:${date_time}_${git_cm_id} .

docker push ${whole_img_addr}

"""

}

}

}

}

}

stage('Deploy img to K8S') {

steps {

script {

dir('DEPLOYJAVA/deploy') {

//执行构建脚本

sh """

/usr/local/python3/bin/python3 deploy.py -n ${server_name} -s ${namespace_name} -i ${whole_img_addr} -c ${cluster_name}

"""

}

}

}

// 做了下判断如果上面脚本执行失败,会把上面阶段打的镜像删除掉

post {

failure {

sh "docker rmi -f ${whole_img_addr}"

}

}

}

stage('Clear somethings') {

steps {

script {

// 删除打的镜像

sh "docker rmi -f ${whole_img_addr}"

}

}

post {

success {

// 如果上面阶段执行成功,将把当前目录删掉

deleteDir()

}

}

}

}

}

优化构建镜像

上面的pipeline中有一条命令是生成Dockerfile的,在这里做了很多优化,虽然我的Dockerfile就写了一个FROM,但是在这之后又会执行一系列的操作,下面我们对比下没有做优化的Dockerfile
未优化

FROM 基础镜像地址

RUN mkdir xxxxx

COPY *.jar /usr/app/app.jar

ENTRYPOINT java -jar app.jar

优化后的

FROM 基础镜像地址

优化后的Dockerfile就这一行就完了。。。。。 下面简单介绍下这个ONBUILD
ONBUILD可以这样理解,就比如我们这里使用的镜像,是基于java语言做的一个镜像,这个镜像有两部分,一个是包含JDK的基础镜像A,另一个是包含jar包的镜像B,关系是先有A再有B,也就是说B依赖于A。
假设一个完整的基于Java的CICD场景,我们需要拉代码,编译,打镜像,推镜像,更新pod这一系列的步骤,而在打镜像这个过程中,我们需要把编译后的产物jar包COPY到基础镜像中,这就造成了,我们还得写一个Dockerfile,用来COPY jar包,就像下面这个样子:

FROM jdk基础镜像

COPY xxx.jar /usr/bin/app.jar

ENTRYPOINT java -jar app.jar

这样看起来也还好,基本上三行就解决了,但是能用一行就解决为什么要用三行呢?

FROM jdk基础镜像

ONBUILD COPY target/*.jar /usr/bin/app.jar

CMD ["/start.sh"]

打成一个镜像,比如镜像名是:java-service:jdk1.8,在打镜像的时候,ONBUILD后面的在本地打镜像的过程中不会执行,而是在下次引用时执行的

FROM java-service:jdk1.8

只需要这一行就可以了,并且这样看起来更加简洁,pipeline看起来也很规范,这样的话,我们每一个java的服务都可以使用这一行Dockerfile了。

使用凭据

有时候使用docker进行push镜像时需要进行认证,如果我们直接在pipeline里写的话不太安全,所以得进行脱敏,这样的话我们就需要用到凭据了,添加凭据也是非常简单,由于我们只是保存我们的用户名和密码,所以用Username with password类型的凭据就可以了,如下所示

【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级

比如说:拉取git仓库的代码需要用到,然后这里就添加一个凭据,对应与pipeline里的下面这段内容:

stage('Pull server code') {

steps {

script {

checkout(

[

$class: 'GitSCM',

branches: [[name: '${Branch}']],

userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_addr}"]]

]

)

}

}

}

这里的变量${git_auth}就是添加凭据时设置的ID,如果不设置ID会随机生成一个ID

然后docker push时会需要进行认证,也需要添加凭据,添加方式和上面是一样的,不过我们可以用pipeline的语法来生成一个,方式如下:
点击Pipeline Syntax
【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级

选择withCredentials: Bind credentials to variables

【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级

然后和之前添加的凭据进行绑定,这里选择类型为:Username and password (separated)

【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级

设置用户名和密码的变量名,然后选择刚才添加好的凭据

【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级

点击生成即可,就是上面pipeline里的下面这段:

withCredentials([usernamePassword(credentialsId: 'faabc5e8-9587-4679-8c7e-54713ab5cd51', passwordVariable: 'img_pwd', usernameVariable: 'img_user')]) {

sh """

docker login -u ${img_user} -p ${img_pwd} ${img_domain}

docker build -t ${img_addr}:${date_time}_${git_cm_id} .

docker push ${whole_img_addr}

"""

}

credentialsId: 这个ID就是随机生成的ID

执行脚本进行更新镜像

这里是使用python写了一个小脚本,来调用kubernetes的接口做了一个patch的操作完成的。先来看下此脚本的目录结构

【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级
核心代码:deploy.py
核心文件:config.yaml 存放的是kubeconfig文件,用于和kubernetes的认证

下面贴一下deploy.py的脚本内容,可以参考下:

import os

import argparse

from kubernetes import client, config

class deployServer:

def __init__(self, kubeconfig):

self.kubeconfig = kubeconfig

config.kube_config.load_kube_config(config_file=self.kubeconfig)

self._AppsV1Api = client.AppsV1Api()

self._CoreV1Api = client.CoreV1Api()

self._ExtensionsV1beta1Api = client.ExtensionsV1beta1Api()

def deploy_deploy(self, deploy_namespace, deploy_name, deploy_img=None, deploy_which=1):

try:

old_deploy = self._AppsV1Api.read_namespaced_deployment(

name=deploy_name,

namespace=deploy_namespace,

)

old_deploy_container = old_deploy.spec.template.spec.containers

pod_num = len(old_deploy_container)

if deploy_which == 1:

pod_name = old_deploy_container[0].name

old_img = old_deploy_container[0].image

print("获取上一个版本的信息\n")

print("当前Deployment有 {} 个pod, 为: {}\n".format(pod_num, pod_name))

print("上一个版本的镜像地址为: {}\n".format(old_img))

print("此次构建的镜像地址为: {}\n".format(deploy_img))

print("正在替换当前服务的镜像地址....\n")

old_deploy_container[deploy_which - 1].image = deploy_img

else:

print("只支持替换一个镜像地址")

exit(-1)

new_deploy = self._AppsV1Api.patch_namespaced_deployment(

name=deploy_name,

namespace=deploy_namespace,

body=old_deploy

)

print("镜像地址已经替换完成\n")

return new_deploy

except Exception as e:

print(e)

def run():

parser = argparse.ArgumentParser()

parser.add_argument('-n', '--name', help="构建的服务名")

parser.add_argument('-s', '--namespace', help="要构建的服务所处在的命名空间")

parser.add_argument('-i', '--img', help="此次构建的镜像地址")

parser.add_argument('-c', '--cluster',

help="rancher中当前服务所处的集群名称")

args = parser.parse_args()

if not os.path.exists('../config/' + args.cluster):

print("当前集群名未设置或名称不正确: {}".format(args.cluster), 'red')

exit(-1)

else:

kubeconfig_file = '../config/' + args.cluster + '/' + 'config.yaml'

if os.path.exists(kubeconfig_file):

cli = deployServer(kubeconfig_file)

cli.deploy_deploy(

deploy_namespace=args.namespace,

deploy_name=args.name,

deploy_img=args.img

)

else:

print("当前集群的kubeconfig不存在,请进行配置,位置为{}下的config.yaml.(注意: config.yaml名称写死,不需要改到)".format(args.cluster),

'red')

exit(-1)

if __name__ == '__main__':

run()

写的比较简单,没有难懂的地方,关键的地方是:

new_deploy = self._AppsV1Api.patch_namespaced_deployment(

name=deploy_name,

namespace=deploy_namespace,

body=old_deploy

)

这一句是执行的patch操作,把替换好新的镜像地址的内容进行patch。
然后就是执行就可以了。

其他

这里有一个需要注意的地方是pipeline里加了一个异常捕获,如下所示:

post {

success {

// 如果上面阶段执行成功,将把当前目录删掉

deleteDir()

}

}

生命式的pipeline和脚本式的pipeline的异常捕获的写法是有区别的,声明式写法是用的post来进行判断,比较简单,可以参考下官方文档

另外还有一个地方使用了并行执行,同时拉了服务的代码,和构建脚本的代码,这样可以提高执行整个流水线的速度,如下所示:

parallel {

stage('Pull server code') {

steps {

script {

checkout(

[

$class: 'GitSCM',

branches: [[name: '${Branch}']],

userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_addr}"]]

]

)

}

}

}

stage('Pull ops code') {

steps {

script {

checkout(

[

$class: 'GitSCM',

branches: [[name: 'pipeline-0.0.1']], //拉取的构建脚本的分支

doGenerateSubmoduleConfigurations: false,

extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'DEPLOYJAVA']], //DEPLOYJAVA: 把代码存放到此目录中

userRemoteConfigs: [[credentialsId: 'chenf-o', url: '构建脚本的仓库地址']]

]

)

}

}

}

}

嗯,情况就是这么个情况,一个简简单单的流水线就完成了,如果想快速使用流水线完成CICD,可以参考下这篇文章。

欢迎各位朋友关注我的公众号,来一起学习进步哦
【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级

pythonjenkinsk8scicd

阅读 41发布于 今天 10:48

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议

avatar

dogfei

个人博客:www.dogfei.cn

1 声望

0 粉丝

0 条评论

得票时间

avatar

dogfei

个人博客:www.dogfei.cn

1 声望

0 粉丝

宣传栏

现在这家单位的CICD比较的混乱,然后突发奇想,想改造下,于是就用pipeline做了一个简单的流水线,下面是关于它的一些介绍

写一个简单的流水线

【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级
大概就是这么个流程简单来说就是:拉代码---》编译---》打镜像---》推镜像---》部署到k8s中,下面的pipeline就是在这条主线上进行,根据情况进行增加

pipeline {

agent { label 'pdc&&jdk8' }

environment {

git_addr = "代码仓库地址"

git_auth = "拉代码时的认证ID"

pom_dir = "pom文件的目录位置(相对路径)"

server_name = "服务名"

namespace_name = "服务所在的命名空间"

img_domain = "镜像地址"

img_addr = "${img_domain}/cloudt-safe/${server_name}"

// cluster_name = "集群名"

}

stages {

stage('Clear dir') {

steps {

deleteDir()

}

}

stage('Pull server code and ops code') {

parallel {

stage('Pull server code') {

steps {

script {

checkout(

[

$class: 'GitSCM',

branches: [[name: '${Branch}']],

userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_addr}"]]

]

)

}

}

}

stage('Pull ops code') {

steps {

script {

checkout(

[

$class: 'GitSCM',

branches: [[name: 'pipeline-0.0.1']], //拉取的构建脚本的分支

doGenerateSubmoduleConfigurations: false,

extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'DEPLOYJAVA']], //DEPLOYJAVA: 把代码存放到此目录中

userRemoteConfigs: [[credentialsId: 'chenf-o', url: '构建脚本的仓库地址']]

]

)

}

}

}

}

}

stage('Set Env') {

steps {

script {

date_time = sh(script: "date +%Y%m%d%H%M", returnStdout: true).trim()

git_cm_id = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()

whole_img_addr = "${img_addr}:${date_time}_${git_cm_id}"

}

}

}

stage('Complie Code') {

steps {

script {

withMaven(maven: 'maven_latest_linux') {

sh "mvn -U package -am -amd -P${env_name} -pl ${pom_dir}"

}

}

}

}

stage('Build image') {

steps {

script {

dir("${env.WORKSPACE}/${pom_dir}") {

sh """

echo 'FROM 基础镜像地址' > Dockerfile //由于我这里进行了镜像的优化,只指定一个基础镜像地址即可,后面会详细的说明

"""

withCredentials([usernamePassword(credentialsId: 'faabc5e8-9587-4679-8c7e-54713ab5cd51', passwordVariable: 'img_pwd', usernameVariable: 'img_user')]) {

sh """

docker login -u ${img_user} -p ${img_pwd} ${img_domain}

docker build -t ${img_addr}:${date_time}_${git_cm_id} .

docker push ${whole_img_addr}

"""

}

}

}

}

}

stage('Deploy img to K8S') {

steps {

script {

dir('DEPLOYJAVA/deploy') {

//执行构建脚本

sh """

/usr/local/python3/bin/python3 deploy.py -n ${server_name} -s ${namespace_name} -i ${whole_img_addr} -c ${cluster_name}

"""

}

}

}

// 做了下判断如果上面脚本执行失败,会把上面阶段打的镜像删除掉

post {

failure {

sh "docker rmi -f ${whole_img_addr}"

}

}

}

stage('Clear somethings') {

steps {

script {

// 删除打的镜像

sh "docker rmi -f ${whole_img_addr}"

}

}

post {

success {

// 如果上面阶段执行成功,将把当前目录删掉

deleteDir()

}

}

}

}

}

优化构建镜像

上面的pipeline中有一条命令是生成Dockerfile的,在这里做了很多优化,虽然我的Dockerfile就写了一个FROM,但是在这之后又会执行一系列的操作,下面我们对比下没有做优化的Dockerfile
未优化

FROM 基础镜像地址

RUN mkdir xxxxx

COPY *.jar /usr/app/app.jar

ENTRYPOINT java -jar app.jar

优化后的

FROM 基础镜像地址

优化后的Dockerfile就这一行就完了。。。。。 下面简单介绍下这个ONBUILD
ONBUILD可以这样理解,就比如我们这里使用的镜像,是基于java语言做的一个镜像,这个镜像有两部分,一个是包含JDK的基础镜像A,另一个是包含jar包的镜像B,关系是先有A再有B,也就是说B依赖于A。
假设一个完整的基于Java的CICD场景,我们需要拉代码,编译,打镜像,推镜像,更新pod这一系列的步骤,而在打镜像这个过程中,我们需要把编译后的产物jar包COPY到基础镜像中,这就造成了,我们还得写一个Dockerfile,用来COPY jar包,就像下面这个样子:

FROM jdk基础镜像

COPY xxx.jar /usr/bin/app.jar

ENTRYPOINT java -jar app.jar

这样看起来也还好,基本上三行就解决了,但是能用一行就解决为什么要用三行呢?

FROM jdk基础镜像

ONBUILD COPY target/*.jar /usr/bin/app.jar

CMD ["/start.sh"]

打成一个镜像,比如镜像名是:java-service:jdk1.8,在打镜像的时候,ONBUILD后面的在本地打镜像的过程中不会执行,而是在下次引用时执行的

FROM java-service:jdk1.8

只需要这一行就可以了,并且这样看起来更加简洁,pipeline看起来也很规范,这样的话,我们每一个java的服务都可以使用这一行Dockerfile了。

使用凭据

有时候使用docker进行push镜像时需要进行认证,如果我们直接在pipeline里写的话不太安全,所以得进行脱敏,这样的话我们就需要用到凭据了,添加凭据也是非常简单,由于我们只是保存我们的用户名和密码,所以用Username with password类型的凭据就可以了,如下所示

【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级

比如说:拉取git仓库的代码需要用到,然后这里就添加一个凭据,对应与pipeline里的下面这段内容:

stage('Pull server code') {

steps {

script {

checkout(

[

$class: 'GitSCM',

branches: [[name: '${Branch}']],

userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_addr}"]]

]

)

}

}

}

这里的变量${git_auth}就是添加凭据时设置的ID,如果不设置ID会随机生成一个ID

然后docker push时会需要进行认证,也需要添加凭据,添加方式和上面是一样的,不过我们可以用pipeline的语法来生成一个,方式如下:
点击Pipeline Syntax
【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级

选择withCredentials: Bind credentials to variables

【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级

然后和之前添加的凭据进行绑定,这里选择类型为:Username and password (separated)

【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级

设置用户名和密码的变量名,然后选择刚才添加好的凭据

【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级

点击生成即可,就是上面pipeline里的下面这段:

withCredentials([usernamePassword(credentialsId: 'faabc5e8-9587-4679-8c7e-54713ab5cd51', passwordVariable: 'img_pwd', usernameVariable: 'img_user')]) {

sh """

docker login -u ${img_user} -p ${img_pwd} ${img_domain}

docker build -t ${img_addr}:${date_time}_${git_cm_id} .

docker push ${whole_img_addr}

"""

}

credentialsId: 这个ID就是随机生成的ID

执行脚本进行更新镜像

这里是使用python写了一个小脚本,来调用kubernetes的接口做了一个patch的操作完成的。先来看下此脚本的目录结构

【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级
核心代码:deploy.py
核心文件:config.yaml 存放的是kubeconfig文件,用于和kubernetes的认证

下面贴一下deploy.py的脚本内容,可以参考下:

import os

import argparse

from kubernetes import client, config

class deployServer:

def __init__(self, kubeconfig):

self.kubeconfig = kubeconfig

config.kube_config.load_kube_config(config_file=self.kubeconfig)

self._AppsV1Api = client.AppsV1Api()

self._CoreV1Api = client.CoreV1Api()

self._ExtensionsV1beta1Api = client.ExtensionsV1beta1Api()

def deploy_deploy(self, deploy_namespace, deploy_name, deploy_img=None, deploy_which=1):

try:

old_deploy = self._AppsV1Api.read_namespaced_deployment(

name=deploy_name,

namespace=deploy_namespace,

)

old_deploy_container = old_deploy.spec.template.spec.containers

pod_num = len(old_deploy_container)

if deploy_which == 1:

pod_name = old_deploy_container[0].name

old_img = old_deploy_container[0].image

print("获取上一个版本的信息\n")

print("当前Deployment有 {} 个pod, 为: {}\n".format(pod_num, pod_name))

print("上一个版本的镜像地址为: {}\n".format(old_img))

print("此次构建的镜像地址为: {}\n".format(deploy_img))

print("正在替换当前服务的镜像地址....\n")

old_deploy_container[deploy_which - 1].image = deploy_img

else:

print("只支持替换一个镜像地址")

exit(-1)

new_deploy = self._AppsV1Api.patch_namespaced_deployment(

name=deploy_name,

namespace=deploy_namespace,

body=old_deploy

)

print("镜像地址已经替换完成\n")

return new_deploy

except Exception as e:

print(e)

def run():

parser = argparse.ArgumentParser()

parser.add_argument('-n', '--name', help="构建的服务名")

parser.add_argument('-s', '--namespace', help="要构建的服务所处在的命名空间")

parser.add_argument('-i', '--img', help="此次构建的镜像地址")

parser.add_argument('-c', '--cluster',

help="rancher中当前服务所处的集群名称")

args = parser.parse_args()

if not os.path.exists('../config/' + args.cluster):

print("当前集群名未设置或名称不正确: {}".format(args.cluster), 'red')

exit(-1)

else:

kubeconfig_file = '../config/' + args.cluster + '/' + 'config.yaml'

if os.path.exists(kubeconfig_file):

cli = deployServer(kubeconfig_file)

cli.deploy_deploy(

deploy_namespace=args.namespace,

deploy_name=args.name,

deploy_img=args.img

)

else:

print("当前集群的kubeconfig不存在,请进行配置,位置为{}下的config.yaml.(注意: config.yaml名称写死,不需要改到)".format(args.cluster),

'red')

exit(-1)

if __name__ == '__main__':

run()

写的比较简单,没有难懂的地方,关键的地方是:

new_deploy = self._AppsV1Api.patch_namespaced_deployment(

name=deploy_name,

namespace=deploy_namespace,

body=old_deploy

)

这一句是执行的patch操作,把替换好新的镜像地址的内容进行patch。
然后就是执行就可以了。

其他

这里有一个需要注意的地方是pipeline里加了一个异常捕获,如下所示:

post {

success {

// 如果上面阶段执行成功,将把当前目录删掉

deleteDir()

}

}

生命式的pipeline和脚本式的pipeline的异常捕获的写法是有区别的,声明式写法是用的post来进行判断,比较简单,可以参考下官方文档

另外还有一个地方使用了并行执行,同时拉了服务的代码,和构建脚本的代码,这样可以提高执行整个流水线的速度,如下所示:

parallel {

stage('Pull server code') {

steps {

script {

checkout(

[

$class: 'GitSCM',

branches: [[name: '${Branch}']],

userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_addr}"]]

]

)

}

}

}

stage('Pull ops code') {

steps {

script {

checkout(

[

$class: 'GitSCM',

branches: [[name: 'pipeline-0.0.1']], //拉取的构建脚本的分支

doGenerateSubmoduleConfigurations: false,

extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'DEPLOYJAVA']], //DEPLOYJAVA: 把代码存放到此目录中

userRemoteConfigs: [[credentialsId: 'chenf-o', url: '构建脚本的仓库地址']]

]

)

}

}

}

}

嗯,情况就是这么个情况,一个简简单单的流水线就完成了,如果想快速使用流水线完成CICD,可以参考下这篇文章。

欢迎各位朋友关注我的公众号,来一起学习进步哦
【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级

以上是 【Python】结合k8s和pipeline的流水线,并通过k8s接口完成镜像升级 的全部内容, 来源链接: utcz.com/a/109173.html

回到顶部