使用Docker+Jenkins實現Go語言項目的持續集成

這篇文章將介紹如何使用Docker+Jenkins實現Go語言項目的持續集成。git

首先講一下大體的實現思路:golang

推送代碼至Git服務器 => 觸發Jenkins服務器配置的Git Web Hooks => 從Git服務器中pull或clone代碼 => 將代碼編譯成二進制可執行文件 => 構建docker鏡像 => 上傳docker鏡像至鏡像倉庫 => 從Jenkins服務器進入遠程應用服務器 => 從docker鏡像倉庫中拉取鏡像 => 中止並刪除該項目正在運行的docker容器 => 使用該新鏡像構建並啓動docker容器 => 刪除其餘舊版本鏡像 => 完成web

而後講一下實踐過程當中用到的一些技術點:docker

  • Dockershell

    使用Docker的主要緣由主要有,應用移植方便,而且可有效解決同一應用在不一樣服務器上部署帶來的環境問題影響。json

  • Docker Composevim

    docker-compose也是由Docker提供的一個命令行工具,這裏主要用於簡化Jenkins服務器上對容器的操做,僅此而已,可直接使用shell腳本代替。瀏覽器

  • Jenkinsbash

    Jenkins是一個自動化服務器,也能夠做爲簡單的CI/CD服務器。服務器

  • Git

    Git想必你們都不會陌生,這裏一樣使用它做爲項目的代碼管理倉庫,而且利用它的Web Hooks,做爲Jenkins任務構建的觸發器。

  • 鏡像倉庫

    這裏選擇阿里雲提供的容器服務做爲咱們的鏡像倉庫,可自行選擇本身合適的鏡像倉庫。

在本文的最後,列出了實踐過程當中可能會出現的問題,而且提供了實踐使用的Go項目代碼倉庫。

安裝 Jenkins

啓動 Jenkins 容器

  1. 拉取 Jenkins 鏡像

    docker pull jenkins/jenkins:latest
    複製代碼
  2. 編寫 docker-compose.yml 文件

    version: "2"
    services:
    	jks:
    		image: jenkins/jenkins:latest
    		ports:
    			- 8080:8080
    			- 50000:50000
    		volumes:
    			- /data/jenkins:/var/jenkins_home
    			- /var/run/docker.sock:/var/run/docker.sock
    			- /bin/docker:/bin/docker
    		container_name: jks
    		user: root
    複製代碼
  3. 建立用於掛載的 /data/jenkins 文件夾, 並修改該文件夾的擁有者爲 ID=1000 的用戶

    mkdir -p /data/jenkins
    chown -R 1000:1000 /data/jenkins
    複製代碼
  4. 經過 docker-compose 啓動 jenkins 容器

    docker-compose -f /data/compose/docker-compose.yml up -d jks
    複製代碼

安裝 Jenkins 插件

  1. 在瀏覽器輸入 http://IP:8080 進入 Jenkins 管理頁面

  2. 經過命令 cat /data/jenkins/secrets/initialAdminPassword 獲取初始密碼,對 Jenkins 進行解鎖,解鎖後先跳過插件安裝(無需擔憂漏裝推薦的插件,在後續安裝插件過程當中,會自動安裝解鎖後推薦的全部插件)

  3. (可選)修改配置文件,並重啓 Jenkins 容器,實現插件安裝加速

    # 編輯jenkins配置文件
    vim /data/jenkins/updates/default.json
     # 執行ex命令, 替換全部插件下載URL
    :1,$s/http:\/\/updates.jenkins-ci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g
     # 執行ex命令, 替換鏈接測試URL
    :1,$s/http:\/\/www.google.com/https:\/\/www.baidu.com/g
     # 重啓jenkins容器
    docker-compose -f /data/compose/docker-compose.yml restart jks
    複製代碼
  4. 進入Jenkins -> Plugin Manager頁面安裝如下插件

    • Localization: Chinese (Simplified)
    • Publish Over SSH
    • Gitee
    • Go

