Realize Dockerlized CI CT And CD by GitLab

1 概述

1.1 简介

本文档描述一简单应用场景,利用gitlab与docker技术实现从版本管理,持续集成(CI),持续测试(CT)到最终持续部署(CD)的完整过程。重点在于上述知识点的实现方法,鉴于部门内部 asp.net core技术栈的同事较多,因此采用 asp.net core的一极简Hello World工程作为例子,实际上与具体编程语言无关。

1.2 名词解释

名词 解释
Git Git(读音为/gɪt/)是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。
Gitlab GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务。
Docker Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,
然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
CI Continuous integration的缩写,持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,
通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。
每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。
CT Continuous testing的缩写,持续测试是一个过程,它将自动化测试作为软件交付通道中内嵌的一部分,
以尽快获得软件发布后业务风险的反馈。
CD Continuous Deploy的缩写,持续部署是自动地将每一次成功的构建直接部署到生产环境中。
Asp.net Core ASP.NET Core 是一个免费且开放源代码的Web框架,以及由微软和社区开发的下一代 ASP.NET。它是一个模块化框架,
既可以Windows上的完整 .NET Framework上运行,也可以在跨平台 .NET Core上运行。

1.3 知识基础

因使用Gitlab与docker作为实现工具,需要阅读者掌握git与docker的基础知识以及yaml基础语法知识。本文涵盖的大致知识点如下

1.3.1 git 部分

  • git 基本概念 工作区(working directory) 暂存区(stage) 版本库(commit history)
  • git 基本命令 clone add commit reset push branch merge stash

1.3.2 docker 部分

  • 镜像
  • 容器
  • 仓库
  • 制作自己的镜像(DockerFile)
  • 单节点编排工具(docker-compose) --- 只做简要介绍

1.3.3 gitlab 部分

  • 注册
  • 生成密钥
  • 申请与审核分支合并

1.3.4 持续集成,测试与发布

  • Gitlab-Runner
  • .gitlab-ci.yml

1.3 实验环境介绍

两台服务器,一台运行gitlab,一台安装好docker服务。gitlab服务器负责版本管理,docker服务器负责持续集成,持续测试和持续发布。服务器信息:

name ip service
bmtscc1 10.0.31.13 Docker,GitLab-Runner
bmtscc2 10.0.31.14 Gitlab

2 git

2.1 安装

2.1.1 Windows

  • Git for Windows : https://gitforwindows.org/
  • TortoiseGit : https://tortoisegit.org/

2.1.2 Linux

  • Debian,Ubuntu系列
$ sudo apt-get install git
  • RHEL,CentOS系列
$ sudo yum install git
  • 源码安装
    下载源代码:https://github.com/git/git
$ cd git
$ ./configure && make
$ sudo make install

2.1.3 设置全局参数

git config --global user.name '姓名'
git config --global user.email '[email protected]'
git config --global core.safecrlf false # 此处是为了防止回车符被转换造成乱码的问题

2.2 与cvs和svn的最大区别

git具有本地版本管理的功能,无需中心服务器,群组开发场景中才需要用到中心版本服务器。中心服务器与每个用户的主机上都有一个git版本库,通常情况下用户主机的主(master)分支对应服务器中的某个分支。

2.3 git的基础概念

2.3.1 git的四个区

与cvs和svn的不同,git是多了暂存区,一个git库中有下述三个区

  • 工作区(Working Area):用户的工作目录,当前正在使用的目录结构和所有文件都处在工作区
  • 暂存区(stage):版本库追踪的文件被修改后,不是直接提交到本地版本库,而是需要先添加到暂存区,再由暂存区提交至版本库。这样做的好处是当同一文件多次修改时可分段提交,尽可能缩小提交粒度。
  • 本地仓库(Local Repository):存放已经提交的数据,push到中心版本服务器的时候,本地库的所有版本均被推送。
  • 远程仓库(Remote repository):中心版本库

