Docker+Jenkins+Git實現spring-boot項目CI自動發佈流程

本文是結合目前工做實際場景中,實現利用容器來構建docker+jenkins+git+registry進行項目的CI自動發佈流程,從中也填過坑,很少。若有不實之處,歡迎指出,共同討論。java

  • 流程設計
    公司開發大腦×××同窗嘔心瀝血、劈里啪啦地寫了n堆代碼,提交到代碼倉庫後,到能訪問到他本人寫的壯碩成果,通常會經歷以下過程:
    Docker+Jenkins+Git實現spring-boot項目CI自動發佈流程git

  • 環境
    Jenkins安裝,準備一臺server,安裝略,百度一下。
    Docker安裝,準備一臺server,安裝略,百度一下。
    Git倉庫,準備一臺server,安裝略,百度一下。spring

  • Jenkins上配置
    1. 新建一Maven的Job項目。
      Docker+Jenkins+Git實現spring-boot項目CI自動發佈流程
  1. Jenkins配置-源碼
    Docker+Jenkins+Git實現spring-boot項目CI自動發佈流程docker

  2. Jenkins配置-構建觸發器
    Docker+Jenkins+Git實現spring-boot項目CI自動發佈流程shell

  3. Jenkins配置-構建環境
    Docker+Jenkins+Git實現spring-boot項目CI自動發佈流程
    構建前,從集中存放配置文件的GitLab中拉取最新配置文件,包含Dockerfile,後面開始構建會引用最新文件。數據庫

    cd /data/httpd/release/b2b-configuration;git pull
    sleep 3;
    yes | cp -rfp  /data/httpd/release/b2b-configuration/Spring-partner/QA/application.yml  /home/jenkins/.jenkins/workspace/b2b-partner-test/src/main/resources/
    yes | cp -rfp  /data/httpd/release/b2b-configuration/Spring-partner/QA/logback-spring.xml  /home/jenkins/.jenkins/workspace/b2b-partner-test/src/main/resources/
    yes | cp -rfp  /data/httpd/release/b2b-configuration/Spring-partner/QA/Dockerfile  /home/jenkins/.jenkins/workspace/b2b-partner-test/

    配置文件說明:
    Dockerfile:bash

    FROM registry.cn-hangzhou.aliyuncs.com/xmbaby-pre/ms-jdk8
    EXPOSE 8081
    MAINTAINER b2b-partner-test hhyuking@yeah.net
    ADD b2b-partner.jar /data/httpd/
    RUN mkdir -p /data/httpd/log/
    WORKDIR /data/httpd/
    ENTRYPOINT java -Xmx256m -Xss512k -jar b2b-partner.jar

    application.yml:項目基本信息配置項,如數據庫鏈接信息等。
    logback-spring.xml:定義了spring-boot項目log日誌信息,包含日誌級別(info、error)、日誌格式及在運行容器中log的存儲目錄等。app

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml" />
    <appender name="INFO_FILE"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <File>/data/logs/aa-b2b-partner_info.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/data/httpd/log/aa-b2b-partner_info-%d{yyyyMMdd}.log.%i
            </fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>0</maxHistory>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -
                %msg%n</Pattern>
        </layout>
    </appender>
    <appender name="ERROR_FILE"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <File>/data/logs/aa-b2b-partner_error.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/data/httpd/log/aa-b2b-partner_error-%d{yyyyMMdd}.log.%i
            </fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>0</maxHistory>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -
                %msg%n</Pattern>
        </layout>
    </appender>
    <root level="INFO">
        <appender-ref ref="ERROR_FILE" />
        <appender-ref ref="INFO_FILE" />
    </root>
    </configuration>
  4. Jenkins配置-構建和構建後操做
    Docker+Jenkins+Git實現spring-boot項目CI自動發佈流程
    先同步jar包和Dockerfile到Docker那臺server上,而後用expect交互命令將shell腳本發送到Docker那臺server上,進行docker容器的構建、啓動、push到阿里雲鏡像倉庫等操做。
    Jenkins這臺server的rsync腳本:bash /home/jenkins/docker-test/script/b2b-rsync.sh b2b-partner-test 後帶參數。
    rsync同步腳本:
    #!/bin/bash
    IP=10.10.10.10
    PASSWD=p@ssword1
    echo -e "開始同步jar包..."
    rsync -vzrtopg --numeric-ids --progress --password-file=/etc/rsyncd.password6 /home/jenkins/.jenkins/workspace/$1/target/b2b-partner.jar root@$IP::$1
    echo -e "開始同步Dockerfile..."
    rsync -vzrtopg --numeric-ids --progress --password-file=/etc/rsyncd.password6 /home/jenkins/.jenkins/workspace/$1/Dockerfile root@$IP::$1
    expect /home/jenkins/docker-test/script/image_b2b.exp $IP $PASSWD $1

    expect交互命令腳本:/home/jenkins/docker-test/script/image_b2b.expssh

    #!/usr/bin/expect -f
    set ipaddress [lindex $argv 0]
    set passwd [lindex $argv 1]
    set jobname [lindex $argv 2]
    spawn ssh xiaoyu@$ipaddress;
    expect "password:";
    send "$passwd\r";
    expect "#"
    send "sudo nohup /data/docker/layout-script/docker-qa.sh $jobname  >> /data/docker/logs/$jobname.log &\r"

    注意:執行上面expect腳本前,需將ssh的用戶,到對方server的visudo配置中加入:xiaoyu ALL=(ALL) NOPASSWD: ALL, 要否則用戶沒法ssh過去。maven

  • Docker配置
    查看同步到Docker的Dockerfile,maven構建好的jar包也同步到此目錄下。
