使用jenkins和gitlab-runner DevOps CICD - 制作docker镜像并推送到阿里云镜像仓库

前言

DevOps( Development和Operations的组合词 )的概念在软件开发行业中逐渐流行起来。越来越多的团队希望实现产品的敏捷开发,DevOps 使一切成为可能。有了 DevOps,团队可以定期发布代码、自动化部署、并将持续集成( CI ) / 持续交付( CD )作为发布过程的一部分。说到 CICD 比较出名的有 jenkins 和 gitlab-runner 、circle.ci 和travis.ci等等,大家可以自行百度或者找相关文章看看这几个的区别,这里就不详细讲了。

本文将介绍大家如何安装和使用 jenkins 和 gitlab-runner 以及使用 CICD 将前端项目制作成 docker 镜像并推送到阿里云镜像仓库。

准备

首先我们要准备两台机器,可以是虚拟机或者云服务器,我选用的是阿里云 ECS Centos 7 分别来要安装 gitlab 和 jenkins + gitlab-runner,也就是说机器A安装 gitlab,机器B安装 jenkins 和 gitlab-runner。

  • 机器 A 安装 gitlab
  • 机器 B 安装 jenkins 和 gitlab-runner
  • 机器 A 和 B 都安装 jdk、maven 和 docker
  • 在机器A gitlab 上面创建项目

注意:我这里是把jenkins 和 gitlab-runner 安装在同一台机器上

安装 gitlab

之前我已经写过一篇关于如何安装gitlab,这里就不详细说了,大家可以查看这篇文章上面讲的也很详细。注意这篇文章已经教你如何生成你的SSH私钥和公钥了,后面会用到

安装 jenkins

同样的我之前也写过一篇文章关于如何安装jenkins,这里也不详细说了,大家可以查看这篇文章上面讲的也很详细。
注意:这篇文章已经教你如何安装 jdk、maven 和 docker 后面就不做介绍了

安装 gitlab-runner

这里详细讲下如何安装gitlab-runner,我们先去查看官网,上面有介绍如何安装。

# For RHEL/CentOS/Fedora
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash

# For RHEL/CentOS/Fedora
sudo yum install gitlab-runner

安装 jdk、maven和docker

略!

在 gitlab 上面创建项目

这里我们会新建一个前端项目,根据自己熟悉的框架可以使用react、angular或vue来创建项目,我这里使用的是umi来创建项目,创建好之后如下图所示。
使用jenkins和gitlab-runner DevOps CICD - 制作docker镜像并推送到阿里云镜像仓库_第1张图片

编写Dockerfile

不管是jenkins还是gitlab-runner使用的都是同一份Dockerfile文件,下面就是制作前端项目成docker镜像的Dockerfile文件。

FROM node:12

# 设置工作路径。所有的路径都会关联WORKDIR
WORKDIR /usr/src/app

# 安装依赖
COPY package*.json ./
RUN npm install

# 拷贝源文件
COPY . .

# 构建应用
RUN npm run build

# 运行应用
CMD [ "npm", "start" ]

使用jenkins

  1. 新建jenkins任务
  2. 配置jenkins任务

    1. 源码管理
    2. 构建触发器
    3. 构建
    4. 保存
  3. 项目代码添加 tag 并提交,自动触发 jenkins 并构建

新建jenkins任务

点击新建任务,输入任务名称,选择 构建一个自由风格的软件项目 点击确定即可,如图所示

使用jenkins和gitlab-runner DevOps CICD - 制作docker镜像并推送到阿里云镜像仓库_第2张图片

配置jenkins任务

源码管理

源码管理一栏中选择git,在Repository URL中输入上面你新建项目的 git 地址,因为没有配置私钥所以会报红,接下来我们来配置这个私钥,点击添加->jenkins然后弹出一个配置私钥的对话框,类型选择SSH Username with private key,然后就可以在Username输入你的用户名,在 Private Key 选择Enter directly再点击Add把你的私钥放进去即可。
使用jenkins和gitlab-runner DevOps CICD - 制作docker镜像并推送到阿里云镜像仓库_第3张图片

构建触发器

在构建触发器一栏,选择Build when a change is pushed to GitLab. GitLab webhook URL会发现自动生成了webhook的地址,这个地址后面会用到,然后我们选择 push event,然后点击高级选择Secret token,这样就生成了Secret token,这样webhook的地址和token都生成了。

