在前一篇文章,使用了常规的方式,部署了一套k8s电商demo系统。在日常的工作,在系统部署好,还会有持续版本的更新,如果还采用手工的方式进行版本上载,既繁杂,又很容易出错,所以,这篇文章将采用Jenkins对这套系统进行持续集成和部署。

操作的大体流程为:

  1. 建立流水线项目,让Jenkins从gitee中拉取代码到本地,在本地通过dockerfile的方式对代码进行编译和制作镜像,并将镜像上传到Harbor镜像仓库
  2. 镜像的构建采取参数化构建的方式,对每个版本的代码创建标签tag,通过tag对指定版本的代码构建镜像
  3. 流水线项目配置邮件通知功能,将镜像构建结果通过邮件的方式进行通知
  4. 建立自由风格项目,将应用部署到k8s集群当中

下面以应用passport为例对流程进行介绍。

建立build-k8sdemo-passport流水线项目

配置如下参数

勾选参数化构建,并配置参数

通过scm方式构建流水线

最后点击保存

这里需要注意的是,通过scm方式构建流水线项目,需要在原本的代码中增加一个Jenkinsfile,通过在里面配置各个步骤,对流程进行控制

拉取代码

stage('拉取Git代码') {
            steps {
                checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'https://gitee.com/beretxj/k8sdemo-passport.git']]])
            }

 首先从gitee中拉取代码,这里使用gitee只是因为方便,同时,这里也可以使用自建的gitlab,使用方式都一样

如果主机资源充足,还可以用sonarcube对代码进行扫描,因为机器资源有限,这里没有安装,但将相关步骤留空,方便后续扩展

stage('检测代码质量') {
            steps {
                echo '检测代码质量'
            }
        }

构建镜像

 

stage('传送构建代码') {
            steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: 'aa-k8s', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'k8sdemo-passport', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '**/*')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }
        }

        stage('制作自定义镜像') {
            steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: 'aa-k8s', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''cd  /data/code_k8s/k8sdemo-passport/
docker build -t passport:${tag} . 
docker tag passport:v1.0 10.0.20.10:80/k8srepo/passport:${tag}''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }
        }

        stage('发布镜像到Harbor') {
            steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: 'aa-k8s', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''docker login -u admin -p Harbor12345  10.0.20.10:80
docker push 10.0.20.10:80/k8srepo/passport:${tag}''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }
        }

随后传输代码到镜像制作的机器,并制作镜像,上传镜像到仓库

pipeline方式构建中间那个命令是有语法格式要求的,如果不清楚怎么写,可以采用在创建流水线项目的最下面,点击流水线语法,选择相应项目及做了配置后,可以自动生成相应的命令,很方便。

 邮件通知

