赛尔校园公共服务平台 Logo
平台使用
阿里云
百度云
移动云
智算服务
教育生态
登录 →
赛尔校园公共服务平台 Logo
平台使用 阿里云 百度云 移动云 智算服务 教育生态
登录
  1. 首页
  2. 阿里云
  3. 容器镜像服务
  4. 实践教程
  5. 使用Jenkins实现镜像的CICD

使用Jenkins实现镜像的CICD

  • 实践教程
  • 发布于 2025-04-18
  • 0 次阅读
文档编辑
文档编辑

若您期望实现从源代码自动构建、推送镜像到最终部署应用的一体化自动化操作。您可以使用Jenkins实现镜像的CI/CD,只要您在GitLab中提交源代码,容器镜像会自动使用源代码构建镜像,容器服务会自动拉取镜像部署应用,并自动发送事件通知到钉钉群。

前提条件

  • 已安装Git、GitLab和Jenkins。

    说明

    GitLab需要安装JDK8,部分插件不能在JDK11上运行。

  • 已创建ACR企业版实例,并且开启公网访问。具体操作,请参见创建企业版实例和配置公网的访问控制。

  • 已创建ACK集群,且与ACR实例位于同一地域。具体操作,请参见创建Kubernetes托管版集群。

  • 已创建钉钉机器人,并记录下Webhook地址和加签密钥。具体操作,请参见步骤一:创建钉钉机器人。

  • 使用ACR的交付链功能,需要您升级至ACR高级版实例。具体操作,请参见计费说明。

使用Jenkins实现镜像的CI

