3

我们想以最简单的方式使用Paketo.io / CloudNativeBuildpacks (CNB) GitLab CI 。我们的 GitLab 设置使用 AWS EKS 集群,该集群具有利用Kubernetes executor 的非特权 GitLab CI Runners 。我们也不想通过在我们的构建中使用 Docker 来引入安全风险。所以我们没有/var/run/docker.sock暴露我们的主机也不想使用docker:dind.

我们找到了一些关于如何将 Paketo 与 GitLab CI 一起使用的指南,例如https://tanzu.vmware.com/developer/guides/gitlab-ci-cd-cnb/。但正如标题下方所述Use Cloud Native Buildpacks with GitLab in GitLab Build Job WITHOUT Using the GitLab Build Template,该方法依赖于 Docker 和 pack CLI。我们试图在我们.gitlab-ci.yml的看起来像这样:

image: docker:20.10.9

stages:
  - build

before_script:
  - |
    echo "install pack CLI (see https://buildpacks.io/docs/tools/pack/)"
    apk add --no-cache curl
    (curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.21.1/pack-v0.21.1-linux.tgz" | tar -C /usr/local/bin/ --no-same-owner -xzv pack)

build-image:
  stage: build
  script:
    - pack --version
    - >
      pack build $REGISTRY_GROUP_PROJECT/$CI_PROJECT_NAME:latest
      --builder paketobuildpacks/builder:base
      --path . 

但正如概述的那样,我们的设置不支持 docker,我们最终在日志中出现以下错误:

...
$ echo "install pack CLI (see https://buildpacks.io/docs/tools/pack/)" # collapsed multi-line command
install pack CLI (see https://buildpacks.io/docs/tools/pack/)
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz
(1/4) Installing brotli-libs (1.0.9-r5)
(2/4) Installing nghttp2-libs (1.43.0-r0)
(3/4) Installing libcurl (7.79.1-r0)
(4/4) Installing curl (7.79.1-r0)
Executing busybox-1.33.1-r3.trigger
OK: 12 MiB in 26 packages
pack
$ pack --version
0.21.1+git-e09e397.build-2823
$ pack build $REGISTRY_GROUP_PROJECT/$CI_PROJECT_NAME:latest --builder paketobuildpacks/builder:base --path .
ERROR: failed to build: failed to fetch builder image 'index.docker.io/paketobuildpacks/builder:base': Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
Cleaning up project directory and file based variables 00:01
ERROR: Job failed: command terminated with exit code 1

关于如何在 GitLab CI 中使用 Paketo Buildpacks 而不在我们的 GitLab Kubernetes 运行器中存在 Docker 的任何想法(这似乎是一种最佳实践)?我们也不希望我们的设置变得复杂——例如通过添加kpack

4

1 回答 1

4

TLDR;

直接在你这里使用 Buildpack 的生命周期.gitlab-ci.yml 是一个完整的工作示例):

image: paketobuildpacks/builder

stages:
  - build

# We somehow need to access GitLab Container Registry with the Paketo lifecycle
# So we simply create ~/.docker/config.json as stated in https://stackoverflow.com/a/41710291/4964553
before_script:
  - mkdir ~/.docker
  - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_JOB_TOKEN\"}}}" >> ~/.docker/config.json

build-image:
  stage: build
  script:
    - /cnb/lifecycle/creator -app=. $CI_REGISTRY_IMAGE:latest

细节:“直接使用生命周期”

关于这个话题的讨论正在进行中。特别是看看https://github.com/buildpacks/pack/issues/564https://github.com/buildpacks/pack/issues/413#issuecomment-565165832。如那里所述:

如果您希望在 CI(而不是本地)中构建映像,我鼓励您直接使用生命周期,这样您就不需要 Docker。这是一个例子:

该示例的链接已损坏,但它指的是关于如何在 Kubernetes 环境中使用 buildpacks的Tekton实现。在这里,我们可以得到关于斯蒂芬莱文所说的第一个胶水。其中最关键的是. 所以这就是每个人都在谈论的生命周期!在这个 CNB RFC中可以找到关于这个命令的很好的文档。"to use the lifecycle directly"command: ["/cnb/lifecycle/creator"]

选择一个好的镜像:paketobuildpacks/builder:base

那么如何开发工作.gitlab-ci.yml呢?让我们从简单的开始。深入研究 Tekton 实现,您会看到生命周期命令是在 中定义的环境中执行的,该环境BUILDER_IMAGE本身被记录为The image on which builds will run (must include lifecycle and compatible buildpacks).That sound's familiar!paketobuildpacks/builder:base我们不能简单地从我们的 pack CLI 命令中选择构建器映像吗?让我们在我们的工作站上本地尝试一下,然后再向我们的 GitLab 提交大量噪音。选择您要构建的项目(如果您愿意,我在gitlab.com/jonashackt/microservice-api-spring-boot上创建了一个示例 Spring Boot 应用程序,您可以克隆)并运行:

docker run --rm -it -v "$PWD":/usr/src/app -w /usr/src/app paketobuildpacks/builder bash

现在在paketobuildpacks/builder图像驱动的容器中尝试直接运行 Paketo 生命周期:

/cnb/lifecycle/creator -app=. microservice-api-spring-boot:latest

我只使用了命令的许多可能参数中的参数-app,因为它们中的大多数都有很好的默认值。但是由于默认的应用程序目录路径不是默认的-而是当前目录,因此我对其进行了配置。此外,我们还需要在末尾定义一个,它将简单地用作生成的容器镜像名称。creator/workspace<image-name>

第一个 .gitlab-ci.yml

这两个命令都在我的本地工作站上运行,所以让我们最终.gitlab-ci.yml使用这种方法创建一个(这是一个完整的工作示例.gitlab-ci.yml):

image: paketobuildpacks/builder

stages:
  - build

build-image:
  stage: build
  script:
    - /cnb/lifecycle/creator -app=. $CI_REGISTRY_IMAGE:latest

没有docker的docker登录

docker由于我们的 Kubernetes Runners 中没有可用的资源,因此我们无法按照文档中的描述登录 GitLab Container Registry。所以我使用第一种方法发生了以下错误:

===> ANALYZING
ERROR: failed to get previous image: connect to repo store "gitlab.yourcompanyhere.cloud:4567/yourgroup/microservice-api-spring-boot:latest": GET https://gitlab.yourcompanyhere.cloud/jwt/auth?scope=repository%3Ayourgroup%2Fmicroservice-api-spring-boot%3Apull&service=container_registry: DENIED: access forbidden
Cleaning up project directory and file based variables 00:01
ERROR: Job failed: command terminated with exit code 1

使用this so answer中描述的方法解决了问题。我们需要创建一个~/.docker/config.json包含 GitLab Container Registry 登录信息的文件 - 然后Paketo 构建将获取它们,如文档中所述

如果CNB_REGISTRY_AUTH未设置并且存在 docker config.json 文件,则生命周期应该使用此文件的内容与任何匹配的注册表进行身份验证。

在我们的内部.gitlab-ci.yml,这可能看起来像:

# We somehow need to access GitLab Container Registry with the Paketo lifecycle
# So we simply create ~/.docker/config.json as stated in https://stackoverflow.com/a/41710291/4964553
before_script:
  - mkdir ~/.docker
  - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_JOB_TOKEN\"}}}" >> ~/.docker/config.json

我们最终的 .gitlab-ci.yml

当我们image: paketobuildpacks/builder在顶部使用 时.gitlab-ci.yml,我们现在可以直接利用生命周期。这就是我们最初想做的事情。只记得使用正确的 GitLab CI 变量来描述你<image-name>这样的:

/cnb/lifecycle/creator -app=. $CI_REGISTRY_IMAGE:latest

否则,Buildpack 流程分析器步骤将中断,最终不会被推送到 GitLab 容器注册表。所以最后我们.gitlab-ci.yml看起来像这样(这里是完整的工作示例):

image: paketobuildpacks/builder

stages:
  - build

# We somehow need to access GitLab Container Registry with the Paketo lifecycle
# So we simply create ~/.docker/config.json as stated in https://stackoverflow.com/a/41710291/4964553
before_script:
  - mkdir ~/.docker
  - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_JOB_TOKEN\"}}}" >> ~/.docker/config.json

build-image:
  stage: build
  script:
    - /cnb/lifecycle/creator -app=. $CI_REGISTRY_IMAGE:latest

我们的构建现在应该可以使用 Paketo/Buildpacks 成功运行,而无需打包 CLI 和 Docker:

在此处输入图像描述

在此处查看示例项目的完整日志

于 2021-10-14T11:19:27.500 回答