CI/CD

CI/CD

啥是CI/CD

CI: continuous integration, 持續集成。就是頻繁地把開發的工做提交到主線代碼。主要是爲了解決集成問題。什麼是集成問題呢,白話說,就是從你本地的代碼pull下來的時間點開始,距離你提交時候越長,你提交時候遇到衝突的風險越大。由於別人也可能會修改。java

CD: continuous delivery, 持續交付。簡言之就是頻繁地通過UT、靜態代碼分析、build過程產出release。node

CD:continuous deployment, 持續部署。拿到持續交付的產出(release),自動化部署到環境,並通過自動化測試過程。git

實現舉例

最近項目基於Jenkins, Docker實現CI/CD,在此記錄一下。github

jenkins 安裝

wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war
java -jar jenkins.war --httpPort=8889 >./jenkins.log &

#初始化Jenkins時須要的密碼
cat ~/.jenkins/secrets/initialAdminPassword

#安裝推薦的plugin
#建立Admin

在Manage Jenkins->Global Tool Configuration->Add Maven 添加一個叫M3的Maven,自動安裝maven,下面pipeline腳本會用(可選,若是沒此步本身要先安裝好maven)web

jenkins任務的配置主要是經過頁面完成。docker

點擊New Item,輸入名字,選擇Pipeline,點OKapp

General裏配置一些項目描述信息webapp

Build Triggers設置編譯觸發。好比勾選Build periodically表示按期編譯。Schedule填寫H 5,10,15,20,23 * * *表示天天的5點、10點、15點、20點和23點都編譯一次。而選擇Poll SCM表示有提交才編譯。maven

Pipeline裏配置pipeline腳本。(這裏用我本身git的一個小項目)測試

node {
  def mvnHome
  stage('Preparation') {
    git 'https://github.com/qwsdcv/Stock.git'
    mvnHome = tool 'M3'
  }
  stage('Build') {
    sh "'${mvnHome}/bin/mvn' -f SpringStuff/pom.xml -Dmaven.test.failure.ignore clean package"
  }
  stage('Results') {
    //junit '**/target/surefire-reports/TEST-*.xml'
    //archive 'SpringStuff/target/*.jar'

    def date = sh (script: 'date +"%Y%m%d-%H%M%S"',returnStdout: true).trim()
    
    def RELEASEDIR = "~/release/${date}"
    
    def mkdir = { dir->
        sh "mkdir -p ${dir}"
    }
    mkdir(RELEASEDIR)

    sh "cp SpringStuff/target/*.war ${RELEASEDIR}"
  }
}

docker

咱們的Dockerfile
從一個公共的image jetty開始,把生成的war包拷貝進去

FROM jetty

COPY SpringStuff/target/*.war /var/lib/jetty/webapps

那上面的pipeline腳本就能夠改爲下面這樣了

node {
  def mvnHome
  stage('Preparation') {
    git 'https://github.com/qwsdcv/Stock.git'
    mvnHome = tool 'M3'
  }
  stage('Build') {
    sh "'${mvnHome}/bin/mvn' -f SpringStuff/pom.xml -Dmaven.test.failure.ignore clean package"
  }
  stage('Results') {
    //junit '**/target/surefire-reports/TEST-*.xml'
    //archive 'SpringStuff/target/*.jar'

    def date = sh (script: 'date +"%Y%m%d-%H%M%S"',returnStdout: true).trim()
    
    def RELEASEDIR = "~/release/${date}"
    
    def mkdir = { dir->
        sh "mkdir -p ${dir}"
    }
    mkdir(RELEASEDIR)

    sh "cp SpringStuff/target/*.war ${RELEASEDIR}"
    //這裏我能夠直接build 是由於我把Dockerfile上傳到github的根路徑下了
    sh "docker build -t jetty_stock_${date} ./"
    
  }
}

結合docker-registry搭建一個私有倉庫,每次build完成打個標籤推送到私有倉庫就OK啦。

後面我會寫一個用來申請容器環境的web服務。

另外附加這些指令解釋

#生成image
docker build -t jetty_stock ./
#運行容器, 把容器內部的8080端口映射到宿主機器的9000端口
docker run -d -p 9000:8080 jetty_stock
docker ps #列出正在運行的容器
docker ps -a #列出全部容器,包括停了的
docker stop XXXX #中止容器
docker rm XXXX #刪除容器(須要先中止再刪除)

docker images #列出全部鏡像
docker rmi XXX #刪除鏡像

docker rm `docker ps -a -q` #刪除全部容器
相關文章
相關標籤/搜索