只要您在GitLab中提交源代码,容器镜像会自动使用源代码构建镜像,然后您可以对镜像进行漏洞扫描,镜像扫描完成后,将自动发送事件通知到钉钉群。

  1. 在GitLab中创建项目。

    1. 登录GitLab。

    2. 在顶部导航栏中,选择Projects > Your projects 。

    3. 在Projects页面单击右上角的New Project,单击Create blank project。

    4. 在Create blank project页面设置Project name、Project URL和Project slug,设置Visibility Level为Private,然后单击Create project。

      创建Project

    5. 使用以下内容,在本地创建Dockerfile、pom.xml、DemoApplication.java和HelloController.java文件。

      • Dockerfile

        FROM registry.cn-hangzhou.aliyuncs.com/public-toolbox/maven:3.8.3-openjdk-8-aliyun AS build
        COPY src /home/app/src
        COPY pom.xml /home/app
        RUN ["/usr/local/bin/mvn-entrypoint.sh","mvn","-f","/home/app/pom.xml","clean","package","-Dmaven.test.skip=true"]
        
        FROM registry.cn-hangzhou.aliyuncs.com/public-toolbox/openjdk:8-jdk-alpine
        COPY --from=build /home/app/target/demo-0.0.1-SNAPSHOT.jar /usr/local/lib/demo-0.0.1-SNAPSHOT.jar
        EXPOSE 8080
        ENTRYPOINT ["java","-jar","/usr/local/lib/demo-0.0.1-SNAPSHOT.jar"]
      • pom.xml

        <?xml version="1.0" encoding="UTF-8"?>
        <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
            <modelVersion>4.0.0</modelVersion>
            <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>2.6.1</version>
                <relativePath/> <!-- lookup parent from repository -->
            </parent>
            <groupId>com.example</groupId>
            <artifactId>demo</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <name>demo</name>
            <description>Demo project for Spring Boot</description>
            <properties>
                <java.version>1.8</java.version>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-freemarker</artifactId>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </dependency>
        
                <dependency>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                    <optional>true</optional>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-test</artifactId>
                    <scope>test</scope>
                </dependency>
                <dependency>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-core</artifactId>
                    <version>2.13.2</version>
                </dependency>
            </dependencies>
        
            <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>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        
        </project>
      • DemoApplication.java

        package com.example.demo;
        
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        
        import java.util.TimeZone;
        
        @SpringBootApplication
        public class DemoApplication {
        
            public static void main(String[] args) {
                TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
                SpringApplication.run(DemoApplication.class, args);
            }
        
        }
      • HelloController.java

        package com.example.demo;
        
        import lombok.extern.slf4j.Slf4j;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
        
        import javax.servlet.http.HttpServletRequest;
        import java.text.SimpleDateFormat;
        import java.util.Date;
        
        @RestController
        @Slf4j
        public class HelloController {
        
            @RequestMapping({"/hello", "/"})
            public String hello(HttpServletRequest request) {
                return "Hello World at " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            }
        }
    6. 执行以下命令,上传构建文件至GitLab。

      cd java-web  #进入构建文件所在目录。
      git remote set-url origin http://8.218.20*.***/shoppingmall/java-web.git
      git push origin master
      * [new branch]      master -> master
  2. 在Jenkins配置构建镜像的流水线。

    1. 在Jenkins配置GitLab的SSH Key。

      1. 登录Jenkins。

      2. 在Jenkins左侧导航栏单击系统管理。

      3. 在安全区域单击Manage Credentials。

      4. 在Stores scoped to Jenkins区域单击存储列下的Jenkins,然后单击全局凭据。

      5. 在左侧导航栏单击添加凭据。

      6. 设置类型为SSH Username with private key,然后输入描述、Username,选中Enter directly,然后单击确定。

        在全局凭据页面会自动生成凭据ID,保存该凭据ID。

    2. 创建流水线。

      1. 在Jenkins左侧导航栏单击新建任务。

      2. 输入任务名称,选中流水线,单击确定。

      3. 单击构建触发器页签,选中Build when a change is pushed to GitLab,然后选中Push Events。

        在Build when a change is pushed to GitLab右侧记录Webhook的地址。

      4. 单击高级,单击Secret token右下角的Generate。

        Jenkins会生成一个Secret token,保存该Secret token。

      5. 单击流水线页签,根据实际情况修改以下模板,然后将内容复制到文本框中,然后单击保存。

        def git_auth_id = "6d5a2c06-f0a7-43c8-9b79-37b8c266****"  #凭据ID
        def git_branch_name = "master" #分支名
        def git_url = "git@172.16.1*.***:shoppingmall/java-web.git"   #GitLab仓库地址
        def acr_url = "s*****-devsecops-registry.cn-hongkong.cr.aliyuncs.com"  #镜像仓库地址
        def acr_username = "acr_test_*****@test.aliyunid.com"   #容器镜像用户名
        def acr_password = "HelloWorld2021"   #容器镜像密码
        def acr_namespace = "ns"    #命名空间
        def acr_repo_name = "test"   #镜像仓库名称
        def tag_version = "0.0.1"   #镜像版本
        node {
        
            stage('checkout git repo') {
                checkout([$class: 'GitSCM', branches: [[name: "*/${git_branch_name}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth_id}", url: "${git_url}"]]])
            }
            stage('build image') {
                sh "sudo docker build -t java-web:${tag_version} ."
                sh "sudo docker tag java-web:${tag_version} ${acr_url}/${acr_namespace}/${acr_repo_name}:${tag_version}"
            }
            stage('push image') {
                sh "sudo docker login --username=${acr_username} --password=${acr_password} ${acr_url}"
                sh "sudo docker push ${acr_url}/${acr_namespace}/${acr_repo_name}:${tag_version}"
            }
        }
  3. 添加Webhook地址到GitLab中。

    1. 登录GitLab。

    2. 在Projects页面单击上文创建的Project名称。

    3. 在左侧导航栏选择Settings > Webhooks,输入Webhook地址和Secret token,取消选中Enable SSL verification,然后单击Add webhooks。

  4. 创建事件通知。

    1. 登录容器镜像服务控制台。

    2. 在顶部菜单栏,选择所需地域。

    3. 在左侧导航栏,选择实例列表。

    4. 在实例列表页面单击目标企业版实例。

    5. 在实例详情页面左侧导航栏选择实例管理 > 事件通知 。

    6. 在事件规则页签下单击创建规则。

    7. 在事件范围配置向导中设置规则名称,事件类型为镜像扫描完成,选中扫描完成,设置生效范围为命名空间,选择命名空间为ns,然后单击下一步。

    8. 在事件通知配置向导中设置通知方式为钉钉,输入钉钉的Webhook地址和加签密钥,然后单击保存。

  5. 触发镜像构建。

    执行以下命令,修改HelloController.java文件,提交文件到GitLab中,从而触发镜像构建。

    vim java/com/example/demo/HelloController.java #根据实际情况在本地修改HelloController.java文件
    git add . && git commit -m 'commit' && git push origin #提交文件到GitLab

    稍等一段时间,在企业版实例详情页面左侧导航栏选择仓库管理 > 镜像仓库,在右侧页面单击目标仓库test,在仓库管理页面左侧导航栏单击镜像版本,可以看到镜像版本页面生成一个镜像。

  6. 设置漏洞扫描。

    1. 在镜像版本页面单击目标镜像右侧操作下的安全扫描。

    2. 在安全扫描页面,单击立即扫描。

      待镜像扫描完成后,您可以在钉钉群里收到通知。