2.3.2 文件的五种状态

  • 未修改(Origin)
  • 已修改(Modified)&未追踪(Untracked)
  • 已暂存(Staged)
  • 已提交(Committed)
  • 已推送(Pushed)

2.4 一般操作顺序

  • 第零步:工作区与仓库保持一致,所有文件均为未修改状态
$ git clone ssh://[email protected]:220/study/asp.net.demo
$ git pull origin master:master
  • 第一步:文件增删改,变为已修改状态
  • 第二步:git add ,变为已暂存状态
$ git add --all # 当前项目下的所有更改
$ git add .  # 当前目录下的所有更改
$ git add xx/xx.xxx xx/xx2.xxx  # 添加某几个文件
  • 第三步:git commit,变为已提交状态
$ git commit -m"<这里写commit的描述>"
  • 第四步:git push,变为已推送状态
$ git push -u origin master # 第一次需要关联上
$ git push # 之后再推送就不用指明应该推送的远程分支了
$ git branch # 可以查看本地仓库的分支
$ git branch -a # 可以查看本地仓库和本地远程仓库(远程仓库的本地镜像)的所有分支

2.5 提交与撤销示意图

2.5.1 代码提交流程

sequenceDiagram

participant 工作区
participant 暂存区
participant 本地仓库
participant 本地远程仓库
participant 远程仓库

工作区->>暂存区:git add
暂存区->>本地仓库:git commit
本地仓库->>远程仓库:git push
远程仓库-->>本地远程仓库:git fetch
本地远程仓库-->>工作区:git merge
远程仓库-->>工作区:git pull

: 本地远程仓库相当于是远程仓库在本地的镜像,每次pull/fetch都将与远程保持同步

2.5.2 五种状态撤销更改

sequenceDiagram
participant 未修改
participant 已修改
participant 已暂存
participant 已提交
participant 已推送

note over 未修改, 已修改:工作区
note over 已暂存: 暂存区
note over 已提交: 本地仓库
note over 已推送: 远程仓库

未修改-->>已修改:增删改
已修改-->>已暂存:add
已暂存-->>已提交:commit
已提交-->>已推送:push

已推送->>已提交:git push -f
已暂存->>已修改:git reset
已修改->>未修改:git checkout(撤销改/删)
已修改->>未修改:git clean(撤销增)
已暂存->>未修改:git reset --hard
已提交->>已修改:git reset
已提交->>未修改:git reset --hard

: 除了未修改以外,还有未追踪(untracted)状态,即该文件是新增的,从未添加至git库,撤销用git clean

3 gitlab使用基础

3.1 gitlab简介

GitLab是由GitLabInc.开发,使用MIT许可证的基于网络的Git仓库管理工具,且具有wiki和issue跟踪功能。使用Git作为代码管理工具,并在此基础上搭建起来的web服务。

3.2 用户配置

3.2.1 注册用户

bmtscc2:http://10.0.31.14:800
注意:在注册信息的email栏中尽量填写公司邮箱,后面讲到的编译、测试和发布信息会推送至这里填写的邮箱中。

3.2.2 生成用户密钥

在Windows命令窗口或Linux终端中执行如下命令:

ssh-keygen -t rsa -C "[email protected]"

上述命令会在用户目录的.ssh目录中生成id_rsa和id_rsa.pub文件,即私钥与公钥文件。
注意:在执行过程中会先后出现需要用户输入的步骤,若对ssh不是很熟悉的用户建议直接按回车键使用默认值即可。当用户此时输入了如保存文件名称信息且与ssh客户端默认值不同,则需要修改.ssh/config文件中的相应配置项。

3.2.3 上传公钥

  • 登陆后单击右上角用户图标,在下拉菜单中点击设置菜单项
  • 在位于左侧的用户设置侧边栏中点击SSH密钥菜单后,在右侧密钥输入栏中粘贴id_rsa.pub文件所有内容
  • 单击下方增加密钥按钮
  • 上传完成后可在用户的计算机中使用如下命令测试是否成功
