Gitlab CI-Kubernetes执行器使用docker/podman/makisu/buildah/kaniko



我使用gitlab CI runner执行CI作业,gitlab cirunner配置有kubernetes executor,实际上在openshift上运行。我希望能够将docker映像构建到dockerfiles,但有以下限制:

  1. runner(openshift pod)以用户身份运行,具有高且随机的uid(例如2341311111111)
  2. runner pod没有特权
  3. 没有群集管理权限,或无法重新配置运行程序

显然DinD无法工作,因为它需要特殊的docker设备配置。Podman、kaniko、buildah、buildkit和makisu不适用于随机的非root用户,并且没有任何卷。有什么建议吗?

DinD(Docker中的Docker)在OpenShift 4 gitlab runner中工作。。。刚刚成功,而且。。。打架!事实上,该解决方案对于其他版本的任何更改都是极其脆弱的。例如,我刚刚尝试将docker:220.10.16替换为docker:最新或docker:稳定,结果失败了。

以下是我使用的配置,它在其中起作用:

  1. OpenShift 4.12
  2. 通过OpenShift Cluster网络控制台/OperatorHub安装的RedHat认证的GitLab Runner操作员;它的特点是gitlab runner v 14.2.0
  3. 码头工人:20.10.16&码头工人:20.10.16

参考文档:

  1. GitLab Runner Operator安装指南:https://cloud.redhat.com/blog/installing-the-gitlab-runner-the-openshift-way
  2. 转轮配置详细信息:https://docs.gitlab.com/runner/install/operator.html和https://docs.gitlab.com/runner/configuration/configuring_runner_operator.html
  3. 这是一个关于匹配管道和流道设置的关键问题:https://docs.gitlab.com/ee/ci/docker/using_docker_build.html这实际上是您在gitlab.gitlab-ci.yml管道定义和运行程序配置config.toml文件中的设置所要遵循的

安装步骤:

  1. 按照上面参考文件中的文档1和2在OpenShift中安装Gitlab Runner Operator,但还没有从操作员实例化Runner

  2. 在gitlab服务器上,复制组范围或项目范围内跑步者注册的跑步者注册令牌

  3. elswhere在安装了oc CLI的终端会话中,通过"oc"CLI登录到openshift集群,例如让cluster:admin或system:admin角色

  4. 创建一个类似于的OpenShift秘密

    vi gitlab-runner-secret.yml

    apiVersion: v1
    kind: Secret
    metadata:
    name: gitlab-runner-secret
    namespace: openshift-operators
    type: Opaque
    stringData:
    runner-registration-token: myRegistrationTokenHere
    

    oc apply -f gitlab-runner-secret.yml

  5. 创建自定义配置映射;请注意,OpenShift操作符将所提供的内容与gitlab runner操作符本身生成的config.toml的内容合并;因此,我们只提供我们想要补充的字段(我们甚至不能覆盖现有的字段值)。还要注意的是,执行器被预设为"0";kubernetes";OC运营商。有关详细了解,请参阅上面的文档。

    vi gitlab-runner-config-map.toml

    [[runners]]  
    [runners.kubernetes]
    host = ""
    tls_verify = false
    image = "alpine"
    privileged = true
    [[runners.kubernetes.volumes.empty_dir]]
    name = "docker-certs"
    mount_path = "/certs/client"
    medium = "Memory"
    

    oc create configmap gitlab-runner-config-map --from-file config.toml=gitlab-runner-config-map.toml

  6. 创建一个由操作员部署的Runner(调整url)

    ​vi gitlab-runner.yml

    apiVersion: apps.gitlab.com/v1beta2
    kind: Runner
    metadata:
    name: gitlab-runner
    namespace: openshift-operators
    spec:
    gitlabUrl: https://gitlab.example.com/
    buildImage: alpine
    token: gitlab-runner-secret
    tags: openshift, docker
    config: gitlab-runner-config-map
    

    oc apply -f gitlab-runner.yml

  7. 然后,您将看到刚刚通过openshift控制台创建的runner(已安装的操作员>gitlab runner>gitlab runer选项卡),然后是PoD的自动创建(请参阅工作负载)。您甚至可以在PoD上输入一个终端会话,并键入例如:gitlab-runner list以查看config.toml文件的位置。您还可以在gitlab repo服务器控制台上看到在组或项目级别列出的runner。当然,OC集群和gitlab服务器之间的防火墙可能会破坏您在这一点上的努力。。。

  8. 技巧的其余部分发生在.gitlab-ci.yml文件中,例如(摘录在某个阶段只显示一个作业)。有关详细理解,请参阅上文中的文件Nb 3。变量MY_ARTEFACT指向相关git项目/repo中的子目录,其中包含您已经在IDE中成功执行的Dockerfile;并且REPO_ PATH保存包括docker Hub存储库路径和一些额外名称片段的公共前缀字符串。你可以根据自己的方便调整所有这些,但不要编辑本工作中定义的前4个变量中的任何一个,也不要更改docker[dind]版本;它会破坏一切。

    my_job_name:
    stage: my_stage_name
    tags:
    - openshift # to run on specific runner
    - docker
    image: docker:20.10.16
    variables:
    DOCKER_HOST: tcp://docker:2376
    DOCKER_TLS_CERTDIR: "/certs"
    DOCKER_TLS_VERIFY: 1
    DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
    REPO_TAG: ${REPO_PATH}-${MY_ARTEFACT}:${IMAGE_TAG}
    services:
    - docker:20.10.16-dind
    before_script:
    - sleep 10 && docker info #give time for starting the service and confirm good setup in logs
    - echo $DOKER_HUB_PWD | docker login -u $DOKER_HUB_USER --password-stdin
    script:
    - docker build --network host -t $REPO_TAG ./$MY_ARTEFACT
    - docker push $REPO_TAG
    