使用Jenkins实现镜像的CD

只要您在GitLab中提交源代码,容器镜像会自动用源代码构建镜像,镜像构建成功后,自动触发执行交付链,待交付链运行完成后,将自动发送HTTP请求至Jenkins,然后触发ACK的Deployment重新拉取镜像部署应用。

  1. 创建应用。

    1. 登录容器服务管理控制台。

    2. 在控制台左侧导航栏,单击集群。

    3. 在集群列表页面,单击目标集群名称或者目标集群右侧操作列下的详情。

    4. 在集群管理页左侧导航栏,选择工作负载 > 无状态。

    5. 在无状态页面单击右上角的使用YAML创建资源。

    6. 在创建页面顶部选择命名空间,设置示例模板为自定义,然后复制以下内容到模板中,然后单击创建。

      说明

      没有设置免密拉取镜像,您需要在容器镜像服务中开启公网访问,并设置镜像为公开镜像。具体操作,请参见配置公网的访问控制。

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        creationTimestamp: null
        labels:
          app: demo
        name: demo
      spec:
        replicas: 3
        minReadySeconds: 5
        progressDeadlineSeconds: 60
        revisionHistoryLimit: 5
        selector:
          matchLabels:
            app: demo
        strategy:
          rollingUpdate:
            maxUnavailable: 1
          type: RollingUpdate
        template:
          metadata:
            annotations:
              prometheus.io/port: "9797"
              prometheus.io/scrape: "true"
            creationTimestamp: null
            labels:
              app: demo
          spec:
            containers:
            - image: s*****-devsecops-registry.cn-hongkong.cr.aliyuncs.com/ns/test:0.0.1 
              imagePullPolicy: Always
              name: demo
              ports:
              - containerPort: 8080
                name: http
                protocol: TCP
              readinessProbe:
                initialDelaySeconds: 5
                tcpSocket:
                  port: 8080
                timeoutSeconds: 5
              resources:
                limits:
                  cpu: "2"
                  memory: 512Mi
                requests:
                  cpu: 100m
                  memory: 64Mi
      status: {}
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: demo-svc
      spec:
        selector:
          app: demo
        ports:
          - protocol: TCP
            port: 80
            targetPort: 8080
      ---
      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: demo
        labels:
          app: demo
      spec:
        rules:
          - host: app.demo.example.com
            http:
              paths:
                - backend:
                    serviceName: demo-svc
                    servicePort: 80
      ---
                                      
    7. 在无状态页面单击目标应用demo,单击访问方式页签。

      在访问方式页签下获取外部端点地址。

    8. 在本地hosts绑定以下内容。

      <外部端点地址> app.demo.example.com
    9. 在浏览器中输入app.demo.example.com。

      应用看到以上页面,说明应用部署成功。

  2. 创建触发器。

    1. 在无状态页面单击目标应用demo的名称。

    2. 在应用详情页面单击触发器页签,单击创建触发器。

    3. 在创建触发器对话框设置触发器行为为重新部署,然后单击确定。

      在触发器页签下获取触发器链接。

  3. 创建流水线。

    1. 登录Jenkins。

    2. 在左侧导航栏单击新建任务。

    3. 输入任务名称,单击流水线。

    4. 单击构建触发器页签,选中Generic Webhook Trigger。

      在Generic Webhook Trigger下可以获取HTTP请求触发地址为JENKINS_URL/generic-webhook-trigger/invoke,本文设置Generic Webhook token为helloworld2021,因此Webhook地址为JENKINS_URL/generic-webhook-trigger/invoke?token=helloworld2021。

    5. 单击流水线页签,根据实际情况修改以下模板中的Generic Webhook token和触发器链接,然后将内容复制到文本框中,然后单击保存。

      pipeline {
        agent any
        triggers {
          GenericTrigger(
           genericVariables: [
            [key: 'InstanceId', value: '$.data.InstanceId'],   
            [key: 'RepoNamespaceName', value: '$.data.RepoNamespaceName'],
            [key: 'RepoName', value: '$.data.RepoName'],
            [key: 'Tag', value: '$.data.Tag']
           ],
           causeString: 'Triggered on $ref',
           token: 'helloworld2021',   #Generic Webhook token,请根据实际情况替换。
           tokenCredentialId: '',
           printContributedVariables: true,
           printPostContent: true,
           silentResponse: false,
           regexpFilterText: '$ref'
          )
        }
        stages {
          stage('Some step') {
            steps {
              sh "echo 'will print post content'"
              sh "echo $InstanceId"
              sh "echo $RepoNamespaceName"
              sh "echo $RepoName"
              sh "echo $Tag"
              sh "echo 'redeploy to ACK or you can deoloy to other platforms use before message'"
              sh "curl 'https://cs.console.aliyun.com/hook/trigger?token=g****'  #触发器链接,请根据实际情况替换。
              sh "echo 'done'"
            }
          }
        }
      }
  4. 创建交付链。具体操作。请参见创建交付链。

  5. 创建事件规则。

    1. 在企业版实例管理页面左侧导航栏中选择实例管理 > 事件通知。

    2. 在事件规则页签下单击创建规则。

    3. 在事件范围配置向导中设置规则名称,事件类型为交付链处理完成,选中成功,设置生效范围为命名空间,选择命名空间为ns,然后单击下一步。

    4. 在事件通知配置向导中设置通知方式为HTTP,输入步骤3获取的Webhook地址,然后单击保存。

  6. 执行以下命令,修改HelloController.java文件,提交代码到GitLab中,从而触发镜像构建。

    vim java/com/example/demo/HelloController.java #根据实际情况在本地修改HelloController.java文件。
    git add . && git commit -m 'add update' && git push origin   #提交文件到GitLab中。

    镜像构建成功后,触发执行交付链,交付链执行完毕后,触发ACK的Deployment重新拉取镜像部署应用。

  7. 执行以下命令,验证应用是否重新部署。

    curl app.demo.example.com

    可以看到输出内容发生了变化, 说明应用重新部署成功。

