Gitlab CI
本篇博客首先介绍了如何使用gitlab的ci功能
本篇博客主要介绍如何使用gitlab的ci功能,并且搭配aliyun docker hub功能,实现特定分支有更新的时候,可以进行打镜像,并且推送到aliyun的docker hub,后续可能还会再加上基于docker hub中的镜像实现部署的部分
这篇博客的由来
- 最近公司打算放弃使用企业版的Github,转向使用Gitlab。刚好最近事情不太多,就尝试了一下gitlab的ci/cd功能
- 并且实现了自动推送镜像到aliyun的docker hub(薅羊毛啊)
- 顺道说一句,经过最近这一段时间使用gitlab的经历,我觉得它没有github好用(OvO)
- 下面部分👇有错误、不好的地方,欢迎大家指正
我做了什么
- 为了学习使用gitlab的ci/cd功能,我专门写了一个demo,主要就是一个最简单的golang http server,搭配写了一个Dockerfile,用于构造镜像
- 然后在gitlab的ci/cd中我会使用这个Dockerfile构造出镜像,来推送到 aliyun docker hub,以供后续的部署使用(目前暂时没有部署部分)
- 这样就模拟了一个项目从开发到线上部署的整个流程,基本全自动化,这样以后可以直接拿来用啦。
- demo地址为:https://gitlab.com/qinhan-shu/dep-demo
- 欢迎大家的 fork,issue,star 😄
Aliyun Docker Hub
- Docker 在如今的web领域的地位、重要性我就不多说了,大家都懂,超级方便好用的容器技术,特别是搭配使用k8s的话
- 官方的 Docker Hub 超级慢,而且还是公开的。我选择使用 aliyun 免费 & 快速的 Docker Hub 😂
- 怎么申请呢,首先注册账号,然后进入控制台,搜索 “容器镜像服务”,然后开通,设置密码,这个密码是后续你推送镜像到 aliyun Docker Hub的密码,好好保存着,然后点击 ”创建镜像仓库“,按照他的指示一步一步来就可以来。(哦对,在创建镜像仓库的时候,应该会让你先创建一个命名空间)
- 创建完成之后点击进入仓库,基本信息中有教你如何使用仓库的教程:
Gitlab使用CI
- 想要使用gitlab的ci,那么你必须要有两个东西:Runner、放置于项目根目录的 .gitlab-ci.yml 文件
- 每当你提交代码的时候,会根据你 .gitlab-ci.yml 配置文件中的规则在 Runner 中运行。这个大概就是 gitlab ci 的实现原理。
Runner
- 所谓的Runner,就是ci的执行者。gitlab上有共享runner,但是我没有用,我是在自己的ecs上运行了gitlab runner,如果没有的话,使用共享的runner应该也是可以的(我没有试过,欢迎大家分享宝贵的踩坑心得)。
如何搭建自己的Runner
首先进入项目,然后依次进入:settings -> CI/CD,然后展开Runner项,可以看到如下所示的一项:
它标注了为这个项目构建runner时候所使用的url和令牌。接下来就来在ecs上搭建自己的runner吧。
我推荐使用docker进行搭建,这样不需要在你的ecs上安装任何其他的东西,比较干净。当然官网也提供了单独安装runner的教程,如果大家想去直接安装runner的话也可以,教程地址:https://docs.gitlab.com/runner/install/
Docker搭建自己的Runner
docker安装runner的话,第一步是安装docker:
1
curl -sSL https://get.docker.com/ | sh
然后,启动runner
- 需要将配置卷安装到gitlab-runner容器中以用于配置和其他资源:
1
2
3
4docker 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容器中以用于配置和其他资源:
第三步就是注册,将上面图片中的url和令牌注册到Runner中,使其成为项目的Runner
1
docker run --rm -t -i -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register
接下来会依次让你输入一些东西(包括上面提到的 url和令牌 )
输入url
1
2Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
https://gitlab.com输入令牌
1
2Please enter the gitlab-ci token for this runner
xxx输入Runner的描述(可以在GitLab的UI中更改)
1
2Please enter the gitlab-ci description for this runner
[hostname] my-runner输入与Runner关联的tag(可以在GitLab的UI中更改)
1
2Please enter the gitlab-ci tags for this runner (comma separated):
my-tag,another-tag输入Runner执行程序(推荐使用docker,因为其他的我也没用过,不敢瞎推荐)
1
2Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
docker上述步骤选择Docker作为执行程序,则会要求将默认image,用于未在 .gitlab-ci.yml 中定义镜像的项目( 推荐使用alpine,因为小😂 )
1
2Please enter the Docker image (eg. ruby:2.1):
alpine:latest完成了上述步骤之后,在返回到gitlab的项目的 settings -> CI/CD,然后展开Runner项,就可以看到你刚刚注册的Runner:
到此,Runner就注册完成了
.gitlab-ci.yml
- 说完了Runner,接下来说说 .gitlab-ci.yml
- 官网的教程地址:https://docs.gitlab.com/ee/user/project/pages/getting_started_part_four.html
- 上面的配置文件详解我就不说了,说说Demo(https://gitlab.com/qinhan-shu/dep-demo)中的配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101# 首先是镜像的设置
# 如果不设置镜像的话,则会使用之前注册runner时候最后选择的镜像
# 在后续每个job中也可以单独设置镜像,如果没有设置的话,则使用这个默认的全局镜像
image: golang:latest
# services 是依赖的服务,因为我有一个名为 push_image 的job,这个job需要用到docker命令,将编译好的镜像推送到 aliyun docker hub
# 因此启动 docker:dind 服务,就是一个 docker daemon,如果没有这个服务,push_image job就会报错了
services:
- docker:dind
# 一些全局变量
variables:
# docker 镜像的驱动,选择overlay2来提速,默认驱动较慢
DOCKER_DRIVER: overlay2
# 项目名称
REPO_NAME: gitlab.com/qinhan-shu/dep-demo
# 顾名思义,就是在 job 执行之前所执行的脚本
before_script:
- mkdir -p $GOPATH/src/$(dirname $REPO_NAME)
- ln -svf $CI_PROJECT_DIR $GOPATH/src/$REPO_NAME
- cd $GOPATH/src/$REPO_NAME
# 这个是比较重要的一个配置项目 -- 阶段
# 各个阶段依次执行,只有前面一个阶段执行完成之后才可以执行后续的阶段
# 而每一个阶段可以有多个job,job就是ci执行的最小单位
# 例如改配置就会分成三个阶段:
# test:测试代码正确性阶段,包括了四个job(gofmt,govet,gotest,coverage)分别从四个不同的侧重点测试代码的正确性;
# build:编译阶段,包括两个阶段(compile,push_image),第一个job 执行go build,第二个推送镜像到阿里云(我设置成了手动点击执行);
# deploy:部署,暂时还没有写 😂;
stages:
- test
- build
- deploy
# gofmt job,后面的几个job都类似,就不一一详细叙述了,可以直接跳到最后一个job - push_image
gofmt:
# 标明属于哪个stage
stage: test
# 执行条件,即满足下面条件才会执行。
# 除去refs,还有其他的条件,见官方文档:https://docs.gitlab.com/ee/ci/yaml/README.html#onlyexcept-basic
only:
# 执行分支
refs:
- master
# 具体这个job的执行脚本,借助了Makefile,可以参考看看项目中的 Makefile
script:
- make gofmt
govet:
stage: test
only:
refs:
- master
script:
- make govet
gotest:
stage: test
only:
refs:
- master
script:
- make gotest
coverage:
stage: test
only:
refs:
- master
script:
- make coverage
compile:
stage: build
only:
refs:
- master
script:
- make server
# push_image job:推送镜像到 aliyun docker hub
push_image:
stage: build
# 本job的镜像,因为需要使用到 docker 指令
image: docker:stable
# 只有prod分支才执行
only:
refs:
- prod
# 默认跳过,手动执行,在项目中的流水线中手动点击执行(考虑到不是每一次都打镜像)。
when: manual
# 具体执行的脚本,首先 build, 然后push
# 这儿一些敏感的账号密码之类放到了 CI/CD 的环境变量中去了
# 可以在 项目 -> settings -> CI/CD -> Variables 中设置
script:
# - COMMIT=$(git rev-parse --short HEAD)
- IMAGE_NAME=registry.cn-shanghai.aliyuncs.com/qinhan-shu/dep-demo:latest
- docker build -t $IMAGE_NAME -f docker/Dockerfile .
- echo ${DOCKER_PASSWORD} | docker login --username ${DOCKER_USER} --password-stdin ${DOCKER_REG}
- docker push $IMAGE_NAME
总结
- 后续补充上部署的部分