使用jenkins和gitlab-runner DevOps CICD - 制作docker镜像并推送到阿里云镜像仓库_第4张图片

然后我们到gitlab上面打开前端项目选择Setting->Integrations,把刚才生成好的url和token输入进去,接着取消选择Push events,并选择Tag push events点击Add webhook即可,这样你的jenkins就关联到你这个项目上,后面只要提交tag就会自动触发构建了。
使用jenkins和gitlab-runner DevOps CICD - 制作docker镜像并推送到阿里云镜像仓库_第5张图片

构建

在构建一栏,点击下拉 增加构建步骤 选择执行shell,然后我们在这个shell输入框里面输入如下代码:
使用jenkins和gitlab-runner DevOps CICD - 制作docker镜像并推送到阿里云镜像仓库_第6张图片

# 定义变量,CONTAINER_NAME 是项目名称,对应阿里云镜像服务中的仓库名称
CONTAINER_NAME="your-repository-name"

# GIT_TAG 变量是自动获取本地git版本的tag
# 注意git添加tag时一定要带-m,如:git tag v1.0 -m 'commit tag'否则下面的命令始终获取不到最新的tag
GIT_TAG=`git describe --always --tag`

CONTAINER_FULL_NAME=${CONTAINER_NAME}-${GIT_TAG}

REPOSITORY=registry.cn-hangzhou.aliyuncs.com/your-namespace/${CONTAINER_NAME}:${GIT_TAG}

# 构建Docker镜像
docker build -t $REPOSITORY -f Dockerfile .

# 推送Docker镜像,username 跟 password 为 阿里云容器镜像服务的账号密码
docker login -u username -p password registry.cn-hangzhou.aliyuncs.com

# 开始推送镜像
docker push $REPOSITORY

# 删除生成的image
docker images | grep $CONTAINER_NAME | awk '{print $3}' | xargs docker rmi -f

# 删除名称或标签为none的镜像
# docker rmi -f  `docker images | grep '' | awk '{print $3}'`

输入完成之后点击保存即可。

使用jenkins和gitlab-runner DevOps CICD - 制作docker镜像并推送到阿里云镜像仓库_第7张图片

项目代码添加 tag 并提交,自动触发 jenkins 并构建

现在你在你的代码中添加一个tag并提交到gitlab上面,你会发现jenkins正在构建,并推送到阿里云镜像仓库。

git tag v1.0 -m 'commit tag v1.0'
git push origin v1.0

使用jenkins和gitlab-runner DevOps CICD - 制作docker镜像并推送到阿里云镜像仓库_第8张图片

使用gitlab-runner

gitlab-runner 比jenkins 的优势在于它和 GitLab 整合的非常好,而且省略了好多配置工作,GitLab CI 使用 YAML(.gitlab-ci.yml)进行项目配置,位于项目的根目录中。这里有一篇详细讲解.gitlab-ci.yml语法的文章,大家可以看看。

  1. gitlab-runner register
  2. 制作 .gitlab-ci.yml 文件
  3. 修改项目代码并提交到gitlab,自动触发 gitlab-runner 并构建

gitlab-runner register

首先我们进入到我们安装的gitlab-runner服务器B中,然后我们使用下面命令进行register:

# sudo gitlab-runner register

回车之后,会要求你输入下面的内容:

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):

Please enter the gitlab-ci token for this runner:

这个时候要求你输入gitlab地址以及registration token,我们打开我们的项目选择Setting->CI/CD->Runners->Specific Runners->Set up a specific Runner manually,在Set up a specific Runner manually里会有你的gitlab地址和register token,复制过来粘贴即可。

使用jenkins和gitlab-runner DevOps CICD - 制作docker镜像并推送到阿里云镜像仓库_第9张图片

回车之后,要求你输入一段描述:

Please enter the gitlab-ci description for this runner:
[xx-xx]:

输入完成回车,接着要求你输入tag:

Please enter the gitlab-ci tags for this runner (comma separated):

输入完成回车,接着要求你输入运行.gitlab-runner.yml的方式:

Please enter the executor: custom, shell, virtualbox, docker+machine, kubernetes, docker, docker-ssh, parallels, ssh, docker-ssh+machine: 
shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

注意这里我们输入的是shell并且提示你注册成功,这样就完成了register,这个时候再到页面上面查看是否已经注册成功

完整的register过程:

# sudo gitlab-runner register

Runtime platform                                    arch=amd64 os=linux pid=14320 revision=21cb397c version=13.0.1
Running in system-mode.

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):

