有时候我们需要使用gitlab-runner来执行构建任务,GitLab Runner 可以安装到不同的机器上,Runner可以安装在独立的vm内,也可以安装在容器内,所以在构建任务运行期间并不会影响到 GitLab 的性能。

    image.png

    比如我们需要将Dockerfile打包成一个镜像推送到私有镜像仓库,这里的docker build就需要executor容器,而这种容器需要的镜像gcr.azk8s.cn/kaniko-project/executor:debug 国内服务访问

    1. .....
    2. build:image:
    3. stage: package
    4. image: gcr.azk8s.cn/kaniko-project/executor:debug
    5. dependencies:
    6. - build:jar
    7. script:
    8. - |
    9. docker build $CI_PROJECT_DIR \
    10. -t $IMAGE:$IMAGE_TAG \
    11. -t $IMAGE:latest
    12. - docker push $IMAGE:$IMAGE_TAG
    13. - docker push $IMAGE:latest
    14. ......

    或者我们需要使用docker和shell 执行器,这个时候我们可以采用kubernetes 中部署gitlab-runner + 服务器部署gitlab-runner,由服务器上的runner负责执行docker build任务。

    下面是服务器上的gitlab-runner的配置文件config.toml,我们需要在gitlab-runner所在的服务器要安装docker,需要把服务器的docker.sock挂载到gitlab-runner中,这样我们才能在runner中执行docker命令。

    concurrent = 8
    check_interval = 0
    
    [session_server]
      session_timeout = 1800
    
    [[runners]]
      name = "docker-runner"
      url = "http://139.195.25.104/"
      token = "4CE3r***m6yFyiyg"
      executor = "shell"
    
      [runners.custom_build_dir]
      [runners.cache]
        Type = "s3"
        Shared = true
        [runners.cache.s3]
          ServerAddress = "storage.****.art"
          AccessKey = "LTAI****1rWf"
          SecretKey = "d3v*******dVYG"
          BucketName = "gitlab-runner-caches"
          Insecure = true
        [runners.cache.gcs]
        [runners.cache.azure]
      [runners.docker]
        tls_verify = false
        image = "docker:latest"
        privileged = true
        volumes = ["/var/run/docker.sock:/var/run/docker.sock","/cache:/cache"]
    

    当然有了上面的还是不够的,比如执行中可能会报错

    ”Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.26/images/json: dial unix /var/run/docker.sock: connect: permission denied“
    

    之所以会出现上面的报错是因为gitlab-runner会以普通用户运行,而他没有操作docker命令
    解决方法:

    1. 查看gitlab-runner执行时使用的用户名

      $ echo $USER
      

      image.png

    2. 赋予用户权限 ```go docker守护进程启动的时候,会默认赋予名字为docker的用户组读写Unix socket的权限,因此只要创建docker用户组,并将当前用户加入到docker用户组中,那么当前用户就有权限访问Unix socket了,进而也就可以执行docker相关命令

    sudo groupadd docker #添加docker用户组 sudo gpasswd -a $USER docker #将登陆用户加入到docker用户组中 newgrp docker #更新用户组 docker ps #测试docker命令是否可以使用sudo正常使用

    当然还有更简单更快速的方法就是给其他用户也赋予读写权限 chmod a+rw /var/run/docker.sock

    [官网](https://docs.gitlab.com/ee/ci/docker/using_docker_build.html)提供了完整的解决方法
    ```go
    Use Docker to build Docker images
    
    #ref:https://docs.gitlab.com/ee/ci/docker/using_docker_build.html
    
    Use the shell executor
    To include Docker commands in your CI/CD jobs, you can configure your runner to use the shell executor. In this configuration, the gitlab-runner user runs the Docker commands, but needs permission to do so.
    
    1、Install GitLab Runner.
    2、Register a runner. Select the shell executor. For example:
    
    sudo gitlab-runner register -n \
      --url https://gitlab.com/ \
      --registration-token REGISTRATION_TOKEN \
      --executor shell \
      --description "My Runner"
    
    3、On the server where GitLab Runner is installed, install Docker Engine. View a list of supported platforms.【https://docs.docker.com/engine/install/】
    
    4、Add the gitlab-runner user to the docker group:
    
    sudo usermod -aG docker gitlab-runner
    
    5、Verify that gitlab-runner has access to Docker:
    
    sudo -u gitlab-runner -H docker info
    
    6、In GitLab, to verify that everything works, add docker info to .gitlab-ci.yml:
    
    before_script:
      - docker info
    
    build_image:
      script:
        - docker build -t my-docker-image .
        - docker run my-docker-image /script/to/run/tests
    
    You can now use docker commands (and install docker-compose if needed).
    

    在我们推送构建完的镜像到私有镜像仓库时,会出现无法推送,推送拒绝的情况,下面提供官网提供方法

    Authenticate with registry in Docker-in-Docker
    
    
    Option 1: Run docker login
    In before_script, run docker login:
    
    image: docker:19.03.13
    
    variables:
      DOCKER_TLS_CERTDIR: "/certs"
    
    services:
      - docker:19.03.13-dind
    
    build:
      stage: build
      before_script:
        - echo "$DOCKER_REGISTRY_PASS" | docker login $DOCKER_REGISTRY --username $DOCKER_REGISTRY_USER --password-stdin
      script:
        - docker build -t my-docker-image .
        - docker run my-docker-image /script/to/run/tests
    

    我们可以把这里用到的DOCKER_REGISTRY_PASS等变量加入到gitlab的变量中,如下
    image-20210816163552359.png