相关文章

使用OCI v1.1.0规范管理和关联容器镜像及其衍生制品 2025-04-18 15:15

从2024年04月起,新创建的ACR企业版实例将支持OCI的Image和Distribution规范v1.1.0,包括对Reference Types的支持。这意味着您除了可以存储和分发容器镜像外,还能管理和分发非容器镜像内容的OCI制品,如镜像签名和软件物料清单(SBOM)。这使您能够像管理容器镜

使用触发器构建容器DevOps 2025-04-18 15:15

通过容器镜像服务可以便捷地构建基于容器的DevOps开发环境。本文介绍如何使用触发实现镜像代码被修改后,自动触发镜像构建,且自动触发容器服务上应用的重新部署。 前提条件 已绑定企业版实例与阿里云Codeup代码平台。<

使用Jenkins实现镜像的CICD 2025-04-18 15:15

若您期望实现从源代码自动构建、推送镜像到最终部署应用的一体化自动化操作。您可以使用Jenkins实现镜像的CI/CD,只要您在GitLab中提交源代码,容器镜像会自动使用源代码构建镜像,容器服务会自动拉取镜像部署应用,并自动发送事件通知到钉钉群。 前提条件

Java项目容器化构建最佳实践 2025-04-18 15:15

使用Dockerfile将源代码构建成容器镜像,进行镜像分发、部署。相比于Golang或Python项目,Java项目因企业一般会选择自建依赖仓库(如Maven)导致容器化构建难度高,因不熟悉Dockerfile缓存机制导致构建速度较慢。本文从典型用户场景(云上自建GitLab代码仓库、自建Mave

在Dockerfile中使用构建打包镜像并运行 2025-04-18 15:15

通过使用多阶段构建应用以及结合阿里云容器镜像服务(ACR)的镜像构建服务,可以使Java应用具有构建安全、构建速度快、镜像文件体积小等优点。 前提条件

本地构建和推送多架构镜像到容器镜像服务 2025-04-18 15:15

使用ARM架构资源部署容器通常可以节省不少成本,但也可能导致维护成本增加,您可能需要面向x86、ARM架构分别构建镜像并设置不同的Tag。您可以使用docker buildx来构建多架构镜像,并通过docker manifest实现一个Tag管理多架构的容器镜像。 前提条件

目录
Copyright © 2025 your company All Rights Reserved. Powered by 赛尔网络.
京ICP备14022346号-15
gongan beian 京公网安备11010802041014号