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-runnerdocker-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-runnergitlab-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后的信息如下:
gitlab_runner_list

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_rsaid_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 的接管。
gitlab_runner_assigned_projects.png

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_IMAGECI_REGISTRY_IMAGE分开两个,是因为推送镜像地址和客户机下载镜像的地址不是同一个,所以分开两个。
  • 这里variables中的SERVER_IPSERVER_USERTARGET_DIRCOMPOST_FILE,分别是服务器的IP、操作的用户、目标服务器的目录、compose文件名。
  • 两个stageswhen都是设置成manual,在gitlab页面上手动点启动。
  • 都是只有在打了tag标签推送,才会触发这个管道。
  • deployscript里有两条命令,一条是更改密钥文件的权限,一条是ssh登录到远程服务器,然后执行sed更改docker-compose.yml文件的image镜像tag版本号,然后去启动。
  • -o StrictHostKeyChecking=no确保绕过是否信任这个问题。无论您是否信任远程主机,这个问题在管道等非交互式上下文中无法回答。

推送到 gitlab后,就可以看到这个Pipelines在等待执行:
gitlab_runner_pipeline
接下来点操作就可以了。

这里主要注意的地方就是,因为在.gitlab-ci.yml中,是以普通用户执行sed更新docker-compose.yml文件的。sed修改文件需要在当前目录有写权限,因为sed原理是在当前目录创建一个临时文件,修改临时文件,然后用修改好的临时文件替换源文件,然后删除临时文件。所以目标机器的这个文件和这个目录,也需要有这个普通用户的w写入权限。
如果这个目录没有写入权限的话,就会报couldn't open temporary file的错误。