基于Gitlab-CI/CD Docker 持續集成 node 項目

最近揮霍青春、沉淪于學習科學文化知識,摸了些旁門左道,故而在此想做一些分享,同時也是小弟我第一次編寫文章。以下都是一些僅代表個人的一些觀點和心得,本人盡量使用比較通俗易懂的話語來闡述,希望能給各位少俠一些啟發和幫助。若有解釋不當的地方,還請各位大鍋指點一二。


CI/CD介紹

對與Gitlab 提供的 CI/CD, 其稱之為持續集成服務、通俗點就是自動化(打包、測試、部署 ...)

CI (持續構建) --> 代碼提交后觸發自動化的單元測試,代碼預編譯,構建鏡像,上傳鏡像等.

CD (持續發布) --> 將構建好的程序發布到各種環境,如預發布環境,正式環境.


為什么要使用持續集成?

我們都知道,項目開發最基本的流程不過于 "開發" -> "打包" -> "測試" -> "部署",在一個完整項目的生命周期中,避免不了多次以上這樣的流程。傳統的模式可能會讓我們覺得厭煩,原因不外乎于下面幾點:

1、開發和打包都在同一臺機器上運作,可能導致打包的過程中,影響開發的進度

2、一天天的都是手動打包、測試、部署、日復一日的工作使我們厭倦

3、每個開發者都在自己的機器打包項目,不同的環境配置可能會有各種千奇百怪的問題

除以上問題,當然還有其他不盡人意的缺點,就不一 一描述了,上面的問題足以讓人腦殼深疼。在這個時候,我相信強大的持續集成方案一定能解決你對開發流程不滿的地方

1、提供后臺集成服務,開發、打包,互不影響

2、減少人工編譯部署過程中的低級錯誤

3、解決不同環境下構建項目產生不一致的問題

還有各種好處。。。(具體還是根據大家不同的場景需求定制自己的自動化方案吧)


特別說明

本人使用的系統環境都是 ubuntu、使用docker,項目語言是node.js

不熟悉docker基礎的仁兄們需要先看看docker的一些基礎知識

個人建議使用兩臺以上的服務器, 一臺開發+測試, 一臺部署發布項目 (筆者認為,如果只使用一臺服務器,實際上發揮不出 CI/CD 的威力)

對與網上現有的各大分享gitlab ci/cd 的文章,使用 shell 來搭建ci/cd服務的太多了,在此我就不介紹這種方案了。但是基于docker 方案的文章,也看了不少,對與我個人而言并不是太友好,有些說的比較高深,難以理解,有些過于簡單,不夠詳細。所以決定寫下這篇文章希望能和大家互相探討。該文章主要是基于docker 的持續集成方案。


認識Gitlab-CI/CD流程

該小節適于初步認識gitlab持續集成服務的讀者閱讀、對于已經理解基本流程的可以直接跳過本小節(這一節已經不能教你什么了)

GitLab8.0之后,GitLab CI/CD 就已經集成在GitLab里了。給我幾分鐘,你會發現,其實流程很簡單。

pipeline

每次代碼提交就會觸發一次pipeline。如上去所示,每一行就是一個集成服務,我們稱之為流水線。一次pipeline可以看成一次構建任務。

stage

stage就是上述構建任務中的各個構建階段。一般會包含:安裝依賴,測試,編譯,部署服務等多個階段。

job

job表示構建工作,是每個stage構建階段里具體執行的工作。

我們可以點擊進去看看,你會發現整個流程就像工廠車間里面的任務一樣,一個任務完成后接著執行下一個(或多個)任務,不難看出來,以上的任務順序為 build ->test -> deploy。

(并且如果有其中一個任務失敗了,我們可以選擇后面的任務是否能繼續下去,這對我們很有用,而這些任務都是我們可以預先設定好的,并按照我們的規則來進行)

通過上面這些概念上的東西,你應該對 Gitlab-CI/CD 的工作 流程有了初步的了解,但是這些任務都是交給誰來托管呢? 沒錯,它就是 GitLab runner。下面就開始我們的主題吧。


啟動GitLab runner服務

1、首先要安裝docker、已經安裝的可跳過此步驟:

(附上docker 安裝的官方文檔 Get Docker CE for Ubuntu | Docker Documentation)

sudo apt-get update
sudo apt-get install docker-ce

2、創建gitlab-runner容器:

sudo docker pull gitlab/gitlab-runner:latest
sudo docker stop gitlab-runner && docker rm gitlab-runner
sudo docker run -d --name gitlab-runner --restart always \
  -v /srv/gitlab-runner/config:/etc/gitlab-runner \
  -v /var/run/docker.sock:/var/run/docker.sock \
  gitlab/gitlab-runner:latest

