美文网首页DevOps开发应用
Jenkins+Gitlab搭建CICD流程进阶——制品管理和自

Jenkins+Gitlab搭建CICD流程进阶——制品管理和自

作者: 文景大大 | 来源:发表于2022-10-12 17:01 被阅读0次

    一、制品的管理

    1.1 从Pipeline中下载制品

    在如上的pipeline流程中,我们是无法从Jenkins的流水线详情中下载制品的:

    pipeline中不能下载制品

    但Jenkins本身就支持该种模式,只需要将Jenkinsfile中的流水线定义改为:

    pipeline {
        agent any
    
        stages {
            stage('Build') {
                steps {
                    bat 'mvn -B -DskipTests clean package'
                }
            }
    
            stage('Archive') {
                steps {
                    archiveArtifacts artifacts: 'target/*.jar',allowEmptyArchive: true,fingerprint: true,onlyIfSuccessful: true
                }
            }
        }
    }
    

    再次运行流水线,就可以查看和下载制品了:

    pipeline中可以下载制品

    该种方式比较原始,需要手动下载和管理制品,不太推荐。

    1.2 将制品上传到私仓

    大多数公司都是有自己的制品私仓的,比如使用Nexus搭建的Maven仓库,这种方式比较适合研发中间件项目,直接上传到私仓供别的依赖项目使用了。

    方式一:通过maven

    首先项目的pom文件中需要增加如下配置:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.8.2</version>
            </plugin>
        </plugins>
    </build>
    
    <distributionManagement>
        <snapshotRepository>
            <id>nexus-snapshot</id>
            <name>my nexus snapshot</name>
            <url>http://10.x.x.x:8081/repository/maven-snapshots</url>
        </snapshotRepository>
        <repository>
            <id>nexus-release</id>
            <name>my nexus release</name>
            <url>http://10.x.x.x:8081/repository/maven-releases</url>
        </repository>
    </distributionManagement>
    

    然后在需要使用的maven settings.xml中增加nexus私仓的账密信息:

      <servers>
        <server>
            <id>nexus-snapshot</id>
            <username>admin</username>
            <password>password</password>
        </server>
        <server>
            <id>nexus-release</id>
            <username>admin</username>
            <password>password</password>
        </server>
      </servers>
    

    我们再修改pipeline的流程如下:

    pipeline {
        agent any
    
        stages {
            stage('Build') {
                steps {
                    bat 'mvn -B -DskipTests clean package'
                }
            }
    
            stage('Archive') {
                steps {
                    bat 'mvn deploy'
                }
            }
        }
    }
    

    提交代码,运行流水线,Deploy插件会根据Maven项目中定义的version值决定是使用nexus-snapshot仓库还是nexus-release仓库。当version值是以-SNAPSHOT后缀结尾时,则发布到nexus-snapshot仓库。

    如下是流水线输入日志的最后部分:

    Uploaded to nexus-snapshot: http://10.x.x.x:8081/repository/maven-snapshots/com/example/java-cicd-test/0.0.2-SNAPSHOT/java-cicd-test-0.0.2-20221012.055840-1.jar (18 MB at 14 MB/s)
    Uploading to nexus-snapshot: http://10.x.x.x:8081/repository/maven-snapshots/com/example/java-cicd-test/0.0.2-SNAPSHOT/java-cicd-test-0.0.2-20221012.055840-1.pom
    Progress (1): 2.2 kB
                        
    Uploaded to nexus-snapshot: http://10.x.x.x:8081/repository/maven-snapshots/com/example/java-cicd-test/0.0.2-SNAPSHOT/java-cicd-test-0.0.2-20221012.055840-1.pom (2.2 kB at 66 kB/s)
    Downloading from nexus-snapshot: http://10.x.x.x:8081/repository/maven-snapshots/com/example/java-cicd-test/maven-metadata.xml
    Uploading to nexus-snapshot: http://10.3.17.71:8081/repository/maven-snapshots/com/example/java-cicd-test/0.0.2-SNAPSHOT/maven-metadata.xml
    Progress (1): 775 B
                       
    Uploaded to nexus-snapshot: http://10.x.x.x:8081/repository/maven-snapshots/com/example/java-cicd-test/0.0.2-SNAPSHOT/maven-metadata.xml (775 B at 5.8 kB/s)
    Uploading to nexus-snapshot: http://10.x.x.x:8081/repository/maven-snapshots/com/example/java-cicd-test/maven-metadata.xml
    Progress (1): 285 B
                       
    Uploaded to nexus-snapshot: http://10.x.x.x:8081/repository/maven-snapshots/com/example/java-cicd-test/maven-metadata.xml (285 B at 9.2 kB/s)
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  14.466 s
    [INFO] Finished at: 2022-10-12T13:58:41+08:00
    [INFO] ------------------------------------------------------------------------
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] }
    [Pipeline] // withEnv
    [Pipeline] }
    [Pipeline] // node
    [Pipeline] End of Pipeline
    Finished: SUCCESS
    

    然后搜索nexus上我们的项目名称,就能搜索到了:

    nexus上搜索结果

    方式二:通过Jenkins插件

    首先需要在jenkins的插件市场上安装Nexus Platform,然后在Jenkins的系统设置中添加nexus服务的信息:

    !jenkins配置nexus服务](https://img.haomeiwen.com/i5673257/e14728f08afd0ab4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    然后需要我们编写流水线Archive阶段的脚本,这个有点复杂,我们借助Jenkins Pipeline流水线语法工具生成:

    使用pipeline语法生成器1
    使用pipeline语法生成器2
    使用pipeline语法生成器3
    • 示例步骤:选择nexus publisher;
    • nexus instance:选择上一步配置好的nexus服务;
    • nexus repository:根据自己需要选择release库或者snapshots库;
    • tag:随意;
    • packages Group:填写你项目的GroupId;
    • packages Artifact:填写你项目的ArtifactId;
    • packages Version:填写你项目的Version;
    • packages packaging:选择打包方式,我们是jar;
    • packages Artifacts File Path:选择需要上传的制品内容;

    其余保持默认不动。然后点击下面的“生成流水线脚本”按钮,即可得到该步骤的流水线脚本了,将其放到流水线文件中:

    pipeline {
        agent any
    
        stages {
            stage('Build') {
                steps {
                    bat 'mvn -B -DskipTests clean package'
                }
            }
    
            stage('Archive') {
                steps {
                    nexusPublisher nexusInstanceId: 'my-nexus', nexusRepositoryId: 'maven-snapshots', packages: [[$class: 'MavenPackage', mavenAssetList: [[classifier: '', extension: '', filePath: './target/*.jar']], mavenCoordinate: [artifactId: 'java-cicd-test', groupId: 'com.example', packaging: 'jar', version: '0.0.3-SNAPSHOT']]]
                }
            }
        }
    }
    

    然后提交代码,触发流水线运行,就能看到执行成功,同样查看下日志,并在nexus上搜索下我们的制品,这里同上,就不再赘述了。

    总结下,这两种方式,第二种的好处就是和nexus的配置,包括密码都保存在Jenkins的配置中了,Jenkins本身就有权限控制,比较安全;缺点就是pipeline的配置略显麻烦,不如maven的方式简单好用,个人比较推荐使用maven。

    1.3 将制品上传到镜像仓库

    首先我们自己新建一个镜像私仓,这个可以参考:Docker Registry的搭建与使用 - 简书 (jianshu.com)

    然后,我们需要在项目根目录下新增一个Dockerfile:

    FROM openjdk:8
    EXPOSE 8080
    ADD target/java-cicd-test-0.0.3-SNAPSHOT.jar /app/app.jar
    ENTRYPOINT ["java", "-jar", "/app/app.jar"]
    

    方式一:在Pipeline中使用docker命令

    我们修改pipeline的描述:

    pipeline {
        agent any
    
        stages {
            stage('Build') {
                steps {
                    bat 'mvn -B -DskipTests clean package'
                }
            }
    
            stage('Archive') {
                steps {
                    bat 'docker build -t java-cicd-test:0.0.3-SNAPSHOT .'
                    bat 'docker tag java-cicd-test:0.0.3-SNAPSHOT localhost:5000/java-cicd-test:0.0.3-SNAPSHOT'
                    bat 'docker push localhost:5000/java-cicd-test:0.0.3-SNAPSHOT'
                }
            }
        }
    }
    

    提交代码运行流水线,就能将当前项目打成镜像并提交到私仓镜像仓库了。

    C:\Users\zhangxun\.jenkins\workspace\java-cicd-test>docker push localhost:5000/java-cicd-test:0.0.3-SNAPSHOT 
    The push refers to repository [localhost:5000/java-cicd-test]
    cc71e4dd775f: Preparing
    bff9fe6e429c: Preparing
    7c245b2fe4f1: Preparing
    f9e18e59a565: Preparing
    26a504e63be4: Preparing
    8bf42db0de72: Preparing
    31892cc314cb: Preparing
    11936051f93b: Preparing
    8bf42db0de72: Waiting
    31892cc314cb: Waiting
    11936051f93b: Waiting
    7c245b2fe4f1: Pushed
    f9e18e59a565: Pushed
    cc71e4dd775f: Pushed
    8bf42db0de72: Pushed
    31892cc314cb: Pushed
    11936051f93b: Pushed
    bff9fe6e429c: Pushed
    26a504e63be4: Pushed
    0.0.3-SNAPSHOT: digest: sha256:06fb42031d422fbfdac62918ccdf375537e145f607a01409198eaf9c7fba4c13 size: 2007
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] }
    [Pipeline] // withEnv
    [Pipeline] }
    [Pipeline] // node
    [Pipeline] End of Pipeline
    Finished: SUCCESS
    

    真实生产中,我们搭建的镜像仓库或者使用的公有云进行仓库,比如阿里云、腾讯云镜像仓库肯定是需要登录验证的,只需要加一行命令docker login --username=xxx --password=xxx即可,而且公有云镜像仓库还配有webhook,可用于让Jenkins监控到镜像推送是否成功,从而决定是否继续下一个部署操作,这块内容和上面讲解sonarqube比较类似,而且需要开通公有云服务,此处就不展开了。

    方式二:使用maven的docker插件

    由于我们项目使用的是Spring Boot2.7.3,自身就包含了对镜像制作的支持,因此无需下载和引入其它插件,而且也不需要项目根目录下的Dockefile。

    首先,我们需要设置本地的Docker Engine,使之对外暴露端口,否则SpringBoot无法和Docker Engine进行交互:

    本地DockerEngine暴露访问端口

    然后,我们pom中增加如下配置:

        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <excludes>
                            <exclude>
                                <groupId>org.projectlombok</groupId>
                                <artifactId>lombok</artifactId>
                            </exclude>
                        </excludes>
                        <image>
                            <!--镜像名称-->
                            <name>localhost:5000/${project.name}:${project.version}</name>
                            <!--生成镜像后是否推送到镜像仓库-->
                            <publish>true</publish>
                        </image>
                        <docker>
                            <!--docker daemon地址,此处是本机的Docker Desktop暴露的地址-->
                            <host>http://localhost:2375</host>
                            <!--不使用TLS访问-->
                            <tlsVerify>false</tlsVerify>
                            <!--Docker推送镜像仓库配置-->
                            <publishRegistry>
                                <!--推送镜像仓库用户名-->
                                <username>admin</username>
                                <!--推送镜像仓库密码-->
                                <password>admin</password>
                                <!--推送镜像仓库地址-->
                                <url>http://localhost:5000</url>
                            </publishRegistry>
                        </docker>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    

    然后执行构建命令mvn spring-boot:build-image或者双击IDEA中Maven面板中的SpringBoot:build-image,就可以尝试镜像的制作了。此处需要下载一些内容,时间较长,对github的访问也要畅通。如果能顺利完成的话,我们修改Pipeline中内容:

    pipeline {
        agent any
    
        stages {
            stage('Build') {
                steps {
                    bat 'mvn -B -DskipTests clean package'
                }
            }
    
            stage('Archive') {
                steps {
                    bat 'mvn spring-boot:build-image'
                }
            }
        }
    }
    

    如此就可以通过简单的配置晚上将项目打包镜像推送到私仓中了。

    总结下,这两种方式,个人比较偏向第一种,Dockerfile比较灵活,可以定制自己需要的内容,而且docker命令比较直观简单,方便修改。第二种方式试了几次,因为不能从github很流畅地下载内容,并没有真的实验成功,估计在真实环境中也会存在这个问题。

    二、自动部署

    自动部署则是在Jenkinsfile中增加一个stage,通过远程命令或者接口调用的方式将制品从私仓中拉取到目标服务器上进行部署。这块内容如果涉及远程服务器或者公有云,甚至是k8s集群会比较复杂,此处为简单演示起见,就在本机上演示下如何将上一步的镜像拉取下来进行部署。

    修改Jenkinsfile如下:

    pipeline {
        agent any
    
        stages {
            stage('Build') {
                steps {
                    bat 'mvn -B -DskipTests clean package'
                }
            }
    
            stage('Archive') {
                steps {
                    bat 'docker build -t java-cicd-test:0.0.4-SNAPSHOT .'
                    bat 'docker tag java-cicd-test:0.0.4-SNAPSHOT localhost:5000/java-cicd-test:0.0.4-SNAPSHOT'
                    bat 'docker push localhost:5000/java-cicd-test:0.0.4-SNAPSHOT'
                }
            }
    
            stage('Deploy') {
                steps {
                    bat 'docker pull localhost:5000/java-cicd-test:0.0.4-SNAPSHOT'
                    bat 'docker run -d -p 8080:8080 --name java-cicd-test localhost:5000/java-cicd-test:0.0.4-SNAPSHOT'
                }
            }
        }
    }
    

    然后提交代码运行流水线,流水线能正常运行成功,且发现新的0.0.4-SNAPSHOT镜像已经成功上传私仓镜像仓库。然后我们看下本地的Docker Desktop,发现镜像也从私仓中拉取下来并成功运行了。

    私仓镜像上传成功 将制品镜像pull到目标服务器 使用制品镜像在目标服务器上运行

    DevOps和CICD是一个永恒的话题,其中的思想、组件、工具都有很多种选择,没有说一定要如何如何,各家公司也需要按照自己实际情况制定合适的流水线模式。

    相关文章

      网友评论

        本文标题:Jenkins+Gitlab搭建CICD流程进阶——制品管理和自

        本文链接:https://www.haomeiwen.com/subject/inatzrtx.html