選單
GSS 技術部落格
在這個園地裡我們將從技術、專案管理、客戶對談面和大家分享我們多年的經驗,希望大家不管是喜歡或是有意見,都可以回饋給我們,讓我們有機會和大家對話並一起成長!
若有任何問題請來信:gss_crm@gss.com.tw
3 分鐘閱讀時間 (512 個字)

從原始碼到容器化

philipp-katzenberger-iIJrUoeRoCQ-unsplash-2

tags: CI Jenkins Docker



從原始碼到容器化

一、前言

最近常碰 Jenkins, Docker 等等比較偏 Ops 的技術,
而剛好手邊有一個任務是要串起CI流程,
因此這篇主要是針對做出的結果所做的筆記。

注意: 在往下走之前,先確你有基本的docker、docker-compose知識,
而且也已經用docker-compose在正式機起了一組微服務。


二、環境配置

作業的環境大致如下: 

OS : CentOS 7 64-bit
RAM: 4G
CPU: 2-Core
HDD: 32GB

使用到的技術如下:

版本控制: Gitlab
自動化: Jenkins
容器: Docker

三、開始動手

假設有多個微服務透過docker-compose啟動,
任一服務的原始碼有更動時,要能透過自動化流程自動更新容器,
流程步驟如下:

  1. 寫好程式碼,push到gitlab
  2. gitlab自動觸發Jenkins build
  3. Jenkins利用docker CLI產出image
  4. 依狀況將image push至registry或是產出tar
  5. 透過docker-compose重啟更新的服務

安裝Publish Over SSH Plugin

首先先參考連結安裝plugin,
安裝之後到Manage Jenkins -> Configure System

如上圖,要設定的東西如下:

  1. Name: 隨便給一個名字也可以
  2. Hostname: SSH Server的IP或Domain Name
  3. Username: 登入的帳號
  4. Remote Directory: 如果透過這個plugin傳檔,預設會放的路徑
  5. Passphrase/Password: 記得先勾選Use password authentication, or use a different key,這樣才能選擇要用密碼或是用一組ssh key(在這為了方便就不特別用ssh key了,一般來講這個是比較安全的選項)

設定Jenkins Build的觸發時機

我們專案的相依套件管理是交由maven管控的,
因此先在Jenkins新增一個專案並進入組態設定:

如上圖,先設定好repository的url/crediential。

接著在Build Triggers的部份先勾選Build when a change is pushed to GitLab

如上圖,勾選後再來按下Advanced,會看到如下的展開:

我們的情境是以master當作是dockerized app release branch,
因此限定這個build只在master有git push的時候被觸發。

另外,這邊的Secret Token在一開始會是空白的,
記得按下Generate產生一組token並複製起來,
等下設定Gitlab的時候會用到。

設定Gitlab的觸發時機

設定好Jenkins在觸發的參數後接著要來設定Gitlab,
先到該repository的settings -> Integration選單如下圖:

這裡有幾個重點要留意:

  1. 首先是要觸發的URL,這個在前面Jenkins勾選的時候後方有附上一串URL
  2. 接著是Secret Token,前面在Jenkins頁面按下Generate的產出貼到這
  3. 最後是什麼樣的Event及什麼branch會觸發上面的URL

這三個都設定好之後按下Add Webhook會出現一個Trigger在下方:

到這邊先別急著做什麼,還有一些流程要設定,
我們不是還要對docker-compose起的服務作更新嗎?

設定Artifact利用Docker CLI作的後處理

首先當然是要設定maven的goal,這邊只是為了展示方便,
暫時加上-DskipTests的設定,在正式環境當然是要跑測試的:

再來就是設定Artifact產出後如何處理:

離線版

如上圖,第一個步驟就是先將jar檔透過Dockerfile的描述build成image,
接著將產出的image打包成tar檔,以便在沒有對外網路的客戶端使用。
打包完之後就要自動部署到正式環境了(如果是客戶端應該是用USB或光碟攜出):

透過先前安裝的Plugin,先選好SSH Server是哪台,
再來將前面打包的tar檔複製到設定好的路徑,
最後透過docker load的方式將tar展開,
docker image的部份就在這邊直接更新完成了,
緊接著再透過下一個Step來重啟服務:

如上圖,其實只是切到docker-compose所在路徑,
再執行一段寫好的shell script針對單一服務作stop與up:

#!/bin/sh if [[ $# -eq 0 ]] ; then echo 'No service assigned!!' exit 1 fi serviceName=$1 docker-compose stop $serviceName docker-compose up -d --no-deps $serviceName

有網路版

如上圖,image產出後先加上tag,再push到docker registry,
也正因為push上registry,也不用特別作docker load了,
但shell script內容會稍微不一樣:


#!/bin/sh if [[ $# -eq 0 ]] ; then echo 'No service assigned!!' exit 1 fi serviceName=$1 docker-compose stop $serviceName docker-compose pull $serviceName # 差異在這一行 docker-compose up -d --no-deps $serviceName

四、結論

很快地我們串起了從程式原始碼-> Push至Gitlab -> Jenkins Build -> Docker image -> 重啟docker-compose單一服務的流程,這邊主要都是自己覺得這樣最順,如果有更好的建議請不吝指教。

Docker registry 刪除特定 Tag
Jenkins 容器中執行 docker 指令

相關文章