ssh -T [email protected] -p 220 #公司办公网
  • 若显示类似如下欢迎信息则代表成功
Welcome to GitLab, {UserName}!

3.3 在gitlab上创建工程

网页操作:

  • 创建群组并添加用户
  • 在群组中新建项目

3.4 在本地库新建工程与本地版本库

本文档以一简单的 Asp.net core的Web API项目为例,创建工程并推送至服务器。

3.4.1 新建Asp.net项目

bmtscc2服务器上具备 dotnet core的开发与运行环境,因此使用putty之类的终端远程登陆该服务器后执行如下命令

$ mkdir asp.net.demo
$ cd asp.net.demo
$ dotnet new web

3.4.2 初始化git库

$ git init
Initialized empty Git repository in /root/workspace/asp.net.demo/.git/


$ git status
On branch master

No commits yet

Untracked files:
  (use "git add ..." to include in what will be committed)

        Program.cs
        Properties/
        Startup.cs
        appsettings.Development.json
        appsettings.json
        asp.net.demo.csproj
        obj/

nothing added to commit but untracked files present (use "git add" to track)

3.4.3 将所有文件添加至暂存区

$ git add .
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached ..." to unstage)

        new file:   Program.cs
        new file:   Properties/launchSettings.json
        new file:   Startup.cs
        new file:   appsettings.Development.json
        new file:   appsettings.json
        new file:   asp.net.demo.csproj
        new file:   obj/asp.net.demo.csproj.nuget.dgspec.json
        new file:   obj/asp.net.demo.csproj.nuget.g.props
        new file:   obj/asp.net.demo.csproj.nuget.g.targets
        new file:   obj/project.assets.json
        new file:   obj/project.nuget.cache

3.4.4 提交第一个版本至本地库

$ git commit -m 'Ver1'
[master (root-commit) 40749c0] First Version
 11 files changed, 275 insertions(+)
 create mode 100644 Program.cs
 create mode 100644 Properties/launchSettings.json
 create mode 100644 Startup.cs
 create mode 100644 appsettings.Development.json
 create mode 100644 appsettings.json
 create mode 100644 asp.net.demo.csproj
 create mode 100644 obj/asp.net.demo.csproj.nuget.dgspec.json
 create mode 100644 obj/asp.net.demo.csproj.nuget.g.props
 create mode 100644 obj/asp.net.demo.csproj.nuget.g.targets
 create mode 100644 obj/project.assets.json
 create mode 100644 obj/project.nuget.cache

3.4.5 添加远程仓库

$ git remote add origin ssh://[email protected]:220/study/asp.net.demo.git

命令参数解释:

  • remote 远程仓库相关操作
  • add 添加动作
  • origin 远程仓库名称
  • ssh://[email protected]:220/study/asp.net.demo.git 远程仓库地址
    从上面命令可以看出,可以任意添加多个远程服务器,之需要在执行上述命令时取不同的远程仓库名称即可。

3.4.6 推送至远程仓库

$ git push -u origin master:master
Enumerating objects: 15, done.
Counting objects: 100% (15/15), done.
Delta compression using up to 32 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (15/15), 3.83 KiB | 784.00 KiB/s, done.
Total 15 (delta 1), reused 0 (delta 0)
To ssh://10.0.31.14:220/study/asp.net.demo.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

命令参数解释

  • push 推送
  • -u 加了参数-u后,以后即可直接用git push 代替git push origin master:master
  • origin 远程仓库名称,与3.4.5节中相同
  • master:master 从本地master分支推送至远程仓库的master分支

3.5 分支操作

群组开发中的版本管理模式有很多种,这里仅仅举例说明,大致工作流程如下:

  • 每个开发者的本地库中最起码具有master和dev分支
