摘要:為了看起來清晰,我寫了一個文件,將這個文件和之前的放在同一個目錄中,可以用以下命令快速啟動,啟動之后新構(gòu)建的鏡像和容器都名為。
在軟件開發(fā)過程中,如果我們每一次提交的代碼都能夠進(jìn)行一次完整的編譯、測試、打包、發(fā)布,就能及早發(fā)現(xiàn)問題、及早修復(fù),在保證代碼質(zhì)量的同時讓產(chǎn)品快速迭代。這就是持續(xù)集成(CI)、持續(xù)部署(CD)的好處。
目前 CI/CD 的方案有很多,本文將展示一個用 Docker + Jenkins 實(shí)現(xiàn)的完整過程。
本文的 CI/CD 流程開發(fā)人員提交代碼到自己的分支并 push 到遠(yuǎn)程倉庫 ==> 觸發(fā)遠(yuǎn)程倉庫(GitHub/GitLab)的 Webhooks ==> Jenkins 接到通知自動執(zhí)行之前準(zhǔn)備好的一個流程(克隆代碼,對代碼進(jìn)行編譯、測試、打包,沒有問題后會執(zhí)行 docker 命令進(jìn)行鏡像構(gòu)建)==> 最終發(fā)布到測試服務(wù)器中。
環(huán)境說明本文選用的測試環(huán)境是阿里云的服務(wù)器,所以全程也是在服務(wù)器上操作的,無需本地安裝 docker,當(dāng)然在本地操作也是可以的。
本文選用的遠(yuǎn)程代碼庫是 GitHub 公有倉庫,如果是私有倉庫或 GitLab,步驟會略有不同。
本文中所用的 Jenkins 也是用的 docker 版,并不是直接安裝在宿主機(jī)上的。
開始一個 docker 應(yīng)用要演示整個過程,就得有一個應(yīng)用,這里我們用一個 create-react-app 為例,無需 IDE,一個 terminal 即可搞定。
首先創(chuàng)建 react-app 和 Dockerfile
4、5 行是增加了一個設(shè)置,是關(guān)掉 webpack 的 host 檢查,如果不加此項(xiàng),訪問綁定域名的服務(wù)器就會被 webpack-dev-server 攔截。
$ npm install -g create-react-app $ create-react-app my-app $ cd my-app $ touch .env $ echo DANGEROUSLY_DISABLE_HOST_CHECK=true > .env $ touch Dockerfile
將以下內(nèi)容寫入 Dockerfile:
為了簡單,我們這里直接采用 npm start 的方式啟動它,就不 build 了,安裝 cnpm 是為了提高依賴的下載速度
FROM node:8.11.1-slim WORKDIR /home/app COPY . ${WORKDIR} RUN npm install -g cnpm --registry=https://registry.npm.taobao.org && cnpm install EXPOSE 3000 ENTRYPOINT [ "npm", "start" ]
到這里就完全好了,單元測試什么的就暫且忽略。
為什么要使用 Jenkins如果沒有 Jenkins,就上面那個例子,我們想要將自己的代碼集成并且部署到服務(wù)器,可能要經(jīng)歷以下步驟:
1、將代碼 push 到倉庫
2、ssh 登錄服務(wù)器,克隆代碼到宿主機(jī)(宿主機(jī)還要安裝 git)
3、執(zhí)行以下命令完成鏡像構(gòu)建和部署
$ cd repository $ docker build -t test . $ docker run -d -p 80:3000 --name my-react test
可以看到上面那個過程需要人工操作,非常繁瑣,這還沒算上對代碼進(jìn)行測試,如果每次提交了代碼都要來一個這樣的過程,那是真的沒法專心搞開發(fā)了。
如果用了 Jenkins,上面的整個過程都可以自動化完成。
初始化 JenkinsJenkins 的官網(wǎng)是 jenkins.io,它有很多種安裝方式,例如下載 war 包到宿主機(jī)上,然后用 java -jar jenkins.war 命令啟動。但是這種安裝方式非常不利于管理和服務(wù)器的遷移,完全是在給 docker 托后腿。所以我選擇用 docker 版的 jenkins。
使用 docker 版的 jenkins 是需要注意很多細(xì)節(jié)的
首先我們要重寫官方 jenkins 鏡像
$ vi Dockerfile
FROM jenkins/jenkins:lts USER root RUN echo deb http://mirrors.aliyun.com/debian wheezy main contrib non-free deb-src http://mirrors.aliyun.com/debian wheezy main contrib non-free deb http://mirrors.aliyun.com/debian wheezy-updates main contrib non-free deb-src http://mirrors.aliyun.com/debian wheezy-updates main contrib non-free deb http://mirrors.aliyun.com/debian-security wheezy/updates main contrib non-free deb-src http://mirrors.aliyun.com/debian-security wheezy/updates main contrib non-free > /etc/apt/sources.list && apt-get update && apt-get install -y libltdl-dev
這里用了 jenkins 最新穩(wěn)定版最為基礎(chǔ)鏡像,主要干了兩件事:一、將賬戶改為 root,避免后面不必要的權(quán)限問題;二、安裝 libltdl-dev ,它是為了解決用 jenkins 調(diào)用容器外部 docker 命令時發(fā)生以下錯誤的問題。(第 4~10 行是為了換阿里源提高速度)
docker: error while loading shared libraries: libltdl.so.7: cannot open shared object file: No such file or directory
在啟動剛剛重寫好的 jenkins 鏡像的時候還需要掛載三個宿主機(jī)的目錄到容器內(nèi),第一個 jenkins_home 是為了對容器內(nèi) jenkins 的所有改動做數(shù)據(jù)持久化。最后兩個目錄是為了能讓容器內(nèi)的 jenkins 調(diào)用并操作容器外的 docker。
$ vi docker-compose.yml
version: "3" services: jenkins: build: . image: my_jenkins ports: - "8090:8080" - "50000:50000" container_name: my_jenkins volumes: - "/home/jenkins_home:/var/jenkins_home" - "/var/run/docker.sock:/var/run/docker.sock" - "/usr/bin/docker:/usr/bin/docker"
為了看起來清晰,我寫了一個 docker-compose.yml 文件,將這個文件和之前的 Dockerfile 放在同一個目錄中,可以用以下命令快速啟動 jenkins,啟動之后新構(gòu)建的鏡像和容器都名為 my_jenkins。
$ docker-compose up -d
啟動 jenkins 后瀏覽器訪問 ip:8090 可看到初始化頁面
這里要輸入密碼,它給出了密碼在容器內(nèi)的位置,我們要將路徑改成宿主機(jī)上的,然后 cat 一下就能看到密碼。
$ cat /home/jenkins_home/secrets/initialAdminPassword
將密碼粘貼進(jìn)去然后點(diǎn)繼續(xù),下一個頁面選擇插件,點(diǎn)默認(rèn)推薦的就好了
接著按提示創(chuàng)建一個賬戶
之后就能夠使用 jenkins 了
配置 Webhooks要讓 jenkins 操作本機(jī)上的 docker 的前提是它收到了我們 push 代碼的通知,而這個通知就是由 GitHub 上的 Webhooks 來完成的,所以要將這兩者關(guān)聯(lián)起來。
配置 Webhooks 之前首先要更改一下安全設(shè)置
打開全局安全配置,軟后進(jìn)行如下操作,否則 Webhooks 連接不成功,設(shè)置好了別忘了點(diǎn)保存。
開始創(chuàng)建任務(wù)
點(diǎn)擊首頁的「開始創(chuàng)建一個新任務(wù)」,起個名字,選擇流水線。
生成身份令牌
點(diǎn)擊「構(gòu)建觸發(fā)器」,選擇「觸發(fā)遠(yuǎn)程構(gòu)建」,然后隨便填寫一段字符,然后把 URL 復(fù)制下來,記得把「JENKINS_URL」和「TOKEN_NAME」替換為相應(yīng)的值,例如下圖最終得到的 URL 就是 111.11.1.1:8090/job/test/build?token=123456,記下 URL 后點(diǎn)保存。
去 GitHub 創(chuàng)建 Webhooks
打開我們要 push 代碼的倉庫,點(diǎn)擊「Add webhook」
然后將剛才記下的回調(diào) URL 填寫到這里即可
此時,可以嘗試一下 push 代碼到倉庫,正常情況下,jenkins 就會自動進(jìn)行構(gòu)建,雖然沒有配置要構(gòu)建什么,但是它也會進(jìn)行這個任務(wù),如果構(gòu)建歷史中自動出現(xiàn)了一個顏色是藍(lán)色的任務(wù)則代表整個自動觸發(fā)的過程是配置成功的。
編寫自動任務(wù)腳本進(jìn)行 CI/CD點(diǎn)擊上面那個任務(wù)的「配置」,切換到流水線這里。本文不介紹流水線語法,就用 shell 命令來編寫整個過程。但我們首先還是要點(diǎn)擊「流水線語法」
將示例步驟切換到「sh: Shell Script」,編寫好 shell 腳本,熟悉 linux 命令的話,這個過程也應(yīng)該很容易。寫好之后點(diǎn)擊「生成流水線腳本」,之后把生成好的流水線腳本復(fù)制下來。
將生成好的 流水線腳本復(fù)制到這里就好了,不過要把它復(fù)制到一個 node{} 里面才行。
以下是我寫的生成好的流水線腳本,記得把定義的四個變量替換一下。
node { sh """#!/bin/sh REPOSITORY_NAME="你的倉庫名" REPOSITORY_URL="你的倉庫地址" IMAGE_NAME="給你要構(gòu)建的鏡像起個名字" CONTAINER_NAME="給你要構(gòu)建的容器起個名字" echo "清除倉庫目錄" rm ${REPOSITORY_NAME} -r echo "克隆遠(yuǎn)程倉庫" git clone ${REPOSITORY_URL} echo "刪除之前的鏡像和容器" docker stop ${CONTAINER_NAME} docker rm ${CONTAINER_NAME} docker rmi ${IMAGE_NAME} echo "構(gòu)建鏡像" cd ${REPOSITORY_NAME} docker build -t ${IMAGE_NAME} . echo "發(fā)布應(yīng)用" docker run -d -p 80:3000 --name ${CONTAINER_NAME} ${IMAGE_NAME}""" }
最后可以提交一次代碼或者點(diǎn)擊「立即構(gòu)建」,就會自動完成整個過程,在「控制臺輸出」那里可以看到構(gòu)建過程。
此時,瀏覽器訪問 ip 就能看到更新過的應(yīng)用了,這就是一個 CI/CD 過程,整個過程省略的測試環(huán)節(jié),可自行加上。
后記用一個測試服務(wù)器來做 CI/CD,能夠更及時的發(fā)現(xiàn)問題、解決問題,提高代碼質(zhì)量。
但是本文所展示的過程缺陷也很明顯,在更新應(yīng)用時,是會先停掉容器,再啟動新容器的,不能做到無宕機(jī)更新。而且整個過程也沒有服務(wù)監(jiān)控什么的,不能很好地了解無服務(wù)的運(yùn)行狀態(tài)。
總之,到目前為止,我們已經(jīng)能夠很好地將 docker 用在日常的開發(fā)中了。
點(diǎn)擊查看博客原文
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/27309.html
摘要:王者榮耀項(xiàng)目組高級測試工程師工程師文化團(tuán)隊(duì)中的實(shí)踐本文不是一篇入門教程,而是從結(jié)合實(shí)際場景,闡述在團(tuán)隊(duì)協(xié)作中如何去好好地應(yīng)用。 CI Weekly 圍繞『 軟件工程效率提升』 進(jìn)行一系列技術(shù)內(nèi)容分享,包括國內(nèi)外持續(xù)集成、持續(xù)交付,持續(xù)部署、自動化測試、 DevOps 等實(shí)踐教程、工具與資源,以及一些工程師文化相關(guān)的程序員 Tips 。同步于 flow.ci Blog、微信公眾號、官方微...
摘要:隔離的進(jìn)程獨(dú)立于宿主和其它的隔離的進(jìn)程。容器可以被創(chuàng)建啟動停止刪除暫停等。添加內(nèi)核參數(shù)使用看到下面的這些警告信息解決方法內(nèi)核配置參數(shù)以啟用這些功能。然后重新加載 Docker簡介 Docker 是使用 Go 語言 進(jìn)行開發(fā)實(shí)現(xiàn),基于 Linux 內(nèi)核的 cgroup,namespace,以及 AUFS 類的 Union FS 等技術(shù),對進(jìn)程進(jìn)行封裝隔離,屬于 操作系統(tǒng)層面的虛擬化技...
摘要:隔離的進(jìn)程獨(dú)立于宿主和其它的隔離的進(jìn)程。容器可以被創(chuàng)建啟動停止刪除暫停等。添加內(nèi)核參數(shù)使用看到下面的這些警告信息解決方法內(nèi)核配置參數(shù)以啟用這些功能。然后重新加載 Docker簡介 Docker 是使用 Go 語言 進(jìn)行開發(fā)實(shí)現(xiàn),基于 Linux 內(nèi)核的 cgroup,namespace,以及 AUFS 類的 Union FS 等技術(shù),對進(jìn)程進(jìn)行封裝隔離,屬于 操作系統(tǒng)層面的虛擬化技...
摘要:年開發(fā)者應(yīng)該熟練使用,并且知道版本更新內(nèi)容。對開發(fā)和運(yùn)維人員來說,最希望的就是一次性創(chuàng)建或配置,可以在任意地方正常運(yùn)行。是標(biāo)準(zhǔn)規(guī)范,是開發(fā)的實(shí)踐標(biāo)準(zhǔn)。對開發(fā)者來說語言推薦和,全棧的選擇非常多,推薦熱門的 前言 在前天(2018-08-02)已經(jīng)發(fā)布了PHP 7.3.0.beta1 Released 如果你還沒有使用 PHP7 ,那真的很遺憾。2018年P(guān)HP開發(fā)者應(yīng)該熟練使用 PHP7...
閱讀 1292·2023-04-26 01:03
閱讀 1907·2021-11-23 09:51
閱讀 3299·2021-11-22 15:24
閱讀 2662·2021-09-22 15:18
閱讀 1010·2019-08-30 15:55
閱讀 3458·2019-08-30 15:54
閱讀 2233·2019-08-30 15:53
閱讀 2387·2019-08-30 15:44