文章目录

一、下载gitlab以及gitlab-runner镜像

1sudo podman pull docker.io/gitlab/gitlab-ee
2sudo podman pull docker.io/gitlab/gitlab-runner

笔者下载的版本是gitlab-ee 14.5,gitlab-runner 14.5

二、运行容器与配置gitlab

1、运行gitlab容器

 1sudo podman run -dt \
 2  --h "192.168.1.8" \
 3  -p 443:443 -p 80:80 -p 22:22 -p 5050:5050 \
 4  --name gitlab \
 5  --restart always \
 6  -v /home/gitlab/etc:/etc/gitlab \
 7  -v /home/gitlab/logs:/var/log/gitlab \
 8  -v /home/gitlab/git-data:/var/opt/gitlab/git-data \
 9  -v /home/gitlab/backups:/var/opt/gitlab/backups \
10  -v /home/gitlab/opt:/var/opt/gitlab \
11  docker.io/gitlab/gitlab-ee
  • -d:后台运行
  • -t:分配伪终端
  • -h:指定主机名
  • -p:映射主机与容器端口,冒号前面为主机端口,后面为容器端口
  • –name:指定名字
  • -v:映射主机与容器的目录,冒号前面为主机目录,后面为容器目录 这里映射了gitlab的配置、日志、以及数据。要求在映射时主机存在相应的目录。

2、修改配置

笔者不作任何配置修改的情况下,运行gitlab会一直报错:

1caller=cluster.go:154 component=cluster err="couldn't deduce an advertise address: no private IP found, explicit advertise addr not provided"
2
3caller=main.go:241 msg="unable to initialize gossip mesh" err="create memberlist: Failed to get final advertise address: No private IP address found, and explicit IP not provided"

使用如下命令进入容器Bash:

1sudo podman exec -it gitlab bash

然后修改/etc/gitlab/gitlab.rb文件(如果在创建容器时有将配置文件所在目录映射到主机,则可以直接在主机修改),添加如下配置:

1alertmanager['flags'] = {
2  'cluster.advertise-address' => "0.0.0.0:9093"
3}

即可解决不断报错的问题。

添加如下配置,设置时区为上海时区

1gitlab_rails['time_zone'] = 'Asia/Shanghai'

如果想开启Gitlab自带的容器镜像库,添加如下配置:

1registry_external_url 'https://localhost:5050'
2gitlab_rails['registry_enabled'] = true
3registry_nginx['ssl_certificate_key'] = "/var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key"
4registry_nginx['ssl_certificate'] = "/var/opt/gitlab/registry/gitlab-registry.crt"

需要注意的是证书及密钥的存储位置(笔者下载的Gitlab容器启用容器镜像库后,默认就是上面的位置),如果上面的目录中没有相应的文件,则需要修改为相应的位置

每次修改了gitlab.rb文件后,都需要在主机使用如下命令让配置生效:

1sudo podman exec -it gitlab gitlab-ctl reconfigure

3、登录gitlab

在配置好gitlab并运行后,就可以使用root账号进行登录了,root账号的密码在:

1/etc/gitlab/initial_root_password

文件中。 注意:此文件将在第一次运行reconfigure后24小时删除,所以安装好后,需要尽快登录gitlab并设置密码。

三、运行与注册gitlab-runner

1、运行gitlab-runner

1sudo podman run -dt --name gitlab-runner --restart always -v /home/gitlab-runner:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock docker.io/gitlab/gitlab-runner

由于gitlab-runner默认使用的用户为gitlab-runner,如上图所示,而/home/gitlab-runner默认是root用户才有相应的权限,为了顺利执行,笔者建议使用root用户执行,这样就不用手动修改/home/gitlab-runner的权限:

1sudo podman run -dt --name gitlab-runner --restart always -v /home/gitlab-runner:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock docker.io/gitlab/gitlab-runner run --working-directory=/home/gitlab-runner

注意:为了让gitlab-runner能够使用docker命令,在创建容器时必须将/var/run/docker.sock映射到容器,否则会执行失败。

2、进入容器Bash

使用下面的命令进入容器bash:

1sudo podman exec -it gitlab-runner bash

3、注册gitlab-runner

