基于Gitlab-CI/CD Docker 持續(xù)集成 node 項(xiàng)目

最近揮霍青春穿挨、沉淪于學(xué)習(xí)科學(xué)文化知識,摸了些旁門左道肴盏,故而在此想做一些分享科盛,同時(shí)也是小弟我第一次編寫文章。以下都是一些僅代表個(gè)人的一些觀點(diǎn)和心得菜皂,本人盡量使用比較通俗易懂的話語來闡述贞绵,希望能給各位少俠一些啟發(fā)和幫助。若有解釋不當(dāng)?shù)牡胤交衅€請各位大鍋指點(diǎn)一二榨崩。


CI/CD介紹

對與Gitlab 提供的 CI/CD, 其稱之為持續(xù)集成服務(wù)、通俗點(diǎn)就是自動化(打包章母、測試蜡饵、部署 ...)

CI (持續(xù)構(gòu)建) --> 代碼提交后觸發(fā)自動化的單元測試,代碼預(yù)編譯胳施,構(gòu)建鏡像,上傳鏡像等.

CD (持續(xù)發(fā)布) --> 將構(gòu)建好的程序發(fā)布到各種環(huán)境肢专,如預(yù)發(fā)布環(huán)境舞肆,正式環(huán)境.


為什么要使用持續(xù)集成?

我們都知道,項(xiàng)目開發(fā)最基本的流程不過于 "開發(fā)" -> "打包" -> "測試" -> "部署"博杖,在一個(gè)完整項(xiàng)目的生命周期中椿胯,避免不了多次以上這樣的流程。傳統(tǒng)的模式可能會讓我們覺得厭煩剃根,原因不外乎于下面幾點(diǎn):

1哩盲、開發(fā)和打包都在同一臺機(jī)器上運(yùn)作,可能導(dǎo)致打包的過程中狈醉,影響開發(fā)的進(jìn)度

2、一天天的都是手動打包、測試唆貌、部署缸浦、日復(fù)一日的工作使我們厭倦

3、每個(gè)開發(fā)者都在自己的機(jī)器打包項(xiàng)目渣慕,不同的環(huán)境配置可能會有各種千奇百怪的問題

除以上問題嘶炭,當(dāng)然還有其他不盡人意的缺點(diǎn)抱慌,就不一 一描述了,上面的問題足以讓人腦殼深疼眨猎。在這個(gè)時(shí)候抑进,我相信強(qiáng)大的持續(xù)集成方案一定能解決你對開發(fā)流程不滿的地方

1、提供后臺集成服務(wù)睡陪,開發(fā)寺渗、打包,互不影響

2宝穗、減少人工編譯部署過程中的低級錯(cuò)誤

3户秤、解決不同環(huán)境下構(gòu)建項(xiàng)目產(chǎn)生不一致的問題

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


特別說明

本人使用的系統(tǒng)環(huán)境都是 ubuntu、使用docker须鼎,項(xiàng)目語言是node.js

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

個(gè)人建議使用兩臺以上的服務(wù)器, 一臺開發(fā)+測試鲸伴, 一臺部署發(fā)布項(xiàng)目 (筆者認(rèn)為,如果只使用一臺服務(wù)器晋控,實(shí)際上發(fā)揮不出 CI/CD 的威力)

對與網(wǎng)上現(xiàn)有的各大分享gitlab ci/cd 的文章汞窗,使用 shell 來搭建ci/cd服務(wù)的太多了,在此我就不介紹這種方案了赡译。但是基于docker 方案的文章仲吏,也看了不少,對與我個(gè)人而言并不是太友好蝌焚,有些說的比較高深裹唆,難以理解,有些過于簡單只洒,不夠詳細(xì)许帐。所以決定寫下這篇文章希望能和大家互相探討。該文章主要是基于docker 的持續(xù)集成方案毕谴。


認(rèn)識Gitlab-CI/CD流程

該小節(jié)適于初步認(rèn)識gitlab持續(xù)集成服務(wù)的讀者閱讀成畦、對于已經(jīng)理解基本流程的可以直接跳過本小節(jié)(這一節(jié)已經(jīng)不能教你什么了)

GitLab8.0之后,GitLab CI/CD 就已經(jīng)集成在GitLab里了涝开。給我?guī)追昼娧剩銜l(fā)現(xiàn),其實(shí)流程很簡單舀武。

pipeline

每次代碼提交就會觸發(fā)一次pipeline惧浴。如上去所示,每一行就是一個(gè)集成服務(wù)奕剃,我們稱之為流水線衷旅。一次pipeline可以看成一次構(gòu)建任務(wù)捐腿。

stage

stage就是上述構(gòu)建任務(wù)中的各個(gè)構(gòu)建階段。一般會包含:安裝依賴柿顶,測試茄袖,編譯,部署服務(wù)等多個(gè)階段嘁锯。