$ git branch dev #创建分支
graph LR
subgraph 本地仓库
  A[Ver1] --master分支--> B[Ver1]
  A[Ver1] --dev分支--> C[Ver1]
end
  • 中心库具有master、dev以及所有开发者的分支
graph LR
subgraph 远程仓库
  A[Ver1] --master分支--> B[Ver1]
  A[Ver1] --dev分支--> C[Ver1]
end
  • 通常情况下开发者工作在自己的dev分支,普通的版本提交应提交至dev分支
$ git checkout dev #切换当前分支至dev分支
... modified some file ...
$ git add .
$ git commit -m 'Ver2'
graph LR
subgraph 本地仓库
  A[Ver1] --master分支--> B[Ver1]
  A[Ver1] --dev分支--> C[Ver2]
end
  • 经过自己的测试没有问题,开发者将dev推送至中心版本库上自己的分支
$ git push origin dev:userbranchname
graph LR
  subgraph 本地仓库
  A[Ver1] --master分支--> B[Ver1]
  A[Ver1] --dev分支--> C[Ver2]
  end
  
  subgraph 远程仓库
    I[Ver1] --master分支--> J[Ver1]
    I[Ver1] --dev分支--> K[Ver1]
    I[Ver1] --user分支--> L[Ver2]
    C[dev分支]--push-->L[Ver2]
  end
  • 推送成功后在gitlab网页中向管理员提交合并申请
  • 管理员审核代码后,将开发者分支合并至dev分支
graph LR
  subgraph 本地仓库
  A[Ver1] --master分支--> B[Ver1]
  A[Ver1] --dev分支--> C[Ver2]
  end
  
  subgraph 远程仓库
    I[Ver1] --master分支--> J[Ver1]
    I[Ver1] --dev分支--> K[Ver2]
    I[Ver1] --user分支--> L[Ver2]
    C[dev分支] --push--> L[Ver2]
    L[Ver2] --merge--> K[Ver2]
  end
  • 经管理员测试后没有问题,管理员负责将dev分支合并至master分支
graph LR
  subgraph 本地仓库
  A[Ver1] --master分支--> B[Ver1]
  A[Ver1] --dev分支--> C[Ver2]
  end
  
  subgraph 远程仓库
    I[Ver1] --master分支--> J[Ver2]
    I[Ver1] --dev分支--> K[Ver2]
    I[Ver1] --user分支--> L[Ver2]
    C[Ver2] --push--> L[Ver2]
    L[Ver2] --merge--> K[Ver2]
    K[Ver2] --merge--> J[Ver2]
  end
  • 开发者将主分支最新版拉取至本地获得所有开发者被合并至主分支的最新代码
$ git pull origin master:master
graph LR
  subgraph 本地仓库
  A[Ver1] --master分支--> B[Ver2]
  A[Ver1] --dev分支--> C[Ver2]
  end
  
  subgraph 远程仓库
    I[Ver1] --master分支--> J[Ver2]
    I[Ver1] --dev分支--> K[Ver2]
    I[Ver1] --user分支--> L[Ver2]
    C[Ver2] --push--> L[Ver2]
    L[Ver2] --merge--> K[Ver2]
    K[Ver2] --merge--> J[Ver2]
    J[Ver2] --pull--> B[Ver2]
  end
  • 群组开发的情况下,其他用户也推送了自己分支的代码,并被合并到了主分支,开发者pull到本地master分支行通过如下命令从master分支合并至dev分支
