gitlab+docker+jenkins基於dockerfile持續集成

篇幅使用的組件docker,dockerfile,docker-compose,registry,jenkins,gitlab,釘釘通知,篇幅有限,有些未詳細寫到的東西可能須要你們自行摸索。html

來介紹下這套自動發佈的工做流程及搭建步驟,此文檔只爲記錄及展現,爲了篇幅不過長,docker,docker-compose,不作贅述,其他組件均使用docker運行,linux

初始環境:nginx

  IP1 : 192.168.18.221,jenkins+gitlab+docker-registrygit

  IP2:192.168.18.222,webweb

  關閉selinuxdocker

  關閉防火牆json

一,安裝docker(兩臺機器都裝)vim

# step 1: 安裝必要的一些系統工具
yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加軟件源信息
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 3: 更新並安裝Docker-CE
yum makecache fast
yum -y install docker-ce
# Step 4: 開啓Docker服務
systemctl start docker      
#這裏仍是添加下鏡像加速
vim /etc/docker/daemon.json

  {
  "registry-mirrors": ["https://8****lj0.mirror.aliyuncs.com"]
  }centos

二,安裝gtitlabapi

# 不加 tag 則默認爲最新版本 latest
docker pull gitlab/gitlab-ce
#一般會將 GitLab 的配置 (etc) 、 日誌 (log) 、數據 (data) 放到容器以外, 便於往後升級, 所以請先準備這三個目錄。
mkdir -p /srv/gitlab/config
mkdir -p /srv/gitlab/logs 
mkdir -p /srv/gitlab/data
#啓動運行gitlab
docker run --detach \
  --hostname gitlab.example.com \
  --publish 8443:443 --publish 8880:80 --publish 8222:22 \
  --name gitlab \
  --restart always \
  --volume /srv/gitlab/config:/etc/gitlab \
  --volume /srv/gitlab/logs:/var/log/gitlab \
  --volume /srv/gitlab/data:/var/opt/gitlab \
 --add-host code.shiji.com:192.168.18.221 \ --privileged=true \ gitlab/gitlab-ce:latest
#這裏能成功訪問後就不作額外的配置了,注意修改下配置文件裏面的默認訪問地址
#配置下nginx代理後的訪問地址 http://code.shiji.com (這裏域名是使用的本地解析,當須要拉取代碼的時候必需要能解析這個域名,)

