gitlab-runner 安装使用

安装前环境准备-docker为例

docker与docker-compose安装

docker参考

docker-compose参考

docker安装

  • 选择安装版本,以 linux 的 centos 为例访问docker官网 、点击docker for linux:

  • 选择centos版本

  • 先决条件:要安装Docker Engine,您需要一个CentOS 7的维护版本。不支持或未测试存档版本

  • 卸载旧版本

    $ sudo yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-engine

    如果yum报告未安装这些软件包, 说明无需关注、可以直接走下一步安装。

  • 设置存储库:首次安装Docker Engine之前,需要设置Docker存储库

    安装yum-utils软件包(提供yum-config-manager 实用程序)并设置稳定的存储库

    $ sudo yum install -y yum-utils
    ​
    $ sudo yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
  • 安装docker引擎,我们这里安装最新版, 需要特定版本可参考官网

    $ sudo yum install docker-ce docker-ce-cli containerd.io
  • 启动Docker

    $ sudo systemctl start docker
  • 通过运行hello-world 映像来验证是否正确安装了Docker Engine

    sudo docker run hello-world

    会输出hello word信息 即代表成功。

  • 设置docker开启自启动

    # 允许开机启动
    $ sudo systemctl enable docker
    # 状态检查
    $ sudo systemctl status docker
    

docker-compose安装

  • 前提条件:Docker Compose依靠Docker Engine进行有意义的工作,请确保有安装Docker Engine

  • 安装版本选择

  • 直接使用crul方式安装 卸载方便

    sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  • 给docker-compose添加可执行权限

    sudo chmod +x /usr/local/bin/docker-compose
  • 卸载:(通过curl方式安装卸载)

    sudo rm /usr/local/bin/docker-compose

gitlab-runner安装配置

docker-compose.yaml文件编写

version: "2"
​
services:
  runner:
    image: gitlab/gitlab-runner:latest
    container_name: gitlab-runner
    restart: always
    environment:
        TZ: Asia/Shanghai
    volumes:
      - /docker/gitlab-runner/config:/etc/gitlab-runner
      - /var/run/docker.sock:/var/run/docker.sock

注意:如果runner executor 为docker 、必须挂载 /var/run/docker.sock:/var/run/docker.sock

 

安装&&使用gitlab-runner

配置runner参考

example

  • 安装前准备

    1. mkdir /root/docker

    2. 将上述docker-compose.yaml文件拷贝到/root/docker目录下

    3. 运行gitlab-runner

      docker-compose up -d
    4. 查看日志

      docker logs gitlab-runner
  • 注册gitlab-runner到gitlab、先查看gitlabrunner 的token

    获取token和注册需要的域名或者ip都可

     

  • 注册gitlab-runner

    $ docker exec -it gitlab-runner gitlab-runner register
    Runtime platform                                    arch=amd64 os=linux pid=35 revision=ce065b93 version=12.10.1
    Running in system-mode.
    ​
    Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
    # https://gitlab.com # 你的gitlab的域名或ip
    Please enter the gitlab-ci token for this runner:
    # 89Gz************ # 上面从项目中获取的token值
    Please enter the gitlab-ci description for this runner:
    [9e4cbb00ddf2]: # my-runner # 自定义的runner描述 
    Please enter the gitlab-ci tags for this runner (comma separated):
    # demo # 自定义的tag ci可以根据tag执行任务,可在ci中设置 默认启用tag 如果任务未添加tag 会pending
    Registering runner... succeeded                     runner=89GziSKQ
    Please enter the executor: docker, docker-ssh, shell, kubernetes, docker+machine, docker-ssh+machine, custom, parallels, ssh, virtualbox:
    # docker # 选择executor类型 这里采用docker
    Please enter the default Docker image (e.g. ruby:2.6):
    # golang:1.14.2 # 默认的镜像 因为是go所以选择go的
    Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

    再次查看日志 现在未继续报错了

    Configuration loaded                                builds=0
  • gitlab-runner设置

    如果允许未设置tag的任务运行 需要在runner里面设置

    允许没有tag的任务运行、否则没有tag的任务会 进入pending 状态

gitlab-runner config.toml配置

配置文件路径 与在yaml文件路径下 /docker/gitlab-runner/config/config.toml

# cat config.toml
concurrent = 1
check_interval = 0
​
[session_server]
  session_timeout = 1800
​
[[runners]]
  name = "my-runner"
  url = "https://gitlab.****.com"
  token = "dWza**********"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
  [runners.docker]
    tls_verify = false
    image = "golang:1.14.2"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache", "/root/docker/gitlab-runner/gztar/.tar:/root/.tar","/root/.ssh:/root/.ssh:ro"]
    pull_policy = "if-not-present"
    shm_size = 0