Please enter the gitlab-ci token for this runner:

Please enter the gitlab-ci description for this runner:
[xx-xx]:

Please enter the gitlab-ci tags for this runner (comma separated):

Registering runner... succeeded                     runner=x_xxx

Please enter the executor: custom, shell, virtualbox, docker+machine, kubernetes, docker, docker-ssh, parallels, ssh, docker-ssh+machine:

Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

制作 .gitlab-ci.yml

现在我们开始制作.gitlab-ci.yml,我们这里主要分为两步build和test

stages:
  - build
  - test

variables:
  # CI_PIPELINE_ID 是gitlab自带的全局变量,直接使用
  REPOSITORY: $REGISTRY_DOCKER_RES:$CI_PIPELINE_ID

before_script:
  - echo "开始构建 build"
  - echo $CI_PIPELINE_ID

build_job:
  stage: build
  script:
    # 构建Docker镜像
    - docker build -t $REPOSITORY -f Dockerfile .
    # 推送Docker镜像,username 跟 password 为 阿里云容器镜像服务的账号密码
    - docker login -u $REGISTRY_USERNAME -p $REGISTRY_PASSWORD $REGISTRY_DOMAIN
    # 开始推送镜像
    - docker push $REPOSITORY
    # 删除生成的image
    - docker images | grep awbeci | awk '{print $3}' | xargs docker rmi -f

  tags:
    - awbeci-web-devops
  only:
    - master

test_job:
  stage: test
  script:
    - echo "开始构建 test"
  tags:
    - awbeci-web-devops
  only:
    - master

这样就完成了.gitlab-ci.yml的制作,大家可以对比下和jenkins里面的配置。

注意:

  1. 上面CI_PIPELINE_ID变量是gitlab自带的,还有好多的通用全局变量可以使用,详细请看
  2. REGISTRY_DOCKER_RES、REGISTRY_USERNAME、REGISTRY_PASSWORD、REGISTRY_DOMAIN变量是在gitlab项目中 Variables 配置好的,如图所示

使用jenkins和gitlab-runner DevOps CICD - 制作docker镜像并推送到阿里云镜像仓库_第10张图片

修改项目代码并提交到gitlab,自动触发 gitlab-runner 并构建

现在你可以修改你的代码并提交到gitlab上面,你会发现gitlab-runner正在构建,并推送到阿里云镜像仓库。

git add .
git commit -am 'update'
git push origin master

使用jenkins和gitlab-runner DevOps CICD - 制作docker镜像并推送到阿里云镜像仓库_第11张图片

问题

  • docker权限问题
    将jenkins和gitlab-runenr用户添加到docker组里面
sudo gpasswd -a jenkins docker
sudo gpasswd -a gitlab-runner docker
  • git添加tag一定要带-m
git tag tag-name -m 'commit tag'

总结

1、后面会出docker镜像结合k8s部署的文章;
2、jenkins需要设置webhooks而gitlab-runner不需要;
3、gitlab-runner跟gitlab整合的非常好;
4、现在jenkins和gitlab-runner安装在机器B上面可以切换着使用。

参考

docker + gitlab + jenkins 搭建 CI/CD 系统
List all environment variables
使用GitLab CI在Kubernetes服务上运行GitLab Runner并执行Pipeline
Gitlab CI 使用高级技巧
前端gitlab-ci实现自动化部署
前端的gitlab的ci初尝试
基于 GitLab CI/CD 的前端自动化构建、发布实践
JB的测试之旅-利用jenkins达到提tag自动打包
在docker上开发一个简单的React(next.js)应用
搭建GitLab+Jenkins持续集成环境图文教程
Gitlab CI在前端CI/CD中的运用
Node项目的Gitlab自动部署实践(基于Docker)
阿里云镜像服务+gitlab自动化构建镜像
使用GitLab CI和Docker进行容器应用自动化部署
使用GitLab构建Docker镜像并托管
Jenkins自动化构建vue项目然后发布到远程服务器
Jenkins自动构建部署maven项目到远程服务器上
使用GitLab CI/CD进行自动测试和部署
GitLab持续集成持续部署(CI&CD)
gitlab CI/CD 将react、vue项目打包成Docker镜像
gitlab runner安装与使用
基于 Docker 和 GitLab 的前端自动化部署
gitlab + gitlab-runner 集成 CICD

你可能感兴趣的:(jenkins,devops,docker)