部署基于Gitlab+Docker+Rancher+Harbor的前端项目这一篇就够了
部署基于Gitlab+Docker+Rancher+Harbor的前端项目这一篇就够了

就目前的形势看,一家公司的运维体系不承载在 Docker+Harbor(或 Pouch 等同类平台)之上都不好意思说自己的互联网公司。当然这些技术也不适用于全部公司,技术在迭代,平台也一样,把我使用的工具和大家分享下,一起成长(文章中扩展可按需Google)。
Docker
docker的架构图如下:

从图中可以看出几个组成部分
docker client: 即docker命令行工具docker host: 宿主机,docker daemon的运行环境服务器docker daemon:docker的守护进程,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 有 https://hub.docker.com/ 、 https://cr.console.aliyun.com/ 等。
底层原理
docker 底层使用了一些 linux 内核的特性,大概有 namespace,cgroups 和 ufs
namespace
docker 使用 linux namespace 构建隔离的环境,它由以下 namespace 组成
pid: 隔离进程net: 隔离网络ipc: 隔离 IPCmnt: 隔离文件系统挂载uts: 隔离hostnameuser: 隔离uid/gid
control groups
也叫 cgroups,限制资源配额,比如某个容器只能使用 100M 内存
Union file systems
UnionFS 是一种分层、轻量级并且高性能的文件系统,支持对文件系统的修改作为一次提交来一层层的叠加。docker 的镜像与容器就是分层存储,可用的存储引擎有 aufs,overlay 等。
镜像
镜像是一份用来创造容器的配置文件,而容器可以视作最小型的一个操作系统(类似于容器由镜像解压而来)。
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会轮询的发送带token的http请求给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
部署基于Gitlab+Docker+Rancher+Harbor的前端项目这一篇就够了的更多相关文章
- 关于 Docker 镜像的操作,看完这篇就够啦 !(下)
紧接着上篇<关于 Docker 镜像的操作,看完这篇就够啦 !(上)>,奉上下篇 !!! 镜像作为 Docker 三大核心概念中最重要的一个关键词,它有很多操作,是您想学习容器技术不得不掌 ...
- node项目自动化部署--基于Jenkins,Docker,Github(1)安装Jenkins
前言 每次项目代码更新后都要重新部署,如果只有一台服务器还好. 但是如果是分布式系统,动不动就很多台服务器,所以代码的自动部署就显得十分重要了. 这里用几篇文章来记录一下如何使用Jenkins,Doc ...
- 一键部署基于GitLab的自托管Git项目仓库
https://market.azure.cn/Vhd/Show?vhdId=9851&version=11921 产品详情 产品介绍GitLab https://about.gitlab.c ...
- node项目自动化部署--基于Jenkins,Docker,Github(3)自动化部署
GitHub仓库 由于现在的代码基本上都是多人合作开发,所以肯定会用到像 git 这样的版本控制工具 所以这里使用 GitHub 来做一个演示 首先我们需要在github上新建一个仓库 点击New来新 ...
- node项目自动化部署--基于Jenkins,Docker,Github(2)配置节点
上一篇文章中准备工作已经完成的差不多了 这一篇主要讲解 Jenkins 上面的相关配置 为了让代码部署到所有的子节点上 所以我们首先需要在 Jenkins 中添加我们希望代码部署到的节点 配置节点 首 ...
- 使用docker+jenkins构建nodejs前端项目
前文使用Docker搭建Jenkins+Docker持续集成环境我们已经搭建了基于docker+jenkins的持续集成环境,并构建了基于maven的项目.这一节,我们继续扩展功能,增加对Nodejs ...
- Docker+Jenkins持续集成环境(2)使用docker+jenkins构建nodejs前端项目
前文使用Docker搭建Jenkins+Docker持续集成环境我们已经搭建了基于docker+jenkins的持续集成环境,并构建了基于maven的项目.这一节,我们继续扩展功能,增加对Nodejs ...
- 在已部署好的docker环境下配置nginx项目路径
第一步:申请一个docker连接账号,可以借用putty工具,如果使用sublime,可以下载sftp插件,上传.下载来同步你线上线下的文件: 第二步:修改nginx区域配置文件,在conf文件夹里放 ...
- 基于vue cli 3.0创建前端项目并安装cube-ui
前提条件: 安装node.js. 国内的开发者最好先配置淘宝镜像. 之后用cnpm来代替npm命令. 项目创建过程: 打开cmd,输入命令进入目标工作空间,以本机项目为例: cd /d d: cd D ...
随机推荐
- QDialog
QDialog设置setWindowFlags(Qt::FramelessWindowHint);后,dialog弹不出来,界面不显示: 在继承一个QDialog类并设置窗口为无边框时,如果调用set ...
- HanLP《自然语言处理入门》笔记--3.二元语法与中文分词
笔记转载于GitHub项目:https://github.com/NLP-LOVE/Introduction-NLP 3. 二元语法与中文分词 上一章中我们实现了块儿不准的词典分词,词典分词无法消歧. ...
- Shell常用命令之read
前言 Linux read命令用于从标准输入读取数值.read 内部命令被用来从标准输入读取单行数据.这个命令可以用来读取键盘输入,当使用重定向的时候,可以读取文件中的一行数据. 格式 read [- ...
- 深入理解Java虚拟机内存模型
前言 本文中部分内容引用至<深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)>第12章,如果有兴趣可自行深入阅读,文末放有书籍PDF版本连接. 一.物理机中的并发 物理机遇到的并 ...
- 【大白话系列】MySQL 学习总结 之 初步了解 MySQL 的架构设计
一.MySQL还是个黑盒子 我们都知道,只要我们系统引入了 MySQL 驱动和连接池,就能从数据库连接池获取一个数据库连接,然后就可以执行增删改查的操作了. 可是我们并不知道 MySQL 里面是怎么执 ...
- mysql+jpa简单实现步骤
首先,我们用的开发工具是IDEA,数据库是mysql,以下是步骤: 1.我们需要在pom.xml加入mysql和jpa的依赖 <!-- 依赖的数据库,使用jpa --> <depen ...
- python day01练习和作业
习题:1.简述编译型与解释型语言的区别,且分别列出你知道的哪些语言属于编译型,哪些属于解释型编译型语言:优点:执行速度快 缺点:维护成本高,跨平台性差解释型语言:优点:维护成本低,跨平台性好 缺点:执 ...
- python UnicodeDecodeError: 'gbk' codec can't decode byte 0x99 in position 87: illegal multibyte sequence异常解决
我们处理文本文件时,经常会遇到这样的报错: UnicodeDecodeError: 'gbk' codec can't decode byte 0x99 in position 87: illegal ...
- 小程序图片 mode 设置为 widthFix 图片显示瞬间竖向拉伸变形闪烁
官方文档中 mode="widthFix" 宽度不变,高度自动变化,保持原图宽高比不变,即设置图片宽度而高度自适应. 但是在实际开发中发现图片在初始加载时瞬间竖向拉伸变形闪烁然 ...
- JAVA编程学习之JAVA集合
一.JAVA集合类 为了保存数量不确定的数据,以及保存具有映射关系的数据(关联数组),java提供了集合类.所有集合类位于java.util包下. 集合类就像容是器,现实生活中容器的功能,无非就是添加 ...