在Jenkins下方设置邮件模板,邮件通知和项目构建是平级的,不能配置在项目步骤中

   post{
            
        success {
            script {
                if (sendmail == 'yes') {
           emailext body: '''<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head><body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0">
    <table width="95%" cellpadding="0" cellspacing="0"
        style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
        <tr>
            <td><br />
            <b><font color="#0B610B">构建信息</font></b>
            <hr size="2" width="100%" align="center" /></td>
        </tr>
        <tr>
            <td>
                <ul> 
                    <li>构建名称:${JOB_NAME}</li>
                    <li>构建结果: <span style="color:green"> ${BUILD_STATUS}</span></li> 
                    <li>构建编号:${BUILD_NUMBER}  </li>
                    <li>GIT 地址:${git_url}</li>                    
                    <li>GIT 分支:${git_branch}</li>
                    <li>变更记录: ${CHANGES,showPaths=true,showDependencies=true,format="<pre><ul><li>提交ID: %r</li><li>提交人:%a</li><li>提交时间:%d</li><li>提交信息:%m</li><li>提交文件:<br />%p</li></ul></pre>",pathFormat="         %p <br />"}
                </ul>
            </td>
        </tr>
    </table>
</body>
</html>
''', subject: '${PROJECT_NAME}', to: '111111@qq.com,222222@qq.com'
                }
            }
        }
         
        failure {
            
            script {
                if (gitpullerr == 'noerr') {
                emailext body: '''<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"
    offset="0">
    <table width="95%" cellpadding="0" cellspacing="0"
        style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
        <tr>
            <td><br />
            <b><font color="#0B610B">构建信息</font></b>
            <hr size="2" width="100%" align="center" /></td>
        </tr>
        <tr>
            <td>
                <ul> 
                    <li>构建名称:${JOB_NAME}</li>
                    <li>构建结果: <span style="color:red"> ${BUILD_STATUS}</span></li>  
                    <li>构建编号:${BUILD_NUMBER}  </li>
                    <li>GIT 地址:${git_url}</li>                    
                    <li>GIT 分支:${git_branch}</li>
                    <li>变更记录: ${CHANGES,showPaths=true,showDependencies=true,format="<pre><ul><li>提交ID: %r</li><li>提交人:%a</li><li>提交时间:%d</li><li>提交信息:%m</li><li>提交文件:%p</li></ul></pre>",pathFormat="%p <br />"}
                </ul>
            </td>
        </tr>
        <tr>
            <td><b><font color="#0B610B">构建日志 :</font></b>
            <hr size="2" width="100%" align="center" /></td>
        </tr>
        <tr>
            <td><textarea cols="150" rows="30" readonly="readonly"
                    style="font-family: Courier New">${BUILD_LOG}</textarea>
            </td>
        </tr>
    </table>
</body>
</html>
''', subject: '${PROJECT_NAME}', to: '111111@qq.com,222222@qq.com'
            }else {
                echo 'scm pull error ignore send mail'
            }
            
        }
        }
    }

由于这里使用了变量判断,需要在最开头声明变量

    environment {
        
        gitpullerr = 'noerr'
        sendmail = 'yes'
 
    }

在Jenkins中进行参数化构建

进入Jenkins,会在首页看到刚刚创建好的项目,点击进去

点击build with parameters,这里会有从gitee读取的版本参数信息 

v1.1是单独在gitee中设置的,设置好,Jenkins就能读取到

 

点击开始构建

 在这个界面可以看到构建过程,如果失败,会显示红色,并可以查看相关日志,方便定位报错原因

 由于这里配置了邮件通知,所以最后构建成功后,会发送一个构建成功的邮件通知

如果构建失败,也会有失败邮件通知

 

 检查构建情况

进入仓库,可以看到镜像已经上传成功

 建立deploy-k8sdemo-passport自由风格项目

我们把构建和部署分开,部署主要就是从仓库中拉取指定项目的镜像进行部署。

如果是用docker run的方式进行部署,要稍微麻烦一些,是需要后台停止容器,再启动容器,相关的命令如下

a=`docker ps -a |grep cos_mall | wc -l`
if [ $a -gt 0 ];then docker rm -f $(docker ps -q --filter "name=cos_mall");fi
docker run -it --rm -p 801:80 -d --name=cos_mall 10.0.20.10:80/k8srepo/cos_mall:${tag}

如果是采用k8s部署,则简单很多,将相应的yaml文件放到gitee对应的项目下即可,直接一个命令进行部署

kubectl apply -f /data/jenkins-k8s/k8sdemo-passport.yml

使用apply命令可以直接停止删除旧的pod,并启动新的pod,命令上简单很多

同样采取参数化构建方式

 构建完成后,查看日志成功情况,并后台检查即可

 

总结

实际的部署过程会很繁杂,需要反复配置,这也模拟了真实的工作过程,需要认真和仔细,最后的部署完成的结果如下

 

 后台检查,容器也运行正常

 登录网址,点击各个栏目也ok,如此,我们完成了demo项目的jenkins CI/CD

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