部署基于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

原文地址:https://www.cnblogs.com/fqnb001/p/12369352.html