a、注册shell

 1root@7350bbb38bc1:/# gitlab-runner register
 2Runtime platform                                    arch=amd64 os=linux pid=84 revision=f0a95a76 version=14.5.0
 3Running in system-mode.                            
 4                                                   
 5Enter the GitLab instance URL (for example, https://gitlab.com/):
 6http://192.168.1.8/          ### 这里填写GitLab实例的URL地址
 7Enter the registration token:
 8WWgCAuScx5XGxEVS3Hza         ### 这里填写GitLab实例中的注册令牌,按下图所示的步骤获取令牌
 9Enter a description for the runner:
10[293e39980f0f]: default      ### 这里填写描述信息 
11Enter tags for the runner (comma-separated):
12build						 ### 这里填写标签信息,需要注意的是这个标签在.gitlab-ci.yml中会用到
13Registering runner... succeeded                     runner=CWgCAuSc
14Enter an executor: docker, shell, virtualbox, docker+machine, docker-ssh+machine, kubernetes, custom, parallels, ssh, docker-ssh:
15shell                      ### 这里选择执行器,根据自己情况进行选择
16Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded! 

注册成功后,即可在gitlab中看到runner了

b、注册docker

如果想要在CI/CD时使用docker来进行打包发布,可以注册docker:

 1root@7350bbb38bc1:/# gitlab-runner register
 2Runtime platform                                    arch=amd64 os=linux pid=84 revision=f0a95a76 version=14.5.0
 3Running in system-mode.                            
 4                                                   
 5Enter the GitLab instance URL (for example, https://gitlab.com/):
 6http://192.168.1.8/          ### 这里填写GitLab实例的URL地址
 7Enter the registration token:
 8WWgCAuScx5XGxEVS3Hza         ### 这里填写GitLab实例中的注册令牌,按下图所示的步骤获取令牌
 9Enter a description for the runner:
10[293e39980f0f]: master      ### 这里填写描述信息 
11Enter tags for the runner (comma-separated):
12docker						 ### 这里填写标签信息,需要注意的是这个标签在.gitlab-ci.yml中会用到
13Registering runner... succeeded                     runner=CWgCAuSc
14Enter an executor: docker, shell, virtualbox, docker+machine, docker-ssh+machine, kubernetes, custom, parallels, ssh, docker-ssh:
15docker                      ### 这里选择执行器,输入docker
16Enter the default Docker image (for example, ruby:2.6):
17docker:latest               ## 输入docker使用的镜像
18Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded! 

docker镜像也可以使用构建在自己的镜像仓库中的镜像。

如果想要修改现有的gitlab-runner,可以在gitlab-runner容器中编辑/etc/gitlab-runner/config.toml

 1concurrent = 1
 2check_interval = 0
 3
 4[session_server]
 5  session_timeout = 1800
 6
 7[[runners]]
 8  name = "master"
 9  url = "http://192.168.1.8/"
10  token = "H7UaNzLUwSSx8sNVmrQH"
11  executor = "shell"
12  [runners.custom_build_dir]
13  [runners.cache]
14    [runners.cache.s3]
15    [runners.cache.gcs]
16    [runners.cache.azure]
17
18[[runners]]
19  name = "master"
20  url = "http://192.168.1.8/"
21  token = "hCNqcgJQ8jbNCnkrsP_R"
22  executor = "docker"
23  [runners.custom_build_dir]
24  [runners.cache]
25    [runners.cache.s3]
26    [runners.cache.gcs]
27    [runners.cache.azure]
28  [runners.docker]
29    tls_verify = false
30    image = "docker"
31    privileged = false
32    disable_entrypoint_overwrite = false
33    oom_kill_disable = false
34    disable_cache = false
35    volumes = ["/cache","/var/run/docker.sock:/var/run/docker.sock"]
36    shm_size = 0
37    pull_policy = "if-not-present"

gitlab-runner注册docker时需要填写一个镜像名称,在.gitlab-ci.yml配置文件中有一个image关键字也可以指定镜像名,这两个有什么关系呢?

这两个镜像都是用于运行.gitlab-ci.yml配置文件中的脚本命令,如果.gitlab-ci.yml中没有指定image,则默认使用gitlab-runner注册docker时使用的镜像,否则使用.gitlab-ci.yml中指定image镜像。

在使用docker时,为了避免每次都从网络上拉取,可以设置

1pull_policy = "if-not-present"

这样配置后,如果本地有镜像则直接使用本地镜像。

4、安装相应的软件

由于gitlab-runner是使用的ubuntu系统制作而成,在安装软件前,需要执行一次更新:

1apt update

否则在安装软件时可能报错:

1E: Unable to locate package

更新后,就可以按自己需要安装相应的软件了,比如笔者需要C++相应的编译环境,安装:

1apt install cmake
2apt install g++

在安装cmake时会额外安装一些包,比如gcc等等,但是不会安装g++包,所以需要单独安装g++:

 1root@7350bbb38bc1:~# apt install cmake
 2Reading package lists... Done
 3Building dependency tree       
 4Reading state information... Done
 5The following additional packages will be installed:
 6  binutils binutils-common binutils-x86-64-linux-gnu cmake-data cpp cpp-9 gcc gcc-9 gcc-9-base libarchive13 libasan5 libatomic1 libbinutils libc-dev-bin libc6-dev libcc1-0 libcrypt-dev libctf-nobfd0 libctf0 libgcc-9-dev libgomp1
 7  libicu66 libisl22 libitm1 libjsoncpp1 liblsan0 libmpc3 libmpfr6 libquadmath0 librhash0 libtsan0 libubsan1 libuv1 libxml2 linux-libc-dev make manpages manpages-dev
 8Suggested packages:
 9  binutils-doc cmake-doc ninja-build cpp-doc gcc-9-locales gcc-multilib autoconf automake libtool flex bison gdb gcc-doc gcc-9-multilib gcc-9-doc lrzip glibc-doc make-doc man-browser
10The following NEW packages will be installed:
11  binutils binutils-common binutils-x86-64-linux-gnu cmake cmake-data cpp cpp-9 gcc gcc-9 gcc-9-base libarchive13 libasan5 libatomic1 libbinutils libc-dev-bin libc6-dev libcc1-0 libcrypt-dev libctf-nobfd0 libctf0 libgcc-9-dev
12  libgomp1 libicu66 libisl22 libitm1 libjsoncpp1 liblsan0 libmpc3 libmpfr6 libquadmath0 librhash0 libtsan0 libubsan1 libuv1 libxml2 linux-libc-dev make manpages manpages-dev
130 upgraded, 39 newly installed, 0 to remove and 1 not upgraded.
14Need to get 48.4 MB of archives.

四、测试

1、测试Shell

A、准备项目

新建一个demo项目,这个项目中有如下三个文件:

编写一个.gitlab-ci.yml文件,内容如下:

 1stages:
 2    - build
 3
 4build:
 5    stage: build
 6    script:
 7    - rm build -rf
 8    - mkdir -p build
 9    - cd build
10    - cmake .. -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++
11    - time make -j4
12    tags:
13    - build
14    only:
15        changes:
16           - "**/*.{c,cpp,cc,h,hpp,cxx,C}"
17           - "**/CMakeLists.txt"
18           - "CMakeLists.txt"
19           - "*.{c,cpp,cc,h,hpp,cxx,C}"

其中的tags就是前面注册gitlab-runner使用的标签

CMakeLists.txt文件内容如下:

 1cmake_minimum_required(VERSION 3.0.0)
 2project(demo VERSION 0.1.0)
 3
 4include(CTest)
 5enable_testing()
 6
 7add_executable(demo main.cpp)
 8
 9set(CPACK_PROJECT_NAME ${PROJECT_NAME})
10set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
11include(CPack)

main.cpp文件内容如下:

 1#include <stdio.h>
 2#include <iostream>
 3
 4using namespace std;
 5
 6int main(int, char**) {
 7	cout << "Hello, world!\n";
 8	printf("测试\n");
 9	return 0;
10}

上传到gitlab后,会自动触发编译项目,如下图所示:

B、测试容器镜像库

在前面配置gitlab时有提到,可以启用Gitlab自带容器镜像库,当然也可以配置成外部的容器镜像库,不过配置要复杂些。前面的配置是使用的自带的容器镜像库,启用成功后可以在项目中看到如下图所示功能:

从图中提示可以看出,要使用容器镜像库,还需要先登录,再构建容器镜像,最后推送到容器镜像库,才能显示到页面上。 需要注意的是,这里配置的容器镜像库由于是使用的localhost,所以只能供主机或者容器使用

根据页面提示的命令,来进行测试:

a、准备环境

在主机上新建一个目录,比如mon,创建一个Dockfile文件,内容如下:

1from ubuntu
2Run echo "这是一个podman测试"
b、登录

使用下面的命令登录:

1sudo docker login localhost:5050

登录时需要输入用户名与密码,要求与Gitlab中的用户名密码一致。

c、构建容器镜像

d、推送

e、刷新gitlab容器镜像库页面

推送成功后刷新页面即可看到镜像库列表了,如下图所示:

2、测试docker

A、准备环境

这里以一个go语言项目为例,所以需要在gitlab-runner中准备go的编译环境。 如果不使用shell的方式,而是使用docker的方式,在.gitlab-ci.yml中使用image关键指定镜像为golang,就可以跳过此步。

如果使用shell的方式,由于gitlab-runner容器中使用apt或者yum安装的Go版本可能比较老,所以建议自行下载新版的Go,笔者下载的go1.16.11.linux-amd64.tar.gz,然后使用命令复制到gitlab-runner容器中

1sudo podman cp go1.16.11.linux-amd64.tar.gz gitlab-runner:/usr/local

在容器中解压go1.16.11.linux-amd64.tar.gz到/usr/local

1cd /usr/local
2tar zxvf go1.16.11.linux-amd64.tar.gz

go编译环境还需要安装gcc,前面有说明,这里就不再赘述了。

B、准备项目

新建一个GoDemo目录,目录中有main.go、Dockerfile和.gitlab-ci.yml三个文件, main.go内容如下:

 1package main
 2
 3import (
 4	"net/http"
 5)
 6
 7func main() {
 8	http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
 9		writer.Write([]byte("Hello, 这是一个CI/CD测试!"))
10	})
11
12	http.ListenAndServe(":8000", nil)
13}