好了,触发gitlab管道。。。

如果您错过了任何配置,您将收到通常的错误消息";docker守护进程正在运行吗"在关于无法访问"/var/run/docker.sock";或连接到";tcp://localhost:2375"。不不!端口2376不是打字错误,而是要在上面的步骤8中使用的确切值。

到目前为止还不错吗。。。还没有!

安全设置:

好吧,你现在可能会看到你的docker构建开始了(意味着D-in-D是可以的),然后为了安全起见失败了(或者被锁定了)。尽管我们在步骤5:中设置了"privileged=true">

Docker有一个令人讨厌但简单的(内置的)功能:它在构建的每个容器中默认以"root"的身份运行,并用于构建容器。另一方面,OpenShift的构建考虑到了严格的安全性,并将阻止任何pod以root身份运行。

因此,我们必须更改安全设置,使这些运行者能够在特权模式下执行,这就是为什么将这些权限限制在命名空间中很重要的原因,这里是"openshift operators">特定帐户"gitlab runner sa"。

`oc adm policy add-scc-to-user privileged -z gitlab-runner-sa -n openshift-operators`

以上操作将创建一个RoleBinding,您可以根据需要删除或更改它。事实是,"gitlab runner sa"是gitlab runner Operator用于实例化runner pod的服务帐户,"-z"表示将权限设置目标设置为服务帐户(而不是常规用户帐户)-n'引用了我们在这里使用的特定命名空间。

因此,您现在可以构建图像。。。。但当将这些图像导入OpenShift项目并尝试执行生成的pod时,仍然可能失败。预计有两个限制:

  1. OpenShift将阻止任何需要以"root"身份运行的映像,即在特权模式下运行(docker运行和docker组合中的默认模式)==>因此,请确保您将在DOCKER中使用DOCKER构建的所有映像都可以使用dockerfile指令USER <uid>:<gid>作为非root用户运行!

  2. 。。。但以上可能还不够!实际上,默认情况下,OpenShift生成一个随机用户ID来启动容器,并忽略docker构建中设置为USER <uid>:<gid>的用户ID。为了有效地允许容器切换到定义的用户,您必须将运行您的pod的服务帐户绑定到";anyuid">安全上下文约束。这很容易通过角色绑定实现,否则oc CLI:中的命令

    oc adm policy add-scc-to-user anyuid -n myProjectName -z default

    其中-z表示-n命名空间中的服务帐户。

最新更新