3、注冊runner(綁定gitlab項目):

首先我們需要打開自己gitlab的項目,打開一下紅色指示的地方

注冊runner:

sudo docker exec -it gitlab-runner gitlab-ci-multi-runner register -n \
  --url 這里填寫上圖中的url \
  --registration-token 這里填寫上圖中的token \
  --executor docker \
  --description "gitlab-runner in docker" \
  --tag-list "ci-cd" \
  --docker-privileged=false \
  --docker-pull-policy="if-not-present" \
  --docker-image "docker:latest" \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock

成功后如下圖所示(該步驟有可能會出現網絡異常的情況,可以嘗試多次重試)

上面的命令將注冊一個新的 Runner 來使用 Docker 所提供的特殊docker:latest鏡像。這里使用的是官方提供的 Use Docker socket binding 模式,是將/var/run/docker.sock綁定裝載到容器中,以便 docker 在該鏡像的上下文中可用。(請注意,它正在使用 宿主機 本身的 Docker 守護進程,docker 命令產生的任何容器都將是 一開始我們創建gitlab-runner容器的兄弟,而不是所運行程序的子進程)有興趣可自行閱讀官方文檔,看看具體參數的用法。

這里需要說明的是 docker-pull-policy,設置gitlab是否從遠程拉去image, 如果iamge是本地的,需要配置該屬性的值為 if-not-present,這樣可以避免docker 鏡像每次都pull

4、提升gitlab-runner用戶權限:

由于runner執行過程中,是通過一個叫做 gitlab-runner 的用戶來進行操作的,因為不是root用戶,所以免不了會有權限問題,這里我們將其添加到docker組中,并驗證gitlab-runner是否可以訪問Docker

sudo usermod -aG docker gitlab-runner
sudo -u gitlab-runner -H docker info

配置.gitlab-ci.yml

好了,通過上一節,我們已經成功注冊runner了,是時候定制我們的持續集成服務了,在項目根目錄中創建.gitlab-ci.yml文件。(附上官方的文檔說明 配置gitlab-ci.yml規則)

先附上完整版的yml,里面均有注釋,后面再針對特殊的地方做些解釋

# 使用docker鏡像
image: docker:latest
# 設置變量
variables:
  # 鏡像倉庫地址
  REGISTRY: registry.cn-shenzhen.aliyuncs.com
  # 鏡像版本
  REGISTRY_IMAGE_TAG: registry.cn-shenzhen.aliyuncs.com/jieyufeng/gitlab-ci-cd:master
  # 鏡像啟動后的容器名
  CONTAINER_NAME: gitlab-ci-cd

stages:
  - build
  - test
  - deploy

# ----------------構建-----------------
build:
  stage: build
  script:
    # 停止并刪除正在使用當前鏡像的容器
    - if [ "$(docker ps -a | grep $CONTAINER_NAME)" ]; then
    -  docker stop $CONTAINER_NAME && docker rm $CONTAINER_NAME
    - fi
    # 刪除當前已存在的鏡像
    - if [ "$(docker images | grep $REGISTRY_IMAGE_TAG)" ]; then
    -  docker rmi $REGISTRY_IMAGE_TAG
    - fi
    # 登錄鏡像倉庫
    - docker login -u $REGISTRY_USER -p $REGISTRY_PASSWORD $REGISTRY
    # 構建新的鏡像
    - docker build -t $REGISTRY_IMAGE_TAG .
    # 上傳鏡像
    - docker push $REGISTRY_IMAGE_TAG
  only:
    - master
  tags:
    - ci-cd

# ----------------測試-----------------
test:
  stage: test
  script:
    # 本地啟動容器進行測試
    - docker run -d --name $CONTAINER_NAME -p 3000:3000 $REGISTRY_IMAGE_TAG
  when: on_success
  only:
    - master
  tags:
    - ci-cd

# ----------------部署-----------------
deploy:
  # 切換ubuntu作為deploy任務的鏡像
  image: ubuntu:latest
  stage: deploy
  script:
    # 給runner配置私鑰
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    # 給runner配置ssh登錄不驗證HostKey
    - '[[ -f /.dockerenv ]] && echo -e "Host *\\n\\tStrictHostKeyChecking no\\n\\n" > ~/.ssh/config'
    # 使用ssh遠程登錄正式服務器,并拉取之前build上傳好的鏡像進行部署
    - ssh root@$DEPLOY_HOST "
      docker images;
      docker login -u $REGISTRY_USER -p $REGISTRY_PASSWORD $REGISTRY;
      docker pull $REGISTRY_IMAGE_TAG;
      docker run -d --name $CONTAINER_NAME -p 3000:3000 $REGISTRY_IMAGE_TAG;"
  when: manual
  allow_failure: false
  only:
    - master
  tags:
    - ci-cd