这里volumes挂载了cache目录以及设置了默认拉取的镜像文件

   # 配置从本地获取镜像 加快ci & cd速度
   volumes = ["/root/docker/gitlab-runner/gztar/.tar:/root/.tar"]
   # 会首先从本地获取镜像 本地没有才会从hub上拉取镜像
   pull_policy = "if-not-present" 
   
   # --------------
   # 可选 映射本机的秘钥到docker里面的docker里面、 可用于ssh 部署之类
   volumes = ["/root/.ssh:/root/.ssh:ro"] # ro只读 不允许修改宿主机的秘钥信息

ssh部署可参考

gitlab-yaml

注意:

  url = "https://gitlab.****.com" # gitlab的地址
  token = "dWza**********"        # gitlab的token 

附:docker镜像导入导出命令

# 导出镜像
docker save -o /root/docker/gitlab-runner/gztar/golang.tar golang:latest
# 导入镜像
docker load -i /root/docker/gitlab-runner/gztar/golang.tar 
​
# 另外一种方式
docker save golang:latest > /root/docker/gitlab-runner/gztar/golang.tar
docker load < /root/docker/gitlab-runner/gztar/golang.tar

gitlab-runner 知识点

Runner间隔多久去GitLab上检查是否有job

config.toml文件的check_interval字段会决定这个时间间隔,它的默认值是3秒(注意当你把它设为0时依然采用的是默认值3秒,而不是0秒)

要解释它的意义,首先我们先来定义worker,在config.toml文件中定义了很多runner,它们可能executor类型不同,可能注册地址不同,但都是由GitLab Runner这个服务来管理的,为了与GitLab Runner区分开,我们将config.toml文件中定义的runner称为worker

对于不同的worker,worker之间(如worker A ---> worker B)的间隔为check_interval / worker_nums,但是对于worker A本身来说它下次去检查是否有job的时间间隔仍为check_interval

举个简单例子:config.toml定义了3个worker—— worker A, worker B 和 worker C,check_interval采用默认值为3秒,第0秒时worker A会去检查是否有属于自己的job,第1秒时worker B会去检查,第2秒时worker C去检查,第3秒时worker A再检查……这个过程中worker A到worker B的间隔为3 / 3 = 1秒,而对于worker A下次检查job时的时间间隔为check_interval,即3秒。

官方文档对check_interval的解释:https://docs.gitlab.com/runner/configuration/advanced-configuration.html#how-check_interval-works。

config.toml里的concurrent字段的意义

concurrent限制了整个GitLab Runner能并发处理job的数量。特别注意concurrentworker数量无任何关系,所有worker的工作是受GitLab Runner控制的,如果concurrent值为1并且有一个worker已经在工作了,那么即使其他worker达到了可以工作的条件也只能“pending”。

cache存储在哪里

参考https://docs.gitlab.com/ee/ci/caching/#where-the-caches-are-stored

怎样清除cache

注意cache是没有过期时间的,而且每一次新的push触发的pipeline,都会重新生成cache,重新生成的cache的名字为“-”,其中num是随着push数量递增的。如果不去清除cache,cache会永久保留在Runner上,日积月累会填满存储空间的,因此最好隔一段时间进行一次清除,清除方法请参考https://docs.gitlab.com/ee/ci/caching/#clearing-the-cache,或者使用clear_volumes.sh 这个简单脚本来处理它, 清除cache的原理是将相关的volume移除,当然,docker也有自带的清除命令,推荐将docker system prune -f --volumes加入到定时任务中。

GitLab Runner 变量的优先级

参考https://docs.gitlab.com/ee/ci/variables/#priority-of-environment-variables

GitLab Runner有哪些预定义的变量

参考https://docs.gitlab.com/ee/ci/variables/#predefined-variables-environment-variables

当使用Runner采用docker作为executor时,无法build docker image

这是个dind(docker in docker) 问题,一般pipeline会报如下错误:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
time="2018-12-17T11:12:33Z" level=error msg="failed to dial gRPC: cannot connect to the Docker daemon. Is 'docker daemon' running on this host?: dial unix

可以将本地的docker socket绑定到container里来解决

在配置文件config.toml里添加volumes = ["/var/run/docker.sock:/var/run/docker.sock"]

可参考https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-in-docker-executor。

如何在job所对应的container里使用git clone命令

如果想在job运行期间clone代码(如shell或python的脚本),首先要确保你的宿主机有权限clone代码,然后将将你的secret挂载到container里。

例如,通过git/ssh的方式克隆代码,若ssh目录为/root/.ssh,可以在config.toml文件里添加如下配置:

volumes = ["/root/.ssh:/root/.ssh:ro"]

ro表示容器只有可读权限 避免修改秘钥。

常用的预定义的变量

名称 说明
$CI_PROJECT_NAME 项目名称
$CI_PROJECT_NAMESPACE 组名称
$CI_PROJECT_PATH 项目相对路径
$CI_PROJECT_URL 项目URL地址
$GITLAB_USER_NAME 用户名称
$GITLAB_USER_EMAIL 用户邮箱
$CI_PROJECT_DIR 项目绝对路径
$CI_PIPELINE_ID 流水线ID
$CI_COMMIT_REF_NAME 当前分支

