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

  • 相关阅读:
    php 网络图片转base64
    uniapp微信小程序拒绝授权后,重新调起授权页
    uniapp获取用户信息 getuserinfo
    基于JSP和Mybatis框架技术的应用总结
    Java第16周作业集
    Java第15周作业集
    Java第14周作业集
    Java第13周作业集
    软件工程结课作业
    Java第13次作业--邮箱的正则表达式
  • 原文地址:https://www.cnblogs.com/fqnb001/p/12369352.html
Copyright © 2020-2023  润新知