$ git checkout dev
$ git merge master
graph LR
  subgraph 本地仓库
    A[Ver1] --master分支--> B[Ver2]
    B[Ver2] --master分支--> D[Ver3]
    D[Ver3] --master分支--> E[Ver4]
    E[Ver4] --master分支--> F[Ver5]
    A[Ver1] --dev分支--> C[Ver2]
    C[Ver2] --dev分支--> O[Ver3]
    O[Ver4] --dev分支--> P[Ver5]
    P[Ver5] --dev分支--> Q[Ver5]
    F[Ver5] --merge--> Q[Ver5]
  end
  
  subgraph 远程仓库
    I[Ver1] --master分支--> J[Ver2]
    I[Ver1] --dev分支--> K[Ver2]
    I[Ver1] --user分支--> L[Ver2]
    L[Ver2] --merge--> K[Ver2]
    K[Ver2] --merge--> J[Ver2]
    J[Ver2] --master分支--> Ver3[Ver3]
    Ver3[Ver3] --master分支--> Ver4[Ver4]
    Ver4[Ver4] --master分支--> Ver5[Ver5]
    Ver5[Ver5] --pull--> F[Ver5]
  end

4 Docker

4.1 简介

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

4.1.1 优点:

  • 能高效地构建应用。
  • 对于运维开发来说,能快速的交付和部署
  • 高效的资源利用
  • 轻松的迁移扩展
  • 简单的更新管理

4.1.2 与虚拟机的比较

特性 容器 虚拟机
启动速度 秒级 分钟级
存储 一般为MB级 一般为GB级
性能 接近原生 弱于原生
系统支持量 单机支持上千个容器 一般几十个
隔离性 安全隔离 安全隔离

4.2 镜像(Image)

概念与虚机镜像类似,系统内核支持,隔离性没有虚机好。
为了在在bmtscc2服务器上以docker方式安装gitlab服务应用,首先需要拉取gitlab镜像

$ sudo docker pull gitlab/gitlab-ce
$ docker image list
REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
gitlab/gitlab-ce                       latest              229b36075891        2 months ago        1.84GB

4.3 容器(Container)

类似linux或Windows系统环境,运行和隔离应用。容器从镜像启动的时候,docker会在镜像的最上一层创建一个可写层,镜像本身是只读的,保持不变。
运行gitlab容器

$ docker run gitlab/gitlab-ce -p 800:80 -p 220:22 -p 4430:443 -v /home/dockersrv/gitlab/etc:/etc/gitlab -v /home/dockersrv/gitlab/log:/var/log/gitlab -v /home/dockersrv/gitlab/data:/var/opt/gitlab -d --name gitlab

4.4 仓库(Register)

仓库(Repository)是集中存储镜像的地方,这里有个概念要区分一下,那就是仓库与仓库服务器(Registry)是两回事,像我们上面说的Docker Hub,就是Docker官方提供的一个仓库服务器,不过其实有时候我们不太需要太过区分这两个概念。

4.4.1 公共仓库

公共仓库一般是指Docker Hub,前面我们已经多次介绍如何从Docker Hub获取镜像,除了获取镜像外,我们也可以将自己构建的镜像存放到Docker Hub,这样,别人也可以使用我们构建的镜像。
不过要将镜像上传到Docker Hub,必须先在Docker的官方网站上注册一个账号,注册界面如下,按要求填写必要的信息就可以注册了。

4.4.2 私有仓库

有时候自己部门内部有一些镜像要共享时,如果直接导出镜像拿给别人又比较麻烦,使用像Docker Hub这样的公共仓库又不是很方便,这时候我们可以自己搭建属于自己的私有仓库服务,用于存储和分布我们的镜像。

Docker官方提供了registry这个镜像,可以用于搭建私有仓库服务,我们把镜像拉到本地之后,用下面命令创建该镜像的容器便可以搭建一个仓库服务,如下:

$ docker run -d -p 5000:5000 --restart=always --name registry registry

然后使用下面的语句推送到自己的私有仓库服务器

docker push 10.0.31.14/asp.net.demo:1.0

4.5 制作自己的镜像(DockerFile)

4.5.1 Dockerfile简介

Dockerfile是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。 Docker通过读取Dockerfile中的指令自动生成映像。
docker build命令用于从Dockerfile构建映像。可以在docker build命令中使用-f标志指向文件系统中任何位置的Dockerfile。

