部署基於Gitlab+Docker+Rancher+Harbor的前端項目這一篇就夠了


部署基於Gitlab+Docker+Rancher+Harbor的前端項目這一篇就夠了

安大虎
momenta 中台開發工程師
部署基於Gitlab+Docker+Rancher+Harbor的前端項目這一篇就夠了

就目前的形勢看,一家公司的運維體系不承載在 Docker+Harbor(或 Pouch 等同類平台)之上都不好意思說自己的互聯網公司。當然這些技術也不適用於全部公司,技術在迭代,平台也一樣,把我使用的工具和大家分享下,一起成長(文章中擴展可按需Google)。

Docker

docker的架構圖如下:

從圖中可以看出幾個組成部分

  • docker client: 即 docker 命令行工具
  • docker host: 宿主機,docker daemon 的運行環境服務器
  • docker daemondocker 的守護進程,docker client 通過命令行與 docker daemon 交互
  • container: 最小型的一個操作系統環境,可以對各種服務以及應用容器化
  • image: 鏡像,可以理解為一個容器的模板配置,通過一個鏡像可以啟動多個容器
  • registry: 鏡像倉庫,存儲大量鏡像,可以從鏡像倉庫拉取和推送鏡像

我在剛接觸到Docker的時候,產生了一種錯覺--這不就是個性能不錯的虛擬機嗎?顯然他能做的遠比虛擬機多得多。具體表現在 Docker 不是在宿主機上虛擬出一套硬件后再虛擬出一個操作系統,而是讓 Docker 容器里面的進程直接運行在宿主機上(Docker 會做文件、網絡等的隔離),這樣一來 Docker 會 “體積更輕、跑的更快、同宿主機下可創建的個數更多”(類似於一個一個的沙箱,互相不暴露接口,互相不影響)。

Docker 中有三個核心概念:Image、Container、Repository。

  • Image: 和 windows 的那種 iso 鏡像相比,Docker 中的鏡像是分層的,可復用的,而非簡單的一堆文件迭在一起(類似於一個壓縮包的源碼和一個 git 倉庫的區別)。
  • Container: 容器的存在離不開鏡像的支持,他是鏡像運行時的一個載體(類似於實例和類的關系)。依托 Docker 的虛擬化技術,給容器創建了獨立的端口、進程、文件等“空間”,Container 就是一個與宿機隔離 “沙箱”。沙箱可在宿主機之間可以進行 port、volumes、network 等的通信。
  • Repository: Docker 的倉庫和 git 的倉庫比較相似,擁有倉庫名、tag。在本地構建完鏡像之后,即可通過倉庫進行鏡像的分發。常用的 Docker hub 有  、  等。

底層原理

docker 底層使用了一些 linux 內核的特性,大概有 namespacecgroups 和 ufs

namespace

docker 使用 linux namespace 構建隔離的環境,它由以下 namespace 組成

  • pid: 隔離進程
  • net: 隔離網絡
  • ipc: 隔離 IPC
  • mnt: 隔離文件系統掛載
  • uts: 隔離hostname
  • user: 隔離uid/gid

control groups

也叫 cgroups,限制資源配額,比如某個容器只能使用 100M 內存

Union file systems

UnionFS 是一種分層、輕量級並且高性能的文件系統,支持對文件系統的修改作為一次提交來一層層的疊加。docker 的鏡像與容器就是分層存儲,可用的存儲引擎有 aufsoverlay 等。

鏡像

鏡像是一份用來創造容器的配置文件,而容器可以視作最小型的一個操作系統(類似於容器由鏡像解壓而來)。

docker 的鏡像和容器都使用了 unionFS 做分層存儲,鏡像作為只讀層是共享的,而容器在鏡像之上附加了一層可寫層,最大程度地減少了空間的浪費,詳見下圖

鏡像倉庫與拉取

我們可以在官方鏡像倉庫拉取鏡像,也可以自己構造鏡像

# 加入拉取一個 node:alpine 的鏡像
$ docker pull node:alpine

# 查看鏡像信息
$ docker inspect node:alpine

