gitlab runner 使用案例
接上文gitlab runner 配置说明
本文以一个使用案例说明docker runner
的使用
1. 配置文件的大概说明
因为gitlab
使用的docker版本的:gitlab/gitlab-ce:12.10.14-ce.0
,所以gitlab-runner
采用docker的版本是:gitlab/gitlab-runner:v12.10.3
。所以gitlab-runner
的docker-compose
配置内容如下:
gitlab-runner:
hostname: gitlab-runner
container_name: gitlab-runner
image: gitlab/gitlab-runner:v12.10.3
restart:
always
userns_mode:
"host"
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- $PWD/gitlab-runner/config:/etc/gitlab-runner
经过修改后的gitlab-runner
的gitlab-runner/config/config.toml
配置文件如下:
concurrent = 1
check_interval = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "gitlab-runner"
url = "http://192.168.xxxx"
token = "tGeDQLKxxxx"
executor = "docker"
[runners.custom_build_dir]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
[runners.docker]
tls_verify = false
image = "docker:19.03.13"
pull_policy="if-not-present"
userns_mode = "host"
privileged = true
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
shm_size = 0
volumes = ["/var/run/docker.sock:/var/run/docker.sock","/root/.docker/config.json:/root/.docker/config.json","/cache"]
这里的volumes
挂载了/root/.docker/config.json:/root/.docker/config.json
的目的是为了在执行自动化的时候,可以不用每次都登录远端的registry才能推送镜像。
2. gitlab 上 runner 的情况
使用root用户登录了gitlab后,在Runners
页添加runner
后的信息如下:
3. 创建部署用户
在需要被runner操作目标机器上,创建一个用于能操作docker的非root普通用户,避免runner后续链接次此机器的时候使用root用户造成权限过大,以dku
为例:
useradd -u 5000 dku
mkdir /home/dku/.ssh
chmod 700 /home/dku/.ssh
usermod -G docker dku
部署登录镜像仓库的json文件
然后把其他用用户的~/.docker/
目录复制过来,比如说root用户的,那么就复制/root/.docker/
到/home/dku
里,因为.docker
目录里有一个config.json
文件,里面有登录容器镜像仓库的json信息。后面需要使用这个用户来拉取镜像,就需要这个文件。
cp -r /root/.docker/ /home/dku
chown -R dku:dku /home/dku/.docker/
另外还需要创建一个 SSH 密钥,GitLab CI/CD 将使用这个密钥登录目标服务器并执行部署等一系列操作:
su - dku
ssh-keygen
生成完秘钥后,需要将公钥复制到authorized_keys
中:
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
此时,id_rsa
和id_rsa.pub
备份下来后可以删除了。在要部署的客户机上,只需要有一个authorized_keys
文件即可。
4. 将私钥添加到 GitLab CI/CD 变量中
将 SSH 私钥存储在 GitLab CI/CD 文件变量中,方便Pipelines管道可以使用该密钥登录到服务器。
当 GitLab 创建 CI/CD 管道时,它会将所有变量发送到相应的运行器,并且这些变量将被设置为作业持续时间的环境变量。特别是,文件变量的值存储在文件中,环境变量将包含该文件的路径。
在设置变量部分时,还可以服务器 IP 和服务器用户等信息添加在web页面里。也可以添加在.gitlab-ci.yml
文件里。
这里只添加一个密钥的文件变量:
在Gitlab的项目中的Settings > CI / CD > Variables并单击Add Variable。填写如下:
- Key: ID_RSA
- Value:
id_rsa
文件里的内容 - Type:File
- Environment scope:All (default)
- Protect variable:未选中
- Mask variable:未选中
这里即使勾选的Mask variable掩码值,也不会被屏蔽,因为它不符合正则表达式要求(具体看masked-variables说明)
Protect variable保护变量,如果勾选了,就需要在受保护分支和标签上才能使用这个变量值。
5. 配置runner允许使用自动部署的仓库
如下图所示,在runner 的页面中,下方的 Restrict projects for this Runner里把需要用给该runner执行的仓库点击 enable 激活,这样这个仓库的项目就可以被这个runner接管。不需要的时候,可以通过点击 disable 就可以取消 runner 的接管。
6. 配置.gitlab-ci.yml
文件
在这个被允许的仓库中,添加一个.gitlab-ci.yml
文件,示例如下:
variables:
PUSH_CI_REGISTRY_IMAGE: registry-vpc.cn-guangzhou.aliyuncs.com/demo
CLIENT_CI_REGISTRY_IMAGE: registry-vpc.cn-guangzhou.aliyuncs.com/demo
SERVER_IP: 1.2.3.4
SERVER_USER: dku
TARGET_DIR: /data/
COMPOST_FILE: docker-compose.yml
stages:
- build
- deploy
build:
stage:
build
only:
- tags
tags:
- ingram
when:
manual
script:
- docker build -t "$PUSH_CI_REGISTRY_IMAGE":"$CI_COMMIT_TAG" .
- docker push "$PUSH_CI_REGISTRY_IMAGE:$CI_COMMIT_TAG"
deploy:
stage:
deploy
only:
- tags
tags:
- ingram
when:
manual
script:
- chmod 600 "$ID_RSA"
- ssh -i "$ID_RSA" -o StrictHostKeyChecking=no "$SERVER_USER"@"$SERVER_IP" "cd $TARGET_DIR ; sed -ri 's#'$CLIENT_CI_REGISTRY_IMAGE'(.*)#'$CLIENT_CI_REGISTRY_IMAGE':'$CI_COMMIT_TAG'#' $COMPOST_FILE ; docker-compose up -d"
文件说明:
- 这里variables中的
PUSH_CI_REGISTRY_IMAGE
和CI_REGISTRY_IMAGE
分开两个,是因为推送镜像地址和客户机下载镜像的地址不是同一个,所以分开两个。 - 这里variables中的
SERVER_IP
、SERVER_USER
、TARGET_DIR
、COMPOST_FILE
,分别是服务器的IP、操作的用户、目标服务器的目录、compose文件名。 - 两个
stages
的when
都是设置成manual
,在gitlab页面上手动点启动。 - 都是只有在打了
tag
标签推送,才会触发这个管道。 deploy
的script
里有两条命令,一条是更改密钥文件的权限,一条是ssh登录到远程服务器,然后执行sed更改docker-compose.yml文件的image镜像tag版本号,然后去启动。-o StrictHostKeyChecking=no
确保绕过是否信任这个问题。无论您是否信任远程主机,这个问题在管道等非交互式上下文中无法回答。
推送到 gitlab后,就可以看到这个Pipelines在等待执行:
接下来点操作就可以了。
这里主要注意的地方就是,因为在.gitlab-ci.yml
中,是以普通用户执行sed更新docker-compose.yml
文件的。sed
修改文件需要在当前目录有写权限,因为sed原理是在当前目录创建一个临时文件,修改临时文件,然后用修改好的临时文件替换源文件,然后删除临时文件。所以目标机器的这个文件和这个目录,也需要有这个普通用户的w
写入权限。
如果这个目录没有写入权限的话,就会报couldn't open temporary file
的错误。