部分說明:

1、這里會涉及一個概念,叫做docker in docker的概念,針對這個我個人也沒能很好的解釋是個什么東西,以免誤導大家,因此提供官方的文檔 docker socket binding 給大家參考

2、既然要使用自動化部署,那就免不了要使用ssh免密登錄策略,此處就關于免密的就不做詳細介紹了,可以參考該文檔 ssh免密登錄

3、試想一下,有些敏感的參數我們是不希望明文暴露在.gitlab-ci.yml 中的,比如密碼、私鑰等,那怎么辦才好呢?對此,官方提供了很好的方案 GitLab CI/CD Variables,設置后,我們可以直接使用參數來代替銘感信息

如上圖所示,我們需要在我們gitlab項目中設置對應的參數:

REGISTRY_USER: 登錄你個人的docker鏡像倉庫用戶名

REGISTRY_PASSWORD: 登錄你個人的docker鏡像倉庫密碼

DEPLOY_HOST: 你正式服務器的地址

SSH_PRIVATE_KEY: gitlab-runner所在的服務器的ssh私鑰

如下圖所示,我們在.gitlab-ci.yml只需要使用對應的參數即可,很高大上的有木有

對與不敏感的信息,我們也可以.gitlab-ci.yml設置參數 (其實就跟我們平常寫代碼,聲明一個全局的參數是一個道理的)

4、各流程簡單描述

build: 因為我們runner所在的服務器就是測試服務器,所以我們在構建鏡像之前,需要先將使用了該鏡像的容器給刪除,并刪除舊的鏡像。刪除后我們構建新的鏡像,并登陸個人鏡像倉庫進行上傳。(由于網絡沒辦法翻墻,這里推薦使用 阿里云容器鏡像服務,也可以使用你們自己搭載的個人鏡像倉庫。 如果你們可以翻墻,也可以使用gitlab配套的容器鏡像倉庫,如下圖,沒有翻墻請慎用,可能會導致上傳鏡像失敗的情況)

test: 正如剛才我們說的 runner所在的服務器就是測試服務器,所以test的任務比較簡單,就是使用docker啟動我們剛才編譯的鏡像即可

deploy: 因為docker:latest 鏡像中沒有ssh服務,我們可以換一種思路,切換ubuntu:latest 鏡像,大家都知道,使用ssh遠程登錄肯定免不了登錄驗證, 這里一定要先打通服務器之間的ssh免密登錄,也就是上面的第2點說明,否則登錄不成功,接著就是給runner配置私鑰了。針對這個,官方也有方案文檔 ssh-keys-when-using-the-docker-executor。需要注意的地方是,一般我們不希望每一次構建一次流水線就部署一次,因此我們可以在deploy中設置when: manual,它讓我們可以通過手動來控制是否需要執行部署的操作

如圖所示,我們可以根據前面的任務狀態來確定是否需要進行部署任務,只需點一下紅色標注的地方即可


總結

雞湯:可能對于像我這樣的新手一開始接觸這個,會有很多很多困惑,也會遇到各種各樣的問題。但是勇于嘗試,總能成功的,畢竟羅馬也不是一天建成的不是嗎?

最后,由于這個Gitlab-CI/CD太過強大,還有很多高大上的方案本人也還在學習中,文章中出現的文檔鏈接都很有用,都是官方文檔的,每個人可能都會遇到各種不同的問題,本文只是做一個總結分享,并不一定能解決大家所遇到的問題,大家可以多閱讀資料,互相探討一下

附上本人簡單的demo: gitlab-ci-cd

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,604評論 2 380

推薦閱讀更多精彩內容

  • 原創文章,歡迎轉載。轉載請注明:轉載自IT人故事會,謝謝!原文鏈接地址:『中級篇』docker之CI/CD持續集成...
    IT人故事會閱讀 1,668評論 1 7
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,828評論 18 139
  • 一、 為了優化公司服務部署流程, 減少不必要的登錄服務器操作, 實現提交代碼直接部署最短部署路徑, 我們選擇了g...
    becareofzm閱讀 4,897評論 0 4
  • 【萱草芳菲 學而思 20180121 學會花錢】by 艾悅 最近老公和我簡單算了一下2017年花出去的錢年度總額,...
    眸眸_50ae閱讀 122評論 0 1
  • 我不知道自己想成為什么樣的人。 打下這行字時,其實內心萬分恐懼。 小學時看過未名湖的圖片后,莫名憂心長大后要考清華...
    北城未眠閱讀 908評論 94 35