# 列出所有鏡像
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
node                alpine              f20a6d8b6721        13 days ago         105MB
mongo               latest              965553e202a4        2 weeks ago         363MB
centos              latest              9f38484d220f        8 months ago 

鏡像的構造與發布

鏡像倉庫里找不到全部的鏡像,這時我們需要為自己的業務去構建鏡像了。

-t 指定標簽

# -t node-base:10: 鏡像以及版本號
# .: 指當前路徑
$ docker build -t node-base:10 ./
#使用docker push將鏡像推送到鏡像倉庫
$ docker push node-base:10

Dockerfile

在使用docker部署自己應用時,往往需要自己構建鏡像。docker使用Dockerfile作為配置文件構建鏡像,簡單看一個node應用構建的dockerfile

FROM node:alpine

ADD package.json package-lock.json /code/
WORKDIR /code

RUN npm install --production
#.為當前文件目錄 /code為鏡像內的目錄
ADD . /code

CMD npm start 

FROM

基於一個舊的鏡像,格式如下

FROM <image> [AS <name>] 
# 在多階段構建時會用到 
FROM <image>[:<tag>] [AS <name>]

ADD

把目錄,或者 url 地址文件加入到鏡像的文件系統中

ADD [--chown=<user>:<group>] <src>... <dest>

RUN

執行命令,由於 ufs 的文件系統,它會在當前鏡像的頂層新增一層

RUN <command>

CMD

指定容器如何啟動

一個 Dockerfile 中只允許有一個 CMD

# exec form, this is the preferred form 
CMD ["executable","param1","param2"] 
# as default parameters to ENTRYPOINT 
CMD ["param1","param2"] 
# shell form 
CMD command param1 param2

容器

鏡像與容器的關系,類似於代碼與進程的關系。

  • docker run 創建容器
  • docker stop 停止容器
  • docker rm 刪除容器


創建容器

基於 nginx 鏡像創建一個最簡單的容器:啟動一個最簡單的 http 服務

使用 docker run 來啟動容器,docker ps 查看容器啟動狀態

$ docker run -d --name nginx -p 8888:80 nginx:alpine  
$ docker ps -l 
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                    NAMES 
404e88f0d90c        nginx:alpine         "nginx -g 'daemon of…" 4 minutes ago       Up 4 minutes        0.0.0.0:8888->80/tcp     nginx 
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                    NAMES

其中:

  • -d: 啟動一個 daemon 進程
  • --name: 為容器指定名稱
  • -p host-port:container-port: 宿主機與容器端口映射,方便容器對外提供服務
  • nginx:alpine: 基於該鏡像創建容器

此時在宿主機使用 curl 測試容器提供的服務是否正常

curl localhost:8888
會在下方打印出html代碼

使用docker exec -it container-name命令可以進入容器的環境中


容器管理

docker ps 列出所有容器

$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

404e88f0d90c        nginx:alpine         "nginx -g 'daemon of…" 4 minutes ago       Up 4 minutes        0.0.0.0:8888->80/tcp     nginx 
498e7d74fb4f        nginx:alpine         "nginx -g 'daemon of…" 7 minutes ago       Up 7 minutes        80/tcp                   lucid_mirzakhani 2ce
10556dc8f        redis:4.0.6-alpine   "docker-entrypoint.s…" 2 months ago        Up 2 months         0.0.0.0:6379->6379/tcp   apolloserverstarter_redis_1

docker port 查看容器端口映射

$ docker port nginx 80/tcp -> 0.0.0.0:8888

docker stats 查看容器資源占用

$ docker stats nginx CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS 
404e88f0d90c        nginx               0.00%               1.395MiB / 1.796GiB   0.08%               632B / 1.27kB       0B / 0B             2

Harbor

它的目標是幫助用戶迅速搭建一個企業級的 Docker registry 服務。它以 Docker 公司開源的 registry 為基礎,提供了管理UI,基於角色的訪問控制(Role Based Access Control),AD/LDAP集成、以及審計日志(Auditlogging) 等企業用戶需求的功能,同時還原生支持中文。Harbor 的每個組件都是以 Docker 容器的形式構建的,使用 Docker Compose 來對它進行部署。