4.5.2 Dockerfile的基本结构

Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释。
Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本映像,第一条指令必须是FROM。一个声明以#字符开头则被视为注释。可以在Docker文件中使用RUN,CMD,FROM,EXPOSE,ENV等指令。

#指定基础镜像,必须为第一个命令,AS build定义构建阶段名称
FROM mcr.microsoft.com/dotnet/core/sdk AS build
#维护者信息
MAINTAINER tscc inc
#元数据,此处在后面的持续集成章节用到
LABEL stage=asp.net.demo.build
#工作目录,类似于cd命令
WORKDIR /src
#将本地文件添加到容器中,与ADD类似,区别是不自动解压文件
COPY ["asp.net.demo.csproj", "asp.net.demo.csproj"]
#构建镜像时执行的命令
RUN dotnet restore "asp.net.demo.csproj"
#拷贝物理机当前目录的所有文件至容器内当前目录
COPY . .
#编译源代码生成可执行文件
RUN dotnet publish "asp.net.demo.csproj" -c Release -o /app
#当前工作目录转换到/app
WORKDIR /app
#配置容器,使其可执行化
ENTRYPOINT ["dotnet", "asp.net.demo.dll"]

#构建阶段名称为publish
FROM mcr.microsoft.com/dotnet/core/aspnet AS publish
WORKDIR /app
#指定与外界交互的端口,这里的5000端口是代码中固定写死的
EXPOSE 5000
# --from 代表此处要拷贝的源文件来自于build阶段构建的镜像中
COPY --from=build /app .
#配置容器,使其可执行化
ENTRYPOINT ["dotnet", "asp.net.demo.dll"]

上面的Dockerfile分为两个构建阶段,即build与publish。在没有指定--target参数的情况下,执行docker build后会生成两个镜像,build阶段生成的镜像带有源代码和编译好的可执行文件,publish阶段生成镜像中只有可执行文件。这种分阶段构建方法可以为后面讲的持续集成与持续部署简化步骤。

4.5 本地容器编排(docker-compose)

4.5.1 Docker-Compose 简介