配置 Jenkins

全局工具配置

進入Jenkins -> 系統管理 -> 全局工具配置頁面,對GitGo進行相關配置

Gitee 配置

在已安裝 Gitee 插件的前提下,進入Jenkins -> 系統管理 -> 系統配置,找到Gitee 配置,對其進行配置,配置後內容大體以下:

配置 Publish over SSH

在已安裝Publish over SSH 插件的前提下,進入Jenkins -> 系統管理 -> 系統配置,找到Publish over SSH配置,以下圖所示:

Passphrase:生成密鑰時使用的加密口令,爲空則表示無

Path to key:生成的私鑰位置,與Key選項只需填其中一個

Key:生成的私鑰內容,與Path to key選項只需填其中一個

Name:遠程服務器備註名(自定義)

Hostname:遠程服務器地址

Username:遠程服務器用戶名

Remote Directory:進入遠程服務器後所在的位置

主要有兩種配置方式,第一種是直接使用遠程服務器的帳號和密碼,另一種則是經過密鑰的方式。

  • 帳號密碼方式

    使用帳號密碼方式無需配置公私鑰相關的選項,直接對SSH Server內容進行配置,並點擊高級按鈕,勾選Use password authentication, or use a different key選項,並填寫遠程服務器用戶對應的密碼Passphrase / Password,完成後點擊下方的Test Configuration按鈕進行鏈接測試便可。

  • 密鑰方式

    1. 進入 Jenkins 容器

      docker exec -it jks /bin/bash
      複製代碼
    2. 生成密鑰

      ssh-keygen -t rsa
      複製代碼
    3. 將公鑰複製到遠程服務器

      ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.56.101
      複製代碼
    4. 配置Path to key 選項值爲/root/.ssh/id_rsa

    5. 配置SSH Server

    6. 鏈接測試