root@docker-qa b2b-partner-test]# ll
總用量 61476
-rw-rw-r-- 1 1010 1010 62944090 Jul 26 19:46 b2b-partner.jar
-rw-rw-r-- 1 1010 1010      237 Jul 26 10:00 Dockerfile

關鍵在Docker server上執行的docker-qa.sh腳本

#!/bin/bash

JOBMS=$1
VERSION=latest
JOBREPO=/data/docker/$1
IMGREPO=xmbaby-test
IMGNAME=$1
DTIME=`date +%Y-%m-%d" "%H":"%M":"%S`
CONTAINER_NAME=b2b-partner-test-container

if [ ! -d $JOBREPO ];then
    mkdir -p $JOBREPO
    scp jenkins@10.10.10.10:~/.jenkins/workspace/$1/target/b2b-partner.jar $JOBREPO
    scp jenkins@10.10.10.10:~/.jenkins/workspace/$1/Dockerfile $JOBREPO
    echo -e "\n[$JOBMS]" >> /etc/rsyncd.conf
    echo "path=/data/docker/$JOBMS/" >> /etc/rsyncd.conf
    echo "comment = update
  ignore errors
  read only = no
  list = no
  hosts allow = 10.10.10.10/255.255.255.0
  auth users = root
  uid = root
  gid = root
  secrets file = /etc/rsyncd.secrets" >> /etc/rsyncd.conf
else
    echo -e "\n時間$DTIME,開始構建docker鏡像"
fi

#CID=$(docker ps | grep "$CONTAINER_NAME" | awk '{print $1}')
#IID=$(docker images | grep "$CONTAINER_NAME" | awk '{print $3}')

cd $JOBREPO
echo -e "構建docker鏡像前,刪除以前的容器、鏡像."
IMAGE_ID=`docker images |grep "b2b-partner-img/$JOBMS" |awk '{print $3}'`
echo "Image鏡像ID:$IMAGE_ID"
#CONTAINER_ID=`docker images |grep "b2b-partner-img/$JOBMS" |awk '{print $1}'`
CONTAINER_ID=`docker ps |grep $CONTAINER_NAME |awk '{print $NF}'`
echo "Container容器:$CONTAINER_ID"

docker rm -f $CONTAINER_ID | true
echo -e "$CONTAINER_ID 當前老容器刪除成功!"
docker rmi -f $IMAGE_ID | true
echo -e "$IMAGE_ID 當前老鏡像刪除成功!"

echo -e "時間$DTIME,正式開始構建docker鏡像"

docker build -t b2b-partner-img/$JOBMS .

if [ $? -ne 0 ];then
    echo -e "時間$DTIME,$JOBMS 鏡像構建失敗,請檢查dockerfile !"
    exit
else
    echo -e "時間$DTIME,開始運行Docker容器."
    #docker run --name $CONTAINER_NAME -v $JOBREPO:$JOBREPO -d -p 8081:8081 b2b-partner-img/$JOBMS
    docker run --name $CONTAINER_NAME -d -p 8081:8081 b2b-partner-img/$JOBMS
    sleep 5
    echo -e "時間$DTIME,$CONTAINER_NAME容器建立完成.開始推送到阿里鏡像倉庫中..."
    IMAGEID_NEW=`docker images |grep "b2b-partner-img/$JOBMS" |awk '{print $3}'`
    echo "New鏡像ID:$IMAGEID_NEW"
    CONTAINERID_NEW=`docker images |grep "b2b-partner-img/$JOBMS" |awk '{print $1}'`
    echo "New Container容器:$CONTAINERID_NEW"
    docker login --username=xiaoming --password=passwd registry.cn-hangzhou.aliyuncs.com
    docker tag $IMAGEID_NEW registry.cn-hangzhou.aliyuncs.com/$IMGREPO/$IMGNAME:$VERSION
    docker push registry.cn-hangzhou.aliyuncs.com/$IMGREPO/$IMGNAME:$VERSION
fi
  • Jenkins上構建
    構建
    Docker+Jenkins+Git實現spring-boot項目CI自動發佈流程
    Jenkins控制檯查看構建log
    Docker+Jenkins+Git實現spring-boot項目CI自動發佈流程

  • 測試訪問
    要使用域名測試訪問,因爲Docker QA上80端口已被其餘應用佔用,故在一臺Nginx服務上設置代理到容器的8081端口上,經過一接口進行域名訪問,以下圖所示,說明能通:
    Docker+Jenkins+Git實現spring-boot項目CI自動發佈流程
相關文章
相關標籤/搜索