go Makefile 常用集成

通过Makefile简单集成单元测试 覆盖率测试 及覆盖率报告

.PHONY: clean test coverage coverhtml build help lint
​
PROJECT_NAME := "code"
PKG_LIST := $(shell go list ./... | grep -v /vendor/)
​
all: build
​
test: ## Run unittests
    @go test -v ${PKG_LIST}
​
race: ## Run data race detector
    @go test -race -short ${PKG_LIST}
​
coverage: ## Generate global code coverage report
    coverage_test
    
coverhtml: ## Generate global code coverage report in HTML
    coverage_test html
​
build: ## Build the binary file
    @go build -i -v -o _${PROJECT_NAME} ./...
​
lint: ## Lint the files
    @golint -set_exit_status ${PKG_LIST}
​
clean:
    rm -rf _${PKG_LIST}
​
help: ## Display this help screen
    @grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
​
SHELL=bash
define BASH_FUNC_coverage_test%%
() {
    # Code coverage generation
    COVERAGE_DIR="${COVERAGE_DIR:-coverage}"
​
    # Create the coverage files directory
    mkdir -p "$COVERAGE_DIR";
​
    # Create a coverage file for each package
    for package in ${PKG_LIST}; do
        go test -covermode=count -coverprofile "./${COVERAGE_DIR}/${package##*/}.cov" "$$package" ;
    done ;
​
    # Merge the coverage profile files
    echo 'mode: count' > "./${COVERAGE_DIR}"/coverage.cov ;
    tail -q -n +2 "./${COVERAGE_DIR}"/*.cov >> "./${COVERAGE_DIR}"/coverage.cov ;
​
    # Display the global code coverage
    go tool cover -func="./${COVERAGE_DIR}"/coverage.cov ;
​
    # If needed, generate HTML report
    if [ "$1" == "html" ]; then
        go tool cover -html="./${COVERAGE_DIR}"/coverage.cov -o coverage.html ;
    fi
​
    # Remove the coverage files directory
    rm -rf "$COVERAGE_DIR";
}
endef
export BASH_FUNC_coverage_test%%
​

 

.gitlab-ci.yaml配置(优化后)

image: golang:1.14.2
variables:
  PROJECT_NAME: "_code"
  DEV_HOST: "测试机器ip"
  DEV_PATH: "部署路径"
  PRD_HOST: "线上机器ip"
  PRD_PATH: "部署路径"
​
stages: 
  - test
  - build
  - deploy
​
before_script:
  - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
  - eval $(ssh-agent -s)
  - mkdir -p /go/src/$GITLAB_USER_NAME /go/src/_/builds
  - cp -r $CI_PROJECT_DIR /go/src/$GITLAB_USER_NAME/$CI_PROJECT_NAME
  - ln -s /go/src/$GITLAB_USER_NAME /go/src/_/builds/$GITLAB_USER_NAME
​
unit_tests:
  stage: test
  script: 
    - make test
  tags: 
    - demo
​
race_detector:
  stage: test
  script:
    - make race
​
code_coverage:
  stage: test
  script:
    - make coverage
​
code_coverage_report:
  stage: test
  script:
    - make coverhtml
  only:
  - master
​
build:dev:
  stage: build
  script:
    - go build -i -v -o ${PROJECT_NAME} ./...
  artifacts:
    expire_in: 1 week
    paths:
      - $PROJECT_NAME
  only:
    - dev
​
build:master:
  stage: build
  script:
    - go build -i -v -o ${PROJECT_NAME} ./...
  artifacts:
    expire_in: 1 week
    paths:
      - $PROJECT_NAME
  only: 
    - master
​
deploy:dev:
  stage: deploy
  script:
    - echo "=====start dev deploy======"
    - scp -r $PROJECT_NAME root@$DEV_HOST:$DEV_PATH
    - ssh root@$DEV_HOST "cd $DEV_PATH; ./$PROJECT_NAME >> dev.log"
    - echo "=====end dev deploy======"
  only:
    - dev
  when: manual
  environment: test
  dependencies:
    - build:dev
  
deploy:master:
  stage: deploy
  script:
    - echo "=====start deploy======"
    - scp -r $PROJECTNAME root@$DEV_HOST:$DEV_PATH
    - ssh root@$DEV_HOST "cd $DEV_PATH; ./$PROJECT_NAME >> master_test.log"
    - echo "=====end deploy======"
  only:
    - master
  when: manual
  environment: production
  dependencies:
    - build:master

验证.gitlab-ci.yml文件的内容:进入项目仓库->CI/CD->作业->CI Lint,示例如下:

gitlab-runner 安装使用_第1张图片

gitlab-runner 安装使用_第2张图片

你可能感兴趣的:(gitlab,git,CD/CD\,DevOps)