docker build -t_利用Docker完成CI/CD流程

涉及知识:

  • Docker、Dockerfile、Docker-compose
  • Git、Gitlab-ci

本文记录了:

  • 使用 Docker 安装 Gitlab-runner
  • 使用 Docker 作为 Gitlab-runner 的执行器
  • 使用 Dockerfile 编译生成镜像
  • Gitlab-ci 文件的编写
  • 将应用部署到服务器

安装Gitlab-runner

应为我们使用的是Docker来完成CI/CD的操作,所以需要提前准备安装好Docker。

利用dokcer安装Gitlab-runner只需要执行:

docker run -d --name gitlab-runner --restart always 
  -v /srv/gitlab-runner/config:/etc/gitlab-runner 
  -v /var/run/docker.sock:/var/run/docker.sock 
  gitlab/gitlab-runner:latest

我们来看下,在这个命令里面挂载了两个东西,第一个是gitlab-runner的配置文件、第二个是为了让runner里面可以执行宿主机的docker。

现在runner已经通过docker在运行了,接下来需要执行注册流程,将runner注册到Gitlab中:

docker exec -it gitlab-runner gitlab-ci-multi-runner register

这里就需要进入自己的gitlab仓库中的CI/CD设置里面。复制下自己仓库URL以及runner的token

3e5716b637dfec7f789ddba98df5641d.png
Runtime platform                                    arch=amd64 os=linux pid=19 revision=a998cacd version=13.2.2
Running in system-mode.

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
https://co*******com/
Please enter the gitlab-ci token for this runner:
bT*********ZcmD
Please enter the gitlab-ci description for this runner:
[b5f641f7df47]: runner
Please enter the gitlab-ci tags for this runner (comma separated):
prod
Registering runner... succeeded                     runner=bTYwz7Zf
Please enter the executor: custom, docker, parallels, ssh, docker-ssh, shell, virtualbox, docker+machine, docker-ssh+machine, kubernetes:
docker
Please enter the default Docker image (e.g. ruby:2.6):
ccchieh/centos-common
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

注意在Please enter the executor中选择执行器为docker,然后选择默认的docker镜像,这里我用的是自己制作的基于centos的镜像,只是在官方的centos镜像基础上安装了openssh、git、nano,如果有其他需要的话也可以自己制作。

接下来需要编辑下我们的配置文件,因为我们吧配置文件挂载到宿主机了,所以我们只需要编辑宿主机的文件:

vim /srv/gitlab-runner/config/config.toml

这里先贴出我的配置

concurrent = 10
[[runners]]
  name = "s****an"
  url = "https://co*******m/"
  token = "m********JFMHxD"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
  [runners.docker]
    tls_verify = false
    image = "ccchieh/centos-common"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock", "/usr/bin/docker:/usr/bin/docker", "/data/.m2:/root/.m2", "/root/.ssh:/root/.ssh", "/root/.docker/:/root/.docker/"]
    pull_policy = "if-not-present"
    shm_size = 0

这里修改的主要是concurrentvolumespull_policy

concurrent 表示这个runner可以并行执行多少任务,比较常见的就是同时提交多次任务时runner可以并行执行,或者在一次管道作业中同一个stage的任务可以并行完成,比如在图中的Build阶段,同时打包了4个子模块,在四个子模块中都会先下载依赖,这时如果最大并发数设置为默认1的时候会把花费很多时间,如果并发数大于4,那么Build阶段就可以并发完成。

0de5537172c393a29ba56d0fb1334a08.png

volumes则是挂载的目录,就是docker run 的时候用的 -v 挂载的目录,应为我们后面需要编译Dockerfile,所以将docker的相关目录文件挂载上去,然后挂载下maven仓库(这里是直接挂载了,实际使用的时候也可以利用gitlab-ci文件里面的cache进行缓存)避免每次打包编译java项目的时候都要下载一次依赖(这里是针对maven的,其他依赖管理软件视情况而定)。最后我这里直接把宿主机的.ssh也挂载上去了,是为了后面可以操作远程部署的服务器,因为我这里都是内网机器,所以安全性暂时不考虑,这里再实际应用中请注意下,避免不必要的风险。

pull_policy则是表示只有当本地没镜像的时候才拉取镜像,避免每次都重新拉取镜像。

Dockerfile 编译生成镜像

对于每个项目我们都需要编写一个Dockerfile用于实现对项目的编译打包,这里我们以前端的项目为例简介的介绍下,首先来看下Dokcerfile文件:

# build stage
FROM node:12.14.0 as builder
COPY . /usr/src/app
WORKDIR /usr/src/app
RUN npm config set registry https://registry.npm.taobao.org 
    && npm install 
    && npm run build

# production stage
FROM nginx:1.19-alpine as prod
COPY --from=builder /usr/src/app/dist/spa /usr/share/nginx/html
COPY --from=builder /usr/src/app/nginx.conf /etc/nginx/conf.d

我们使用Dockerfile的多阶段构建的方式,再第一个build阶段使用node镜像编译打包前端项目,然后第二阶段中把第一编译好的文件移动到nginx镜像中,同时把我们自定义的nginx配置也复制过去。

编写gitlab-ci.yml

在gitlab-ci.yml中是支持变量的,这样我们可以把如主机ip等敏感信息设置为变量,防止信息泄露。

94e08d66abafb7a8a20a70cb8ded25d3.png

以我这里为例分别设置了容器名称、镜像私有仓库地址、部署服务器地址(如root@202.1.1.1)、服务器中的docker-compose的文件路径。

然后我们的gitlab-ci.yml:

cache:
  untracked: true
  key: $CONT_NAME
  paths:
    - node_modules/
    - dist/

stages:
  - build
  - deploy
  - cleanup

build: # 编译阶段
  stage: build
  only:
    - prod # 只有prod更新的时候才执行命令
  tags:
    - ***
  script:
    - docker build -t $IMAGE_PROD .
    - docker push $IMAGE_PROD

deploy: # 部署阶段
  stage: deploy
  only:
    - prod
  tags:
    - ***
  script:
    - ssh $SERVER_ADDR docker-compose -f ${SERVER_PATH}/docker-compose.yml up -d
    - ssh $SERVER_ADDR docker-compose -f ${SERVER_PATH}/docker-compose.yml stop $CONT_NAME
    - ssh $SERVER_ADDR docker-compose -f ${SERVER_PATH}/docker-compose.yml pull $CONT_NAME
    - ssh $SERVER_ADDR docker-compose -f ${SERVER_PATH}/docker-compose.yml up -d --build $CONT_NAME

cleanup: # 清理作业
  stage: cleanup
  only:
    - prod
  tags:
    - ***
  script:
    - echo "回收垃圾"
  when: always

上面cache我们设置缓存,之后分为三阶段(build、deploy、cleanup),而且我们通过only关键字设置只有在prod分支下的代码更新了才进入管道。

大致流程还是比较简单的,但是实际操作的时候还是有许多坑需要慢慢踩。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值