job

job表示構(gòu)建工作宪祥,是每個(gè)stage構(gòu)建階段里具體執(zhí)行的工作。

我們可以點(diǎn)擊進(jìn)去看看家乘,你會發(fā)現(xiàn)整個(gè)流程就像工廠車間里面的任務(wù)一樣蝗羊,一個(gè)任務(wù)完成后接著執(zhí)行下一個(gè)(或多個(gè))任務(wù),不難看出來仁锯,以上的任務(wù)順序?yàn)?build ->test -> deploy耀找。

(并且如果有其中一個(gè)任務(wù)失敗了,我們可以選擇后面的任務(wù)是否能繼續(xù)下去业崖,這對我們很有用野芒,而這些任務(wù)都是我們可以預(yù)先設(shè)定好的,并按照我們的規(guī)則來進(jìn)行)

通過上面這些概念上的東西双炕,你應(yīng)該對 Gitlab-CI/CD 的工作 流程有了初步的了解狞悲,但是這些任務(wù)都是交給誰來托管呢? 沒錯(cuò)妇斤,它就是 GitLab runner摇锋。下面就開始我們的主題吧。


啟動GitLab runner服務(wù)

1站超、首先要安裝docker荸恕、已經(jīng)安裝的可跳過此步驟:

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

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

2、創(chuàng)建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項(xiàng)目):

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

注冊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

成功后如下圖所示(該步驟有可能會出現(xiàn)網(wǎng)絡(luò)異常的情況剑刑,可以嘗試多次重試)

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

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

4撰糠、提升gitlab-runner用戶權(quán)限:

由于runner執(zhí)行過程中酥馍,是通過一個(gè)叫做 gitlab-runner 的用戶來進(jìn)行操作的,因?yàn)椴皇莚oot用戶阅酪,所以免不了會有權(quán)限問題旨袒,這里我們將其添加到docker組中,并驗(yàn)證gitlab-runner是否可以訪問Docker

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

配置.gitlab-ci.yml

好了术辐,通過上一節(jié)砚尽,我們已經(jīng)成功注冊runner了,是時(shí)候定制我們的持續(xù)集成服務(wù)了辉词,在項(xiàng)目根目錄中創(chuàng)建.gitlab-ci.yml文件必孤。(附上官方的文檔說明 配置gitlab-ci.yml規(guī)則)

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

# 使用docker鏡像
image: docker:latest
# 設(shè)置變量
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

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

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

# ----------------部署-----------------
deploy:
  # 切換ubuntu作為deploy任務(wù)的鏡像
  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登錄不驗(yàn)證HostKey
    - '[[ -f /.dockerenv ]] && echo -e "Host *\\n\\tStrictHostKeyChecking no\\n\\n" > ~/.ssh/config'
    # 使用ssh遠(yuǎn)程登錄正式服務(wù)器隧魄,并拉取之前build上傳好的鏡像進(jìn)行部署
    - 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、這里會涉及一個(gè)概念隘蝎,叫做docker in docker的概念购啄,針對這個(gè)我個(gè)人也沒能很好的解釋是個(gè)什么東西,以免誤導(dǎo)大家嘱么,因此提供官方的文檔 docker socket binding 給大家參考

2狮含、既然要使用自動化部署,那就免不了要使用ssh免密登錄策略曼振,此處就關(guān)于免密的就不做詳細(xì)介紹了几迄,可以參考該文檔 ssh免密登錄

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

如上圖所示,我們需要在我們gitlab項(xiàng)目中設(shè)置對應(yīng)的參數(shù):

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

REGISTRY_PASSWORD: 登錄你個(gè)人的docker鏡像倉庫密碼

DEPLOY_HOST: 你正式服務(wù)器的地址

SSH_PRIVATE_KEY: gitlab-runner所在的服務(wù)器的ssh私鑰

如下圖所示妖枚,我們在.gitlab-ci.yml只需要使用對應(yīng)的參數(shù)即可廷臼,很高大上的有木有

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

4荠商、各流程簡單描述

build: 因?yàn)槲覀價(jià)unner所在的服務(wù)器就是測試服務(wù)器寂恬,所以我們在構(gòu)建鏡像之前,需要先將使用了該鏡像的容器給刪除结啼,并刪除舊的鏡像掠剑。刪除后我們構(gòu)建新的鏡像,并登陸個(gè)人鏡像倉庫進(jìn)行上傳郊愧。(由于網(wǎng)絡(luò)沒辦法翻墻朴译,這里推薦使用 阿里云容器鏡像服務(wù),也可以使用你們自己搭載的個(gè)人鏡像倉庫属铁。 如果你們可以翻墻眠寿,也可以使用gitlab配套的容器鏡像倉庫,如下圖焦蘑,沒有翻墻請慎用盯拱,可能會導(dǎo)致上傳鏡像失敗的情況)

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