構建任務

  1. 點擊Jenkins -> 新建任務,建立一個 Jenkins 任務

  2. General

    填寫項目的Gitee 連接以及勾選丟棄舊的構建

  3. 源碼管理

    選擇Git選項,填寫Repositories信息,並建立Gitee 帳號密碼憑據

  4. 構建觸發器

    勾選Gitee webhook 觸發構建,根據需求選擇容許觸發構建的分支,並在下方的Gitee WebHook 密碼選項右邊,點擊生成按鈕,將該觸發器的WebHook URLWebHook 密碼填寫至該項目的Gitee WebHooks管理中。

  5. 構建環境

    在已安裝Go 插件的前提下,勾選Set up Go programming language tools選項框,並在其下方填寫項目使用到的 Go 版本號便可,以下圖:

  6. 構建

    構建過程大體能夠分爲以下步驟:

    • 判斷是否存在項目本地倉庫
      • 存在:進入該本地倉庫文件夾,經過git pull命令從Git遠程倉庫拉取最新代碼
      • 不存在:直接使用git clone命令從Git遠程倉庫克隆項目,並進入該項目文件夾
    • 使用go build命令編譯成二進制可執行文件
    • 執行事先寫好的docker-push腳本,編譯docker鏡像並上傳至docker倉庫

    if [ ! -d "/var/go-docker-demo" ];then
    	cd /var
        git clone https://hkail:xxxxxxxxx@gitee.com/hkail/go-docker-demo
        cd go-docker-demo
    else
    	cd /var/go-docker-demo
        git pull
    fi
    
    go build -o app
    
    chmod +x docker-push && ./docker-push
    複製代碼

    Dockerfile文件內容以下:

    FROM golang:1.14.2
    
    COPY app . COPY conf/conf.toml ./conf/ 
    ENTRYPOINT ["./app"] 複製代碼

    docker-push腳本內容以下:

    # 容器名
    name=`cat version | awk '{print $1}'`
    # 容器標籤
    tag=`cat version | awk '{print $2}'`
    # 倉庫域名
    domain=registry-vpc.cn-shenzhen.aliyuncs.com
    # 倉庫URL
    url=colehuang/coletest
     # 構建Docker鏡像
    docker build -t $name:$tag .
     # 獲取鏡像ID
    id=`docker images | grep $name | grep $tag | awk '{ print $3 }'`
     # 鏡像上傳至Docker鏡像倉庫
    docker login --username=xxx --password=xxx $domain
    docker tag $id $domain/$url:$tag
    docker push $domain/$url:$tag
    複製代碼

    version文件內容以下:

    gdd 1.1.2
    複製代碼
  7. 構建後操做

    構建後操做的過程大體能夠分爲以下步驟:

    • 將項目中的versiondocker-pull文件傳送至遠程服務器中
    • 進入在Publish over SSH中配置的遠程服務器目錄,並執行docker-pull腳本,從docker鏡像倉庫中拉取提交的新版本鏡像,並使用該鏡像構建docker容器

    docker-pull腳本內容以下:

    # 容器名
    name=`cat version | awk '{print $1}'`
    # 容器標籤
    tag=`cat version | awk '{print $2}'`
    # 倉庫域名
    domain=registry.cn-shenzhen.aliyuncs.com
    # 倉庫URL
    url=colehuang/coletest
     # 從Docker鏡像倉庫中拉取鏡像
    docker login --username=xxx --password=xxx $domain
    docker pull $domain/$url:$tag
     # 中止該鏡像正在運行的Docker容器
    line=`docker ps | grep $name`
    if [ -n "$line" ]; then
    	echo "存在正在運行的$name容器, 正在使其中止運行..."
    	docker stop $name
    	echo "$name容器, 已中止運行"
    fi
     # 刪除該鏡像的Docker容器
    line=`docker ps -a | grep $name`
    if [ -n "$line" ]; then
    	echo "存在$name容器, 對其進行刪除..."
    	docker rm $name
    	echo "$name容器, 已被刪除"
    fi
     # 啓動容器
    docker run --rm --name $name -p 8008:8006 -d $domain/$url:$tag
    
    IFS=$'\n'
     # 刪除多餘鏡像
    images=`docker images | grep $domain/$url`
    for i in $images
    	do
    		echo $i
    		t=`echo "$i" | awk '{print $2}'`
    		if [ "$t" != "$tag" ]; then
    			id=`echo "$i" | awk '{print $3}'`
    			docker rmi $id
    		fi
    	done
    複製代碼
  8. 基本完成

    完成以上全部配置後,當在本地將代碼pushGit 遠程倉庫時,則會觸發Git WebHooks,從而全自動的實現對服務器項目的自動更新和部署。

內容小結

這篇文章對如何使用Docker結合Jenkins實現Go語言項目的持續集成進行了簡單講解,在最後講一下實踐過程當中須要注意的地方。

首先是在Jenkins服務器上經過git pull命令拉取遠程倉庫的代碼時,若是爲私有倉庫,可能會須要輸入Git帳號和密碼,這裏使用的方式是經過設置Git全局變量的方式,記錄Git帳號和密碼。

git config --global credential.helper store
複製代碼

而後是最後的構建後操做過程當中,筆者本人會出現一個現象,當遠程服務器第一次從docker鏡像倉庫獲取鏡像時,會由於因爲遠程服務器本地不存在該鏡像依賴的其餘鏡像,從而致使拉取的速度較慢,出現超時的狀況。該問題的解決方案可修改超時時間或者進入遠程服務器中手動拉取一遍。

最後附上與演示項目內容一致的代碼倉庫:gitee.com/hkail/go-do…

實踐時需修改的內容可能有:

docker-push腳本文件中:domain倉庫域名,url倉庫URL,docker login命令後的用戶名和密碼

docker-pull腳本文件中:同docker-pull腳本文件,docker run命令後的映射端口號

最後,感謝你們的耐心閱讀~

相關文章
相關標籤/搜索