Docker 中的 Docker/Podman 作为 GitLab CI 作业失败

Docker 中的 Docker/Podman 作为 GitLab CI 作业失败

语境

我正在运行自己的 GitLab 实例,并为 CI 配备了额外的服务器。如果这很重要,我的 gitlab 运行器的主机有 CentOS 8,gitlab 运行器的版本是 14.4.0,gitlab 实例正在运行 14.4.1。我目前在 CI 服务器上使用 shell 执行器,但想切换到 docker 执行器。

Gitlab Runner 配置

我的/etc/gitlab-runner/config.toml样子是这样的:

concurrent = 1
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "the old shell executor"
  url = "https://XXXXXXXXXXXXXXXXXXXXXX/"
  token = "XXXXXXXXXXXXXXXXXXXX"
  executor = "shell"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]

[[runners]]
  name = "the new docker executor"
  url = "https://XXXXXXXXXXXXXXXXXXXXXX/"
  token = "XXXXXXXXXXXXXXXXXXXX"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "docker.io/centos:7"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
    network_mode = "host"
    shm_size = 0

shell 执行器已标记shell,docker 执行器已标记,docker因此我可以从 gitlab-ci.yml 文件决定在何处运行我的构建。

gitlab-ci.yml

.template:
  before_script:
    - cat /proc/sys/user/max_user_namespaces
  script:
    - $ENGINE login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
    - $ENGINE build -f container/php-71.dockerfile -t "$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/$TAG:$CI_PIPELINE_ID" .
    - $ENGINE push "$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/$TAG:$CI_PIPELINE_ID"

build-with-docker-in-shell-executor:
  extends: .template
  variables:
    ENGINE: docker
    TAG: build-with-docker
  tags: [shell]
build-with-docker-in-docker-executor:
  extends: .template
  image: docker:dind
  variables:
    ENGINE: docker
    TAG: build-with-docker-in-docker
  tags: [docker]
build-with-podman-in-docker-executor:
  extends: .template
  image: quay.io/podman/stable
  variables:
    ENGINE: podman
    TAG: build-with-podman-in-docker
  tags: [docker]

我的container/php-71.dockerfile很简单,它使用centos:7并执行了一堆yum install命令:

FROM docker.io/centos:7
RUN yum install -y epel-release centos-release-scl
RUN yum install -y rh-php71

第一个作业失败了,因为我的 gitlab runner 用户无权访问 docker sockt:

Got permission denied while trying to connect to the Docker
daemon socket at unix:///var/run/docker.sock: Post
"http://%2Fvar%2Frun%2Fdocker.sock/v1.24/auth": dial unix
/var/run/docker.sock: connect: permission denied

我认为这样没问题(或者现在建议向非 root 用户授予对 docker 的访问权限?)。因此,此工作仅供参考。

docker 中的 docker 作业失败,因为 yum 似乎没有网络访问权限:

Step 1/3 : FROM docker.io/centos:7
 ---> eeb6ee3f44bd
Step 2/3 : RUN yum install -y epel-release centos-release-scl
 ---> Running in 8e41cd05bcc1
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=container error was
12: Timeout on http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=container: (28, 'Resolving timed out after 30548 milliseconds')
 One of the configured repositories failed (Unknown),
 and yum doesn't have enough cached data to continue. At this point the only
 safe thing yum can do is fail. There are a few ways to work "fix" this:
     1. Contact the upstream for the repository and get them to fix the problem.
     2. Reconfigure the baseurl/etc. for the repository, to point to a working
        upstream. This is most often useful if you are using a newer
        distribution release than is supported by the repository (and the
        packages for the previous distribution release still work).
     3. Run the command with the repository temporarily disabled
            yum --disablerepo=<repoid> ...
     4. Disable the repository permanently, so yum won't use it by default. Yum
        will then just ignore the repository until you permanently enable it
        again or use --enablerepo for temporary usage:
            yum-config-manager --disable <repoid>
        or
            subscription-manager repos --disable=<repoid>
     5. Configure the failing repository to be skipped, if it is unavailable.
        Note that yum will try to contact the repo. when it runs most commands,
        so will have to try and fail each time (and thus. yum will be be much
        slower). If it is a very temporary problem though, this is often a nice
        compromise:
            yum-config-manager --save --setopt=<repoid>.skip_if_unavailable=true
Cannot find a valid baseurl for repo: base/7/x86_64
The command '/bin/sh -c yum install -y epel-release centos-release-scl' returned a non-zero code: 1

docker 中的 podman 是所有错误中最奇怪的,它在podman login命令中就已经失败了:

time="2021-11-01T13:34:31Z" level=warning msg="\"/\" is not a shared mount, this could cause issues or missing mounts with rootless containers"
cannot clone: Operation not permitted
Error: cannot re-exec process

问题

我想使用 docker 中的 podman 或 docker 中的 docker 来构建我的镜像。我可以采取哪些步骤来调试和修复这个问题?

答案1

我发现卡尼科现在我正在用它构建我的容器。我的 gitlab CI 模板如下所示:

.build-container-with-kaniko:

  stage: build-containers

  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]

  script:
    - mkdir -p /kaniko/.docker
    # this is needed to push the final image back to the container registry on gitlab
    - AUTH="$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')"
    - echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"${AUTH}\"}}}" > /kaniko/.docker/config.json
    - >-
      /kaniko/executor
      --context "${CI_PROJECT_DIR}"
      --dockerfile "${CI_PROJECT_DIR}/${DOCKERFILE}"
      --destination "${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${CI_PIPELINE_ID}"
      --destination "${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${CI_COMMIT_TAG:-latest}"
      ${EXTRA_ARGS}

  variables:
    DOCKERFILE: Dockerfile
    IMAGE_NAME: generic-image
    EXTRA_ARGS: ""

  tags:
    - docker

tags: [docker]意味着我在 gitlab runner 的 docker 执行器上运行这些作业。

相关内容