三,安裝jenkins(這裏放上官方文檔  https://jenkins.io/zh/doc/pipeline/tour/deployment/)

#拉取鏡像(這裏建議你們使用官方推介的鏡像)
docker pull  jenkinsci/blueocean:lts
#建立掛載目錄並修改權限
mkdir /home/jenkins 
#建立並運行 docker run \ -u root \ -d \ -p 8080:8080 \ -p 50000:50000 \ -v /home/jenkins:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ #若是須要在容器中運行docker命令,這條必須加上
--add-host code.shiji.com:192.168.18.221 \ #這裏我給jenkins添加了一條本地解析
 --restart always \
--name jenkins \ jenkinsci/blueocean:latest
#在log中找到初始密碼
docker logs jenkins
#修改密碼後jenkins安裝部分完成
#訪問地址,http://192.168.18.221:8080
#備註,安裝完成記得安裝插件,這裏用docker構建,須要安裝 CloudBees Docker Build and Publish

四,搭建registary私倉(須要把把代碼用dockerfile構建後上傳到私倉庫,而後web服務器在拉下來重構,若是但願便捷操做能夠使用雲上的私人倉庫)

#拉取鏡像
docker pull registry
#建立registry鏡像存儲目錄
mkdir -p /data/registry
#建立啓動registry
docker run -d -p 5000:5000 --restart=always --name registry -v /data/registry:/var/lib/registry registry:latest
#修改web服務的docker配置文件daemon.json,添加http
vim /etc/docker/daemon.json
{
 "insecure-registries": ["http://192.168.18.221:5000"],
  "registry-mirrors": ["https://8****lj0.mirror.aliyuncs.com"]
}
#構建完成後registry地址 http://192.168.18.221:5000

五,配置持續集成,這裏再次梳理下工做流程,開發人員提交代碼  --> 觸發gitlab鉤子   --jenkins拉取代碼構建  -->構建成功,推送鏡像至私倉  -->web服務器拉取私倉鏡像建立容器  -->通知用戶;固然,失敗的時候也會通知用戶。

  1,配置pipeline,

    咱們在jenkins裏建立一個名爲多分支的流水線,而且配置好代碼倉,而且讓他每次自動檢出分支,以及檢出先後都清理工做目錄,其餘選項使用默認便可,Build Configuration選擇jenkinsfile;

    

     注意:此處配置完成後,scan流水線時會自動從gtilab裏識別jenkinsfile文件,

  2,配置jenkinsfile文件,語法參考  https://jenkins.io/zh/doc/book/pipeline/,這裏直接放出這邊配置好的文件

pipeline {
  agent any
  parameters {
	 string(name:'BRANCH_FOR_BODY',defaultValue:"${BRANCH_NAME}",description:'parameters used by ding talk')     #此處的兩個參數是爲了後面釘釘通知的時候使用,這裏後面再說
	 string(name:'BUILD_URL_FOR_BODY',defaultValue:"${BUILD_URL}",description:'build uri for body')
  }
  stages {
    stage('Deploy-Production') {
      when {
        branch 'master'
      }
      steps {
        sh '''
         docker build -t ${DOCKER_IMAGE_NAME}:latest -f Dockerfile .                                      
        '''
        sh 'docker push ${DOCKER_IMAGE_NAME}:latest'      #這裏選擇每次都推送爲lastest標籤
        sh 'docker rmi ${DOCKER_IMAGE_NAME}:latest'    #同時刪除本地構建打好標籤的鏡像
      }
      post {                       #根據執行標記來決定處理內容
        success {
	      sh 'sh notice.sh "test生產環境鏡像推送成功通知" "nginx-test" "推送鏡像成功"  ${BRANCH_NAME} ${BUILD_URL}'     #此處的釘釘推送腳本最後會放出
        }
        failure{
	      sh 'sh notice.sh "test生產環境鏡像推送失敗通知" "nginx-test" "推送鏡像失敗"  ${BRANCH_NAME} ${BUILD_URL}'
        }
      }
    }
  }
  environment {
    DOCKER_DEPLOY_URI = 'http://nginx.test.shiji.com'                    #這裏只是爲了我的使用,此篇幅未用到
    DOCKER_IMAGE_NAME = '192.168.18.221:5000/test/nginx-test'            #鏡像名稱
    DOCKER_SERVICE_NAME = 'TestService'                     #項目名稱
  }
}

  3,在上面的步驟中咱們在構建的時候使用了dockerfile,這裏使用個簡單的nginx做爲測試

FROM nginx
RUN echo 'This is the first version' > /usr/share/nginx/html/index.html

  4,接下來咱們把dockerfile也上傳至代碼倉,這時構建固然是失敗的,由於後續的釘釘通知腳本尚未上傳,

  

  查看輸出,能夠看到鏡像已經上傳成功

  

   5,至此,持續構建算初步完成,放上釘釘推送信息的腳本,記得把tocken換成本身的,(注意新版本的釘釘機器人要加簽了)

gitAuthor=''
gitAuthor=`git show --stat | awk '$0~/Author/{print $2}'`
response=`curl -X POST -H 'Content-Type:application/json; charset=utf-8' \
-d '{"msgtype":"markdown",\
"markdown":{"title":"'$1'",\
"text":"## '$1'\n\n**項目名稱**:'$2'\n\n**提交人**:'$gitAuthor'\n\n**狀態**:'$3'\n\n**分支**:'$4'\\n\\n有關更多構建的過程、錯誤信息、單元測試覆蓋率報告請參照 [構建日誌]('$5')"\
}}' https://oapi.dingtalk.com/robot/send?access_token=d7f17229b054200xxxxxxxxxxxxxxxxxxxx3204e4dee`
echo $response

  6,gitlab自動推送,自動構建

    1,在jenkins安裝gitlab插件,注意這裏並非哪一個gitlabhook的插件

    

      &插件安裝成功後咱們修改jenkinsfile增長tigger,關於tigger的語法,官方文檔和往上都給的不太詳細,這裏若是想過濾分支等操做參考下這兩篇文章

      https://blog.51cto.com/ygqygq2/2461766

      http://www.eryajf.net/3298.html

      &放上修改完成的jenkinsfile   

pipeline {
  agent any
  parameters {
	 string(name:'BRANCH_FOR_BODY',defaultValue:"${BRANCH_NAME}",description:'parameters used by ding talk') 
	 string(name:'BUILD_URL_FOR_BODY',defaultValue:"${BUILD_URL}",description:'build uri for body')
  }
  triggers{
	gitlab( triggerOnPush: true,
			triggerOnMergeRequest: true,
            branchFilterType: "NameBasedFilter",
			includeBranchesSpec: "master,dev",
			secretToken: "028d848ab64f"
		)
  }
  stages {
    stage('Deploy-Production') {
      when {
        branch 'master'
      }
      steps {
        sh '''
         docker build -t ${DOCKER_IMAGE_NAME}:latest -f Dockerfile .                                   
        '''
        sh 'docker push ${DOCKER_IMAGE_NAME}:latest'
        sh 'docker rmi ${DOCKER_IMAGE_NAME}:latest'
      }
      post {  
        success {
	      sh 'sh notice.sh "test生產環境鏡像推送成功通知" "nginx-test" "推送鏡像成功"  ${BRANCH_NAME} ${BUILD_URL}'
        }
        failure{
	      sh 'sh notice.sh "test生產環境鏡像推送失敗通知" "nginx-test" "推送鏡像失敗"  ${BRANCH_NAME} ${BUILD_URL}'
        }
      }
    }
  }
  environment {
    DOCKER_DEPLOY_URI = 'http://nginx.test.shiji.com'
    DOCKER_IMAGE_NAME = '192.168.18.221:5000/test/nginx-test'
    DOCKER_SERVICE_NAME = 'TestService'
  }
}

     2,jenkins設置裏添加倉庫(這裏的tocken須要去gitlab裏生成)

    

 

     3,gitlab項目裏建立webhook

      

    4,最後提交一次測試效果(釘釘通知)

    

 

7,到這裏爲止算是初步完成了自動構建,接下來要說說自動發佈了,咱們已經把鏡像推送到了私倉,接下來只須要在應用服務器上執行命令構建就行,這裏說說咱們是怎麼作的。

  應用服務器發佈腳本,腳本使用compose發佈,腳本執行也是放在Jenkins file裏,(這裏配置了兩條是爲了後續的pipeline多分支),腳本接受兩個參數,一個名稱及標籤,標籤是爲了多分支的pipeline準備的,後續再說。

       腳本:

tag="$2"
# test
if [ $1 == "test" ]
then

    cd /docker/compose/test
    pwd
    docker pull 192.168.18.221:5000/test/nginx-test:$tag

    docker-compose up -d test
    echo "success"

elif [ $1 == "test1" ]
then

    cd /docker/compose/test1
    docker pull 192.168.18.221:5000/test/nginx-test:$tag

    docker-compose up -d test2
    echo "success"

else 
    echo "no equal service"
fi

  jenkinsfile:(寫在setp階段執行,這裏咱們使用的是接口的方式,須要在應用服務器上寫個接口去執行上面的腳本,固然你也能夠直接遠程執行腳本,過程就不在贅述)

steps {
        sh '''
         docker build -t ${DOCKER_IMAGE_NAME}:latest -f Dockerfile .                                   
        '''
        sh 'docker push ${DOCKER_IMAGE_NAME}:latest'
        sh 'docker rmi ${DOCKER_IMAGE_NAME}:latest'
     sh 'curl ${DOCKER_DEPLOY_URI}/staging?service=${DOCKER_SERVICE_NAME}' #請求接口去執行上面的腳本發佈,接口怎麼寫的這裏我就不放出來了,你們能夠省略這一步直接遠程執行腳本(要配置ssh互信)
} 

最後:多分支pipeline

  上面內容設置了一些變量,就是爲此準備的,在這裏咱們能夠對應環境分紅多個流水線分支,主要仍是修改jenkinsfile:

pipeline { agent any parameters { string(name:'BRANCH_FOR_BODY',defaultValue:"${BRANCH_NAME}",description:'parameters used by ding talk') string(name:'BUILD_URL_FOR_BODY',defaultValue:"${BUILD_URL}",description:'build uri for body') } triggers{ gitlab( triggerOnPush: true, triggerOnMergeRequest: true, branchFilterType: "NameBasedFilter", includeBranchesSpec: "master,dev", secretToken: "028d848ab64f" ) } stages { stage('Deploy-Production') { when { branch 'master' } steps { sh '''          docker build -t ${DOCKER_IMAGE_NAME}:latest -f Dockerfile . '''         sh 'docker push ${DOCKER_IMAGE_NAME}:latest' sh 'docker rmi ${DOCKER_IMAGE_NAME}:latest' sh 'curl ${DOCKER_DEPLOY_URI}/staging?service=${DOCKER_SERVICE_NAME}&tags=latest' } post { success { sh 'sh notice.sh "test生產環境鏡像推送成功通知" "nginx-test" "推送鏡像成功" ${BRANCH_NAME} ${BUILD_URL}' } failure{ sh 'sh notice.sh "test生產環境鏡像推送失敗通知" "nginx-test" "推送鏡像失敗" ${BRANCH_NAME} ${BUILD_URL}' } } } stage('Deploy-Dev') { when { branch 'dev' } steps { sh '''         docker build -t ${DOCKER_IMAGE_NAME}:dev -f Dockerfile . '''         sh 'docker push ${DOCKER_IMAGE_NAME}:dev' sh 'docker rmi ${DOCKER_IMAGE_NAME}:dev' sh 'curl ${DOCKER_DEPLOY_URI}/dev?service=${DOCKER_SERVICE_NAME}&tags=dev' } post { success { sh 'sh notice.sh "test測試環境部署成功通知" "nginx-test" "成功" ${BRANCH_NAME} ${BUILD_URL}' } failure{ sh 'sh notice.sh "test測試環境部署失敗通知" "nginx-test" "失敗" ${BRANCH_NAME} ${BUILD_URL}' } } } } environment { DOCKER_DEPLOY_URI = 'http://dockerup.test.shiji.com' DOCKER_IMAGE_NAME = '192.168.18.221:5000/test/nginx-test' DOCKER_SERVICE_NAME = 'TestService' } }

 

  最後效果

    jenkins:

  

 

  釘釘通知:(這裏在實際的生產環境中,並無持續部署,因此通知是有區別的)

   

 

寫在最後:這篇是使用dockerfile的持續集成,固然還有其餘方式,上面文中的鏈接做了更詳細的講解,各位看官若是能看到最後,歡迎留言指出文中不足的地方。

相關文章
相關標籤/搜索