天天看點

cicd 01--建構通用的CI流程1 介紹2 CI建構過程3 注意事項4 說明

cicd 01--建構通用的CI流程

  • 1 介紹
  • 2 CI建構過程
    • 2.1 參數配置說明
    • 2.2 pipeline 腳本
    • 2.3 測試流程
  • 3 注意事項
  • 4 說明

1 介紹

筆者在 docker筆記3–配置jenkins 和 k8s筆記7.3–基于gitlab、jenkins、helm、k8s的CI/CD 中介紹了jenkins的安裝和基于helm 的k8s 流程。本文基于上述基礎繼續分享一個建構和釋出鏡像的通用jenkins流程,以便于為企業中所有的服務實作鏡像釋出。

2 CI建構過程

本案例中涉及多種agent,比如普通的slave節點可以通路gitlab倉庫,aliyun-build可以用來通路上傳鏡像,但是不能通路gitlab;是以需要通過多個節點協調操作,在slave節點上拉取鏡像,然後拷貝到aliyun-build中,在build機器上build鏡像并上傳到倉庫,最後在slave機器上給repo打一個tag。

本案例中為了實作一個通用的build流程,并沒有為不同的鏡像配置不同build環境,而是為其封裝一個通用的build_docker.sh 腳本,使用者按照需要改動即可。

若遇見不同的環境,例如A 鏡像需要 java9、B鏡像需要 java11 的打包環境,那麼可以将其某個機器上build好生成可執行檔案,然後在 build_docker.sh 中下載下傳所需檔案後再打包;也可以封裝一個專用的build code的鏡像,先運作該鏡像build 可執行檔案,然後再繼續生成的檔案build 處生産環境所需的鏡像。

2.1 參數配置說明

  1. 拉取指定gitlab repo 代碼

    對應參數:gitlab_repo (sre設定為下拉選項目)

  2. 切換到指定的分支

    對應參數:branch_name (使用者自填)

  3. 确定鏡像版本号, 格式最好為yyyymmddvx(x為具體數字,例如 20210814v1)

    對應參數:image_version (使用者自填)

  4. 确定dockerhub倉庫字尾, 格式為命名空間/倉庫名稱(例如 yourNamespace/xg_nginx)

    對應參數:dockerhub_repo (使用者自填)

  5. 通過該分支根目錄下的 build_docker.sh 和 Dockerfile 來建構鏡像,并将鏡像推送到對應的dockerhub中

build_docker.sh 案例

以下為build_docker.sh 案例,每個分支都要參考該方法寫一個 build_docker.sh, 并確定執行 bash build_docker.sh dockerhub_repo image_version 後能正常推送到docker倉庫

#!/bin/bash

docker_image_name=xg_nginx # 需要将此處的xg_nginx 替換為dockerhub_repo 中的字尾

function usage() {
cat <<_EOF
usage:
  bash build_docker.sh -h|--help|dockerhub_repo image_version
  for example, bash build_docker.sh yourNamespace/xg_nginx 20210816v1
_EOF
}

function build_docker() {
    docker build -t $docker_image_name:$2 .
    if [ $? -eq 0 ]; then
      echo "build_docker $docker_image_name:$2, success"
    else
      echo "build_docker $docker_image_name:$2, failed"
      exit 1
    fi
    docker tag $docker_image_name:$2 registry-vpc.cn-shanghai.aliyuncs.com/$1:$2
    if [ $? -eq 0 ]; then
      echo "tag $docker_image_name:$2, success"
    else
      echo "tag $docker_image_name:$2, failed"
      exit 1
    fi
    docker push registry-vpc.cn-shanghai.aliyuncs.com/$1:$2
    if [ $? -eq 0 ]; then
      echo "push registry-vpc.cn-shanghai.aliyuncs.com/$1:$2, success"
    else
      echo "push registry-vpc.cn-shanghai.aliyuncs.com/$1:$2, failed"
      exit 1
    fi
    docker rmi $docker_image_name:$2
    docker rmi registry-vpc.cn-shanghai.aliyuncs.com/$1:$2
}

case "$1" in
    -h)
      usage
      ;;
    --help)
      usage
      ;;
    *)
      build_docker $1 $2
      ;;
esac
           

2.2 pipeline 腳本