Dockerfile内容如下:

 1FROM ubuntu
 2
 3# 镜像中项目路径
 4WORKDIR $GOPATH/src/GoDemo
 5# 拷贝当前目录代码到镜像
 6COPY . $GOPATH/src/GoDemo
 7
 8# 暴露端口
 9EXPOSE 8000
10
11# 程序入口
12ENTRYPOINT ["./bin/demo"]

.gitlab-ci.yml内容如下:

 1default:
 2  before_script:
 3    - export PATH=$PATH:/usr/local/go/bin   # 添加go命令的路径
 4    - export GOPATH=~/go                    # 设置GOPATH环境变量
 5    - mkdir -p $GOPATH/src/                 # 根据go要求,创建src目录
 6    - ln -svf $CI_PROJECT_DIR $GOPATH/src/  # 由于gitlab-runner的工作目录不在Go要求的目录,所以这里做一个软链接
 7    - cd $CI_PROJECT_DIR                    # 切换到源码目录
 8    - go mod init demo						# 生成go.mod文件
 9    - go mod tidy 							# 生成go.sum文件
10    - go get								# 下载依赖项
11  
12variables:
13  #CI_DEBUG_TRACE: "true"					# 用于CI调试,输出相关的变量值
14  GO111MODULE: "on"							# 打开go的模块标志
15  GOPROXY: "https://goproxy.cn,direct"      # 由于默认的代理很慢,国内建议使用https://goproxy.cn作代理
16
17stages:
18	- gen
19    - test
20    - build
21    - deploy
22
23format:
24    stage: test
25    tags:
26      - build
27    script:
28      - go fmt $(go list ./... | grep -v /vendor/)
29      - go vet $(go list ./... | grep -v /vendor/)
30
31test:
32    stage: test
33    tags:
34      - build
35    script:
36      - go test -race $(go list ./... | grep -v /vendor/)
37
38compile:
39    stage: build
40    tags:
41      - build
42    script:
43      - go build -race -ldflags "-extldflags '-static'" -o $CI_PROJECT_DIR/bin/demo
44    artifacts:
45      paths:
46        - $CI_PROJECT_DIR/bin/
47
48docker-deploy:
49  image:
50    name: docker:latest
51  stage: deploy
52  before_script:
53    # 需要先登录gitlab内置的镜像仓库
54    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
55  script:
56    # 使用Dockerfile生成容器镜像
57    - docker build --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest .
58    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA  	# 按SHA推送镜像
59    - docker push $CI_REGISTRY_IMAGE:latest				# 推送latest镜像
60    - docker rmi -f $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA   # 删除本地临时镜像
61    - docker rmi -f $CI_REGISTRY_IMAGE:latest			# 删除本地临时镜像
62  tags:
63    - docker
64
65# 让gitlab具有代码跳转的能力
66code_navigation:
67  stage: gen
68  image: sourcegraph/lsif-go:v1
69  allow_failure: true # recommended
70  script:
71    - lsif-go -o server.lsif
72  artifacts:
73    reports:
74      lsif: server.lsif
75  tags:
76      - docker

如果是使用golang的docker镜像,则可以不用设置PATH变量,比如compile,可以写为:

 1compile:
 2    image: golang:1.16
 3    stage: build
 4    tags:
 5      - docker
 6    script:
 7      - go version
 8      - go mod init demo
 9      - go mod tidy
10      - go get
11      - go mod vendor
12      - go build -race -ldflags "-extldflags '-static'" -o $CI_PROJECT_DIR/bin/demo
13    artifacts:
14      paths:
15        - $CI_PROJECT_DIR/bin/

C、测试

笔者的运行流水线如下图所示:

容器镜像库如下图所示:

前面.gitlab-ci.yml中code_navigation让gitlab页面可以进行代码跳转,效果如下图所示:

运行前面提交的镜像,注意需要把端口映射出来:

查看运行情况:

运行成功。