Rancher

rancher 容器管理平台 在生產環境中輕松快捷的部署和管理容器 管理K8s 內置CI/CD 快速搭建 導入和納管 集中式身份。

准確的說,Rancher是一套容器管理打包方案,支持三種編排引擎:Kubernetes,Swarm,還有Rancher自己開發的Cattle(最近好像換成了Mesos)。從功能的完整性和易用性來看,Rancher甚至可以算得上一個商業軟件了,部署極其簡單,這也是我們選擇它作為入門級容器管理平台的原因。以下是Rancher的組件圖:

雖然Rancher非常的易用,但是rancher也不都是優點,隨着后端機器和項目數量的增加,它的一些問題也更易暴露,UI卡頓,發布速度越來越慢,1.3之后甚至經常出現服務的預期狀態(容器數量,版本)無法被保證,卡在發布中或者完成中狀態。團隊后續可能會考慮使用kubernetes。

基於GitLab的CI/CD

個人理解就是把代碼測試、打包、發布等工作交給一些工具來自動完成。這樣可以提高效率,減少失誤,開發人員只需要關心開發和提交代碼到git就可以了。

使用工具如gitlab-CI,這種方式的原理就是為項目在自己的服務器安裝上注冊gitlab-runner,注冊會有一個token,服務器上運行gitlab-runner后,runner會輪詢的發送帶tokenhttp請求給gitlab,如果gitlab有任務了,(一般是git push),那么會把任務信息返回給runner,然后runner就開始調用注冊時選的Executor(我是用的shell)來執行項目根目錄下的配置文件.gitlab-ci.yml,執行后把結果反饋給gitlab
詳細的工作原理請參考:

當談到 GitLab CI 的時候,我們該聊些什么(上篇)​www.upyun.com

對GitLab-CI,GitLab-Runner等概念不清楚,參考:

GitLab-CI與GitLab-Runner - CNundefined - 博客園​www.cnblogs.com圖標

開發環境要求

1、gitlab遠程倉庫

2、本地配置文件gitLab-ci.yml

stages:
  - test
  - build
  - push
  - deploy

variables:
 image:.......
.deploy_test_refs: &deploy_test_refs
  - development
  - test

.deploy_production_refs: &deploy_production_refs
  - master

# all_deploy_refs = deploy_test_refs + deploy_production_refs, but YAML cannot concat arrays
.all_deploy_refs: &all_deploy_refs
  - development
  - test
  - master

3、服務器上配置nginx、gitlab-runner(注冊runner,修改runner的權限)

sudo chown -R gitlab-runner:gitlab-runner /home/gitlab-runner
sudo chmod -R 777 /home/gitlab-runner

開啟runner

 gitlab-runner run

4、本地配置好node、git

配置成功展示界面:

參考文章:

前端項目基於GitLab-CI的持續集成/持續部署(CI/CD) - 掘金​juejin.im

使用Docker+Rancher(結合gitlab)+Harbor的具體流程

環境准備

1、macpro+多出來的服務器(沒有也可以)

2、docker 版本:18 (最新也成)

3、docker-compose:1.24 (最新也成)

4、Harbor:1.1.2(最新也行)

安裝docker

brew cask install docker

打開docker客戶端之后再item中輸入

docker login 域名

然后就可以在客戶端中輸入用戶名與密碼,由於作者使用公司的內網(不涉及業務內容),因此需要事先配置好推到harbor內的權限

處理過權限問題,之后的階段就可以進入相應的文件夾進行手動的配置,前提是要先寫好一個類似於build.sh的文件,內部配置好各種命令,build文件中的內容

function build() {
  echo "------------------------------ BUILD ------------------------------"

  (cd frontend && env COMMIT_ID=${COMMIT_ID} BUILD_TIME=${TIMESTAMP2} $(cat .env.${DEPLOY}) yarn build)

  rm -rf docker/frontend
  cp -r frontend/build docker/frontend

  # local IMAGES=`docker images -q -f 'dangling=true'`
  # [ "$IMAGES" != '' ] && docker rmi -f ${IMAGES}
  # local IMAGES=`docker images -q -f "label=app=${APP}"`
  # [ "$IMAGES" != '' ] && docker rmi -f ${IMAGES}

  docker build -t ${TAG} ${DOCKER_DIR}
}