gitlab_repo = "${params.gitlab_repo}"
def split = gitlab_repo.split("/")
def repo_name = split[1]
branch_name = "${params.branch_name}"
image_version = "${params.image_version}"
dockerhub_repo = "${params.dockerhub_repo}"
repo_url = "[email protected]:${gitlab_repo}.git"

println("gitlab_repogitlab_repo branch=${gitlab_repo} ${branch_name}")
println("repo_name=${repo_name}, image_version=${image_version}")
println("dockerhub_repo=${dockerhub_repo}")

default_description = "${gitlab_repo} ${branch_name}:${image_version}"
currentBuild.description = "${default_description}"

pipeline {
    agent any
    
    environment {
        repo_name1 = "${repo_name}"
    }
    
    stages {
        stage('Clean workspace') {
        agent { 
            node { 
                label 'aliyun-build' 
            } 
        }
         steps {
            sh """
                rm -rf /nas/jenkins/sre_workspace/build_docker_sre/\${repo_name1}_\${branch_name} || true
            """
        }
      }

      stage("Clone Repo"){
          agent { 
             node { 
                 label 'slave' 
             } 
         }
         steps {
            deleteDir()
            dir("${repo_name1}_${branch_name}"){
                    git(
                        url: "${repo_url}",
                        credentialsId: '73d3xxxx-xxxx-xxxx-xxxx-xxxxxxxx9274',
                        branch: "${branch_name}"
                    )
            }
         }
      }

      stage('Scp to aliyun-build') {
         agent { 
             node { 
                 label 'slave' 
             } 
         }
         steps {
            sh """
                pwd
                scp -r \${repo_name1}_\${branch_name} aliyun-build:/nas/jenkins/sre_workspace/build_docker_sre/
                if [ \$? -ne 0 ]
                then
                    echo "Found some error when copy the repo"
                fi
            """
         }
      }

      stage('Build docker images') {
         agent { 
             node { 
                 label 'aliyun-build' 
             } 
         }
         steps {
             sh """
                cd /nas/jenkins/sre_workspace/build_docker_sre/\${repo_name1}_\${branch_name}/
                if [ ! -f Dockerfile ]
                then
                    echo "No available dockerfile in workspace"
                fi
                if [ ! -f build_docker.sh ]
                then
                    echo "No available build_docker.sh in workspace"
                fi
                bash build_docker.sh \${dockerhub_repo} \${image_version}
                pwd 
                ls
            """
        }
      }

      stage('Set tag') {
         agent { 
             node { 
                 label 'slave' 
             } 
         }
         steps {
             dir("${repo_name1}_${branch_name}"){
                sh """
                    git tag -m "Build docker image ${image_version} for ${branch_name}/${image_version}" \${branch_name}/\${image_version}
                    git describe
                    git push origin \${branch_name}/\${image_version}
                """
             }
         }
      }
    }
    post {
        always {
            echo 'I have finished'
        }
        success {
            echo "build ${gitlab_repo} ${branch_name}:${image_version}, succeed!"
            sh """
            curl -X POST -H "Content-Type: application/json" -d '{"msg_type":"text","content":{"text":"build_docker_sre notify: ${gitlab_repo} ${branch_name}:${image_version}, succeed!"}}' https://open.feishu.cn/open-apis/bot/v2/hook/6caa4463-xxxx-xxxx-xxxx-89ac0e9e39c8
            """
        }
        failure {
            echo "build ${gitlab_repo} ${branch_name}:${image_version}, failed!"
            sh """
            curl -X POST -H "Content-Type: application/json" -d '{"msg_type":"text","content":{"text":"build_docker_sre notify: ${gitlab_repo} ${branch_name}:${image_version}, failed!"}}' https://open.feishu.cn/open-apis/bot/v2/hook/6caa4463-xxxx-xxxx-xxxx-89ac0e9e39c8
            """
        }
    }
}
           

2.3 測試流程

jenkins 執行參數如下:

cicd 01--建構通用的CI流程1 介紹2 CI建構過程3 注意事項4 說明

執行結果如下:

cicd 01--建構通用的CI流程1 介紹2 CI建構過程3 注意事項4 說明

3 注意事項

  1. 涉及多個不同節點的時候需要配置不同節點的通路權限,也要配置 jenkins 拉取 gitlab 的權限。

4 說明

軟體環境:

jenkins 版本:2.299

參考文檔:

jenkins 官方文檔

繼續閱讀