OpenShift 4 - DevSecOps Workshop (Jenkins版)

OpenShift 4.x HOL教程汇总
说明:本文已经在OpenShift 4.8环境中验证

DevSecOps Workshop 说明

本Workshop参考了“RedHatGov/devsecops-workshop-dashboard”,使用 Jenins 作为 CI/CD 的引擎实现如下 DevSecOps 的应用发布流程:

  1. 代码从Gogs克隆到Jenkins的执行器节点上。
  2. 代码由Jenkins使用Maven构建。
  3. 针对源代码执行JUnit测试。
  4. 通过SonarQube分析源代码的漏洞、错误和不良模式。
  5. 将WAR工件推送到Nexus存储库管理器。
  6. 将基于JBossEAP上的任务应用于WAR工件,建立一个容器镜像(tasks:latest)。
  7. 将容器镜像部署在DEV项目的一个新容器中。
  8. 在STAGE项目中,DEV镜像被标记为应用程序版本(tasks:7.x)。
  9. 镜像被部署在STAGE项目的一个新容器中。
    在这里插入图片描述

安装 DevSecOps Workshop

参照以下文档安装Jenkins、Nexus、SonarQube、Gogs等Workshop需要的组件。
Hands-on Lab (8) - 基于Gogs+Nexus+Sonarqube的Jenkins CI/CD Pipeline

注意:如果需要 Image Registry 环境,可自行在 OpenShift 上安装 Quay,或使用 Quay.io。

Jenkins Pipeline 操作步骤

完成上面的“Hands-on Lab (8) - 基于Gogs+Nexus+Sonarqube的Jenkins CI/CD Pipeline”安装过程后就已经有了一个完整的 Jenkins Pipeline 过程,如果需要还可参照以下一个教程从零开始实现一个完成的 Jenkins Pipeline 过程。

  • http://redhatgov.io/workshops/secure_software_factory
  • https://github.com/liuxiaoyu-git/devsecops-workshop-dashboard/tree/develop/jenkins/workshop/content

注意:Hands-on Lab (8) 中自带的 Jenkins Pipeline 配置和以上2个 Jenkins Pipeline 的配置稍有差别。

最终Jenkins Pipeline配置

最终 Jenkins Pipeline 的配置可参见以下或 https://github.com/liuxiaoyu-git/OpenShift-HOL/blob/master/devsecops-jenkins.yaml
注意

kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
  name: tasks-pipeline
  namespace: cicd-demo-cicd
spec:
  successfulBuildsHistoryLimit: 5
  failedBuildsHistoryLimit: 5
  strategy:
    type: JenkinsPipeline
    jenkinsPipelineStrategy:
      jenkinsfile: >-
        def version, mvnCmd = "mvn -s configuration/cicd-settings-nexus3.xml"
		
        def oc_user = "opentlc-mgr" 
		
        def oc_pass = "r3dh4t1!" 
		
        def ocp_api = "api.cluster-6d16.6d16.sandbox1717.opentlc.com:6443" 
		
        def ocp_registry = "default-route-openshift-image-registry.apps.cluster-6d16.6d16.sandbox1717.opentlc.com"
		
        def quay_user = "user1" 
		
        def quay_pass = "openshift" 
		
        def quay_repo = "jboss-eap70-openshift" 
		
        def quay_server="quay.apps.cluster-6d16.6d16.sandbox1717.opentlc.com"
		
        pipeline {
    
    
          agent {
    
    
            label 'maven'
          }
          stages {
    
    
            stage('Build App') {
    
    
              steps {
    
    
                git branch: 'eap-7', url: 'http://gogs:3000/gogs/openshift-tasks.git'
                script {
    
    
                    def pom = readMavenPom file: 'pom.xml'
                    version = pom.version
                  }
                sh "${
    
    mvnCmd} install -DskipTests=true"
              }
            }
            stage('Test') {
    
    
              steps {
    
    
                sh "${
    
    mvnCmd} test"
                step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*.xml'])
              }
            }
            stage('Code Analysis') {
    
    
              steps {
    
    
                script {
    
    
                  sh "${
    
    mvnCmd} sonar:sonar -Dsonar.host.url=http://sonarqube:9000 -DskipTests=true"
                }
              }
            }
            stage('Archive App') {
    
    
              steps {
    
    
                sh "${
    
    mvnCmd} deploy -DskipTests=true -P nexus3"
              }
            }
            stage('Create Image Builder') {
    
    
              when {
    
    
                expression {
    
    
                  openshift.withCluster() {
    
    
                    openshift.withProject(env.DEV_PROJECT) {
    
    
                      return !openshift.selector("bc", "tasks").exists();
                    }
                  }
                }
              }
              steps {
    
    
                script {
    
    
                  openshift.withCluster() {
    
    
                    openshift.withProject(env.DEV_PROJECT) {
    
    
                      openshift.newBuild("--name=tasks", "--image-stream=jboss-eap70-openshift:1.5", "--binary=true")
                    }
                  }
                }
              }
            }
            stage('Build Image') {
    
    
              steps {
    
    
                sh "rm -rf oc-build && mkdir -p oc-build/deployments"
                sh "cp target/openshift-tasks.war oc-build/deployments/ROOT.war"

                script {
    
    
                  openshift.withCluster() {
    
    
                    openshift.withProject(env.DEV_PROJECT) {
    
    
                      openshift.selector("bc", "tasks").startBuild("--from-dir=oc-build", "--wait=true")
                    }
                  }
                }
              }
            }
            stage('Create DEV') {
    
    
              when {
    
    
                expression {
    
    
                  openshift.withCluster() {
    
    
                    openshift.withProject(env.DEV_PROJECT) {
    
    
                      return !openshift.selector('dc', 'tasks').exists()
                    }
                  }
                }
              }
              steps {
    
    
                script {
    
    
                  openshift.withCluster() {
    
    
                    openshift.withProject(env.DEV_PROJECT) {
    
    
                      def app = openshift.newApp("tasks:latest")
                      app.narrow("svc").expose();

                      def dc = openshift.selector("dc", "tasks")
                      while (dc.object().spec.replicas != dc.object().status.availableReplicas) {
    
    
                          sleep 10
                      }
                      openshift.set("triggers", "dc/tasks", "--manual")
                    }
                  }
                }
              }
            }
            stage('Deploy DEV') {
    
    
              steps {
    
    
                script {
    
    
                  openshift.withCluster() {
    
    
                    openshift.withProject(env.DEV_PROJECT) {
    
    
                      openshift.selector("dc", "tasks").rollout().latest();
                    }
                  }
                }
              }
            }
            stage('Promote to STAGE?') {
    
    
              steps {
    
    
                timeout(time:15, unit:'MINUTES') {
    
    
                    input message: "Promote to STAGE?", ok: "Promote"
                }

                script {
    
    
                  openshift.withCluster() {
    
    
                    openshift.tag("${
    
    env.DEV_PROJECT}/tasks:latest", "${
    
    env.STAGE_PROJECT}/tasks:${
    
    version}")
                  }
                }
              }
            }
            stage('Deploy STAGE') {
    
    
              steps {
    
    
                script {
    
    
                  openshift.withCluster() {
    
    
                    openshift.withProject(env.STAGE_PROJECT) {
    
    
                      if (openshift.selector('dc', 'tasks').exists()) {
    
    
                        openshift.selector('dc', 'tasks').delete()
                        openshift.selector('svc', 'tasks').delete()
                        openshift.selector('route', 'tasks').delete()
                      }

                      openshift.newApp("tasks:${
    
    version}").narrow("svc").expose()
                    }
                  }
                }
              }
            }
            stage('Clair Container Vulnerability Scan') {
    
    
              agent {
    
    
                label 'skopeo'
              }
              steps {
    
    
                script {
    
    
                  sh "oc login -u $oc_user -p $oc_pass --insecure-skip-tls-verify https://$ocp_api 2>&1"
                  sh 'skopeo copy --src-creds="$(oc whoami):$(oc whoami -t)"' + " --src-tls-verify=false --dest-creds=$quay_user:$quay_pass --dest-tls-verify=false docker://$ocp_registry/cicd-demo-dev/tasks:latest docker://$quay_server/$quay_user/tasks:stage"
                }
              }
            }
          }
        }
      env:
        - name: DEV_PROJECT
          value: cicd-demo-dev
        - name: STAGE_PROJECT
          value: cicd-demo-stage
        - name: ENABLE_QUAY
          value: 'false'
  postCommit: {
    
    }
  source:
    type: None
  triggers:
    - type: GitHub
      github:
        secret: 3QY1TYdk
    - type: Generic
      generic:
        secret: 3QY1TYdk
  runPolicy: Serial

猜你喜欢

转载自blog.csdn.net/weixin_43902588/article/details/119963225