function push() {
  echo "------------------------------ PUSH ------------------------------"

  docker push ${TAG}
  export SERVICE_NAME NAMESPACE IMAGE_URL
  envsubst <deploy/${APP}.tmpl || :
}

function all() {
  build
  push
}

function usage() {
  echo "Usage: $0 [build|push|all] [production|test]"
}

function main() {
  case ${CMD} in
  b*) build ;;
  p*) push ;;
  a*) all ;;
  *) usage ;;
  esac
}

init $@
main

配置好后且確保權限無誤即可執行:

./build.sh all test

配置執行后會直接push鏡像到harbor內(事先配置好)。

查看docker中的各種內容的命令:

docker ps

See 'docker --help'
MacBook-Pro:111$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

查看已經打出的鏡像

docker images

MacBook-Pro:111$ docker images
REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
registry.momenta.works/cla/milky-web   191202-test         1532be927f8d        5 hours ago         18.7MB
registry.momenta.works/cla/milky-web   191128-test         1af4615c4cb3        4 days ago          18.7MB
registry.momenta.works/cla/milky-web   191121-test         f6cb17d8b0a0        11 days ago         18.7MB
registry.momenta.works/cla/milky-web   191120-production   3e11cd30dd89        11 days ago         18.7MB
registry.momenta.works/cla/milky-web   191120-test         ee0909ecd9f7        11 days ago         18.7MB
registry.momenta.works/cla/milky-web   <none>              13993e12200a        12 days ago         18.7MB
registry.momenta.works/cla/milky-web   <none>              8de9f053335a        12 days ago         18.7MB
registry.momenta.works/cla/milky-web   <none>              7828f22eb355        12 days ago         18.7MB
registry.momenta.works/cla/milky-web   <none>              c23b51230cad        12 days ago         18.7MB
registry.momenta.works/cla/milky-web   <none>              f5169dc0f863        12 days ago         18.7MB
registry.momenta.works/cla/milky-web   <none>              eb5463875800        12 days ago         18.7MB
registry.momenta.works/cla/milky-web   <none>              618d7f09c2f6        12 days ago         18.7MB
registry.momenta.works/cla/milky-web   <none>              b682475e4d9b        12 days ago         18.7MB
registry.momenta.works/cla/milky-web   <none>              85420f94ff4c        12 days ago         18.7MB
registry.momenta.works/cla/milky-web   <none>              972cc2cc9c7c        12 days ago         18.7MB
registry.momenta.works/cla/milky-web   <none>              08098283428a        12 days ago         18.7MB
registry.momenta.works/cla/milky-web   191119-test         bdc5d28d724f        12 days ago         18.7MB
registry.momenta.works/cla/milky-web   191118-test         3aca38625579        13 days ago         18.7MB
registry.momenta.works/cla/milky-web   <none>              5b4dcdc14def        13 days ago         18.7MB
registry.momenta.works/cla/milky-web   <none>              f40db7e196fb        2 weeks ago         18.7MB
registry.momenta.works/cla/milky-web   <none>              ff2c5da90a90        2 weeks ago         18.7MB
registry.momenta.works/cla/milky-web   191116-test         c2e20e00fa04        2 weeks ago         18.7MB
registry.momenta.works/cla/milky-web   191115-test         2d0ebce7a82c        2 weeks ago         18.7MB
nginx                                  1.15-alpine         dd025cdfe837        6 months ago        16.1MB

將打好的鏡像上傳到相對應的harbor倉庫中:

docker push registry.momenta.works/cla/milky-web:-test

在rancher中對相應的服務(微服務)edit相應的鏡像地址即可

以上是權限沒有配置好情況下的操作

假如說我們的權限配置沒有問題了,直接執行build.sh即可(省略中間步驟),最后在rancher中edit相應的鏡像即可

 

未完待續(harbor與rancher的使用及配置會在近期附上)

Happy Hacking


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM