我们希望以最简单的方式使用Paketo.io / CloudNativeBuildpacks (CNB) GitLab CI。我们的GitLab设置使用了一个AWS集群,带有利用库伯奈特遗嘱执行人的非特权GitLab CI运行程序。我们还不希望引入在构建中使用Docker带来的安全风险。因此,我们既不公开宿主的/var/run/docker.sock,也不想使用docker:dind。
我们找到了一些关于如何在GitLab CI中使用Paketo的指南,比如这个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而不让Docker出现在我们的GitLab Kubernetes运行程序中(这似乎是一种最佳实践),有什么想法吗?我们也不希望我们的设置变得复杂-例如,通过添加kpack。
发布于 2021-10-14 11:19:27
TLDR;
直接在.gitlab-ci.yml 下面是一个充分发挥作用的例子中使用Buildpack的生命周期):
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/564和https://github.com/buildpacks/pack/issues/413#issuecomment-565165832。如上文所述:
如果您希望在CI (而不是本地)中构建映像,我鼓励您直接使用生命周期,这样您就不需要Docker了。下面是一个例子:
指向该示例的链接已中断,但它引用了泰克顿在如何在Kubernetes环境中使用buildpack上的实现。在这里,我们可以得到关于Stephen所称的"to use the lifecycle directly"的第一种胶水。在其内部,关键是command: ["/cnb/lifecycle/creator"]的使用。,所以这是每个人都在谈论的生命周期!,关于这个命令有很好的文档,可以找到在这个CNB RFC中。
选择一个好的形象:paketobuildpack/builder:base
那么如何开发一个工作的.gitlab-ci.yml呢?让我们从简单开始。深入了解进入Tekton的实现,您将看到生命周期命令是在BUILDER_IMAGE中定义的环境中执行的,这个环境本身被记录为The image on which builds will run (must include lifecycle and compatible buildpacks).,听起来很熟悉!我们不能简单地从pack命令中选择构建器映像paketobuildpacks/builder:base吗?让我们在工作站上进行本地测试,然后在GitLab中进行大量的噪声处理。选择一个您想要构建的项目(我创建了一个示例Spring应用程序,如果您想在gitlab.com/jonashackt/microservice-api-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参数命令,因为它们中的大多数都有很好的缺省值。但是,由于默认的应用程序目录路径不是默认的/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无码头人士登入
由于我们的Kubernetes跑步者中没有可用的docker,所以我们不能使用如文档中所述,登录到GitLab容器注册表。因此,使用第一种方法发生了以下错误:
===> 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使用这种方法,在这个如此的答案中被描述解决了这个问题。我们需要创建一个~/.docker/config.json,其中包含GitLab容器注册表登录信息,然后是如文档中所述,Paketo构建器将捡起它们。
如果
CNB_REGISTRY_AUTH未设置且存在一个停靠器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否则,步骤将中断,最终不会被推送到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/Buildpack成功运行,而不需要pack和Docker:

https://stackoverflow.com/questions/69569784
复制相似问题