实际工作中我们部署一个应用,一般不仅仅只有一个容器,可能会涉及到多个,比如用到数据库,中间件MQ,web前端和后端服务,等多个容器。如果一个个去启动应用,当项目非常多时,就很难记住了,所有需要一个配置文件,负责实现对Docker容器集群的快速编排。
Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。
Docker-Compose将所管理的容器分为三层,分别是工程(project),服务(service)以及容器(container)。Docker-Compose运行目录下的所有文件(docker-compose.yml,extends文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像,参数,依赖。一个服务当中可包括多个容器实例,Docker-Compose并没有解决负载均衡的问题,因此需要借助其它工具实现服务发现及负载均衡。
Docker-Compose的工程配置文件默认为docker-compose.yml,可通过环境变量COMPOSE_FILE或-f参数自定义配置文件,其定义了多个有依赖关系的服务及每个服务运行的容器。

4.5.2 使用Docker-Compose部署gitlab

在bmtscc2服务器中创建gitlab目录(默认目录名称也是工程名称),在该目录下创建docker-compose.yml,并添加如下内容

version: '3' #docker-compose API的版本

services: #服务列表
  gitlab: #定义名称为gitlab服务
    restart: always #重启策略[no | always | on-failure | unless-stopped]
    image: gitlab/gitlab-ce #镜像名称
    container_name: gitlab #容器名称
    ports: #映射端口
      - '220:22'
      - '4430:443'
      - '800:80'
    volumes: #映射卷
      - /home/dockersrv/gitlab/etc:/etc/gitlab
      - /home/dockersrv/gitlab/log:/var/log/gitlab
      - /home/dockersrv/gitlab/data:/var/opt/gitlab

4.5.3 Doker-Compose的使用

在gitlab目录下执行如下操作

  • 创建
$ sudo docker-compose up
  • 删除
$ sudo docker-compose down
  • 启动
$ sudo docker-compose start
  • 停止
$ sudo docker-compose stop

5 持续集成,测试和部署(CI,CT,CD)

5.1 简介

持续集成可简单理解为自动编译,当开发者将自己的代码提交至中心服务器,经过管理员审核后合并至某分支后,会触发编译服务器的编译(或打包)动作,生成可执行文件。GitLab CI 是GitLab内置的进行持续集成的工具,只需要在仓库根目录下创建.gitlab-ci.yml 文件,并配置GitLab Runner;每次提交的时候,gitlab将自动识别到.gitlab-ci.yml文件,并且使用Gitlab Runner执行该脚本。

5.2 Gitlab Runner

5.2.1 类型

GitLab-Runner可以分类两种类型:Shared Runner(共享型)和Specific Runner(指定型)。

  • Shared Runner:所有工程都能够用的,且只有系统管理员能够创建
  • Specific Runner:只有特定的项目可以使用

本文档中演示Specific Runner的使用方法。

5.2.2 Runner 常规安装

  • Windows安装请参见:https://docs.gitlab.com/runner/install/windows.html
  • Debian/Ubuntu
https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.deb.sh | sudo bash
  • RHEL/CentOS
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.rpm.sh | sudo bash

本环境中仅在bmtscc1服务器上安装gitlab-runner,由于网络问题,实际手动下载rpm包本地安装。
下载地址:https://gitlab-runner-downloads.s3.amazonaws.com/latest/index.html ,本地安装命令:

$ sudo rpm -ivh /path/to/gitlab-runner_amd64.rpm

5.2.3 使用docker安装Runner

#拉取镜像
$ sudo docker pull gitlab/gitlab-runner:latest
#运行
$ sudo docker run -d --name gitlab-runner --restart always -v /var/run/docker.sock:/var/run/docker.sock -v /home/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner:latest

5.2.3 获取Runner注册Token

安装好Runner之后,需要向Gitlab进行注册,注册Runner需要GitLab-CI的url和token。可根据需求注册选择所需类型Runner。

  • 获取Shared Runner注册Token:使用管理员用户登录,进入Admin Area->OverView->Runners界面可看到Token信息
  • 获取Specific Runner注册Token:进行项目仓库->settings->CI/CD界面可找到Token信息

5.2.4 注册Runner

在bmtscc1服务器上执行gitlab-ci-multi-runner register命令进行Runner注册,期间会用到前期获取的url及token;注册完成之后,GitLab-CI就会多出一条Runner记录

$ gitlab-runner register --clone-url http://gitlab:800
Runtime platform                                    arch=amd64 os=linux pid=1843 revision=4c96e5ad version=12.9.0
Running in system-mode.

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
http://bmtscc2:800
Please enter the gitlab-ci token for this runner:
L2pE4tqkzExD3B_cC3Ko
Please enter the gitlab-ci description for this runner:
[bmtscc1]:
Please enter the gitlab-ci tags for this runner (comma separated):
dotnet
Registering runner... succeeded                     runner=L2pE4tqk
Please enter the executor: custom, docker, virtualbox, docker+machine, docker-ssh+machine, kubernetes, docker-ssh, parallels, shell, ssh:
shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

注意

  • 由于bmtscc2上的gitlab服务是以docker的方式启动的,且容器的名字叫做gitlab,容器的外部端口为800,因此注册时需要添加 --clone-url http://gitlab:800参数。
  • 第四步手动输入标签,这里可以输入多个标签,需要与后面介绍到的.gitlab-ci.yml文件中的任务标签一致。 - 在使用docker方式安装Runner的情况下,可使用如下命令执行注册动作:
$ docker exec -it gitlab-runner gitlab-runner register

5.3 .gitlab-ci.yml文件编写

5.3.1 构建阶段(Stages)

Stages 表示构建阶段,说白了就是上面提到的流程。默认有3个stages:build, test, deploy。我们可以在一次 Pipeline 中定义多个 Stages,这些 Stages 会有以下特点:

  • 所有 Stages 会按照顺序运行,即当一个 Stage 完成后,下一个 Stage 才会开始
  • 只有当所有 Stages 完成后,该构建任务 (Pipeline) 才会成功
  • 如果任何一个 Stage 失败,那么后面的 Stages 不会执行,该构建任务 (Pipeline) 失败
    举例
stages:
  - build
  - test
  - deploy

5.3.2 任务(Jobs)

Jobs 表示构建工作,表示某个 Stage 里面执行的工作。我们可以在 Stages 里面定义多个 Jobs,这些 Jobs 会有以下特点:

  • 相同 Stage 中的 Jobs 会并行执行
  • 相同 Stage 中的 Jobs 都执行成功时,该 Stage 才会成功
  • 如果任何一个 Job 失败,那么该 Stage 失败,即该构建任务 (Pipeline) 失败
  • 作业必须具有唯一的名字,但不能以以下关键字来定义:image services stages types before_script after_script variables cache
  • Job中可以用only和except定义哪些分支被更新后执行或不执行
  • Job中的tags标签与5.2.4节提到的标签对应,即若Runner中含有该任务中的任一标签则被执行,否则不执行
  • 任务中必须得有script部分
    举例:
job_build:
  stage: build
  only:
    - dev
    - master
  tags:
    - dotnet
  script:
    - cd /home/gitlab-runner
    - rm -rf /home/gitlab-runner/asp.net.demo
    - git clone ssh://[email protected]:220/study/asp.net.demo
    - cd ./asp.net.demo
    - docker stop asp.net.demo || true
    - docker rm -f asp.net.demo || true
    - docker rmi -f asp.net.demo || true
    - docker build -t asp.net.demo --target build .

5.3.3 .gitlab-ci.yml

.gitlab-ci.yml 用来配置 CI 用你的项目中做哪些操作,这个文件位于仓库的根目录。
当有新内容push到仓库,或者有代码合并后,GitLab会查找是否有.gitlab-ci.yml文件,如果文件存在,Runners将会根据该文件的内容开始build本次commit。
.gitlab-ci.yml 使用YAML语法, 你需要格外注意缩进格式,要用空格来缩进,不能用tabs来缩进。

5.3.4 示例

stages:
  - build
  - test
  - deploy

job1:
  stage: build
  only:
    - dev
    - master
  tags:
    - dotnet
  script:
    - cd /home/gitlab-runner
    - rm -rf /home/gitlab-runner/asp.net.demo
    - git clone -b dev ssh://[email protected]:220/study/asp.net.demo
    - cd ./asp.net.demo
    - docker stop asp.net.demo || true
    - docker rm -f asp.net.demo || true
    - docker rmi -f asp.net.demo || true
    - docker build -t asp.net.demo --target build .
    
job2:
  stage: test
  only:
    - dev
    - master
  tags:
    - dotnet
  script:
    - echo "begin test stage"
    - docker run -d -p 6000:5000 --name asp.net.demo asp.net.demo
    - docker image prune -f --filter label=stage=asp.net.demo.build
    - sleep 5
    - curl http://localhost:6000

job3:
  stage: deploy
  only:
    - master
  tags:
    - dotnet
  script:
    - docker stop asp.net.demo || true
    - docker rm -f asp.net.demo || true
    - docker rmi -f asp.net.demo || true
    - cd /home/gitlab-runner/asp.net.demo
    - docker build -t asp.net.demo .
    - docker run -d -p 6000:5000 --name asp.net.demo --restart always asp.net.demo
    - docker image prune -f --filter label=stage=asp.net.demo.build

你可能感兴趣的:(Realize Dockerlized CI CT And CD by GitLab)