deploy: 因?yàn)閐ocker:latest 鏡像中沒有ssh服務(wù)狡逢,我們可以換一種思路,切換ubuntu:latest 鏡像拼卵,大家都知道奢浑,使用ssh遠(yuǎn)程登錄肯定免不了登錄驗(yàn)證, 這里一定要先打通服務(wù)器之間的ssh免密登錄腋腮,也就是上面的第2點(diǎn)說明雀彼,否則登錄不成功,接著就是給runner配置私鑰了即寡。針對這個(gè)徊哑,官方也有方案文檔 ssh-keys-when-using-the-docker-executor。需要注意的地方是聪富,一般我們不希望每一次構(gòu)建一次流水線就部署一次莺丑,因此我們可以在deploy中設(shè)置when: manual,它讓我們可以通過手動來控制是否需要執(zhí)行部署的操作

如圖所示墩蔓,我們可以根據(jù)前面的任務(wù)狀態(tài)來確定是否需要進(jìn)行部署任務(wù)梢莽,只需點(diǎn)一下紅色標(biāo)注的地方即可


總結(jié)

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

最后,由于這個(gè)Gitlab-CI/CD太過強(qiáng)大膜钓,還有很多高大上的方案本人也還在學(xué)習(xí)中嗽交,文章中出現(xiàn)的文檔鏈接都很有用,都是官方文檔的颂斜,每個(gè)人可能都會遇到各種不同的問題夫壁,本文只是做一個(gè)總結(jié)分享,并不一定能解決大家所遇到的問題沃疮,大家可以多閱讀資料盒让,互相探討一下

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市司蔬,隨后出現(xiàn)的幾起案子邑茄,更是在濱河造成了極大的恐慌,老刑警劉巖俊啼,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肺缕,死亡現(xiàn)場離奇詭異,居然都是意外死亡授帕,警方通過查閱死者的電腦和手機(jī)同木,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來跛十,“玉大人彤路,你說我怎么就攤上這事∨计鳎” “怎么了斩萌?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長屏轰。 經(jīng)常有香客問我颊郎,道長,這世上最難降的妖魔是什么霎苗? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任姆吭,我火速辦了婚禮,結(jié)果婚禮上唁盏,老公的妹妹穿的比我還像新娘内狸。我一直安慰自己,他們只是感情好厘擂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布昆淡。 她就那樣靜靜地躺著,像睡著了一般刽严。 火紅的嫁衣襯著肌膚如雪昂灵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機(jī)與錄音眨补,去河邊找鬼管削。 笑死,一個(gè)胖子當(dāng)著我的面吹牛撑螺,可吹牛的內(nèi)容都是我干的含思。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼甘晤,長吁一口氣:“原來是場噩夢啊……” “哼含潘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起线婚,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤调鬓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后酌伊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腾窝,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年居砖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了虹脯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,731評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奏候,死狀恐怖循集,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蔗草,我是刑警寧澤咒彤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站咒精,受9級特大地震影響镶柱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜模叙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一歇拆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧范咨,春花似錦故觅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至替蛉,卻和暖如春贯溅,著一層夾襖步出監(jiān)牢的瞬間炼杖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工盗迟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人熙含。 一個(gè)月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓罚缕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親怎静。 傳聞我的和親對象是個(gè)殘疾皇子邮弹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 原創(chuàng)文章,歡迎轉(zhuǎn)載蚓聘。轉(zhuǎn)載請注明:轉(zhuǎn)載自IT人故事會腌乡,謝謝!原文鏈接地址:『中級篇』docker之CI/CD持續(xù)集成...
    IT人故事會閱讀 1,642評論 1 7
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理夜牡,服務(wù)發(fā)現(xiàn)与纽,斷路器,智...
    卡卡羅2017閱讀 134,652評論 18 139
  • 一塘装、 為了優(yōu)化公司服務(wù)部署流程急迂, 減少不必要的登錄服務(wù)器操作, 實(shí)現(xiàn)提交代碼直接部署最短部署路徑蹦肴, 我們選擇了g...
    becareofzm閱讀 4,858評論 0 4
  • 【萱草芳菲 學(xué)而思 20180121 學(xué)會花錢】by 艾悅 最近老公和我簡單算了一下2017年花出去的錢年度總額僚碎,...
    眸眸_50ae閱讀 120評論 0 1
  • 我不知道自己想成為什么樣的人勺阐。 打下這行字時(shí),其實(shí)內(nèi)心萬分恐懼矛双。 小學(xué)時(shí)看過未名湖的圖片后渊抽,莫名憂心長大后要考清華...
    北城未眠閱讀 890評論 94 35