解决 GitLab CI 使用 Kaniko 构建多镜像时依赖缓存问题
Terry
It has been 0 days since the last update of this post. Some contents may be outdated. Please pay attention to screening.

在使用 gitlab ci 同时构建多个镜像的时候,由于 Kaniko 默认会使用缓存。如果 A 中的 requirements.txt 已经安装过,Kaniko
可能跳过一些安装步骤。在 B 镜像构建时,缓存可能导致某些步骤没有被重新或完全执行。

进而会导致 requirements.txt 文件在构建后续镜像时不可见或被错误忽略。

❌异常复现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
build:
stage: build
image:
name: test-executor:v1.23.2-debug
entrypoint: [ "" ]
script:
- /kaniko/executor
--context "${CI_PROJECT_DIR}"
--dockerfile "${CI_PROJECT_DIR}/webui/Dockerfile"
--destination "${CI_REGISTRY_IMAGE}/webui:${CI_COMMIT_TAG}"
- /kaniko/executor
--context "${CI_PROJECT_DIR}"
--dockerfile "${CI_PROJECT_DIR}/api/Dockerfile"
--destination "${CI_REGISTRY_IMAGE}/api:${CI_COMMIT_TAG}"
rules:
- if: $CI_COMMIT_TAG

在使用以上 ci 文件进行构建时,执行到构建 api 对应镜像时,ci 日志中会出现
No files changed in this command, skipping snapshotting.提示

最后检查镜像中 pip 依赖时会发现缺少很多必要依赖!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ /kaniko/executor --context "${CI_PROJECT_DIR}" --dockerfile "${CI_PROJECT_DIR}/webui/Dockerfile" --destination "${CI_REGISTRY_IMAGE}/webui:${CI_COMMIT_TAG}"
INFO[0004] Running: [/bin/sh -c pip install --no-cache-dir -r requirements.txt]
...
Successfully installed MarkupSafe-3.0.1 Pillow-10.4.0 XlsxWriter-3.2.0 altair-5.4.1
annotated-types-0.7.0 anyio-4.6.0 attrs-24.2.0 blinker-1.8.2 cachetools-5.5.0 certifi-2024.8.30 ...

$ /kaniko/executor --context "${CI_PROJECT_DIR}" --dockerfile "${CI_PROJECT_DIR}/api/Dockerfile" --destination "${CI_REGISTRY_IMAGE}/api:${CI_COMMIT_TAG}"
INFO[0000] Using dockerignore file: /builds/poc/2409-rag-agent-app/.dockerignore
...
⚠️ INFO[0004] No files changed in this command, skipping snapshotting.
INFO[0004] Running: [/bin/sh -c pip install --no-cache-dir -r requirements.txt]
...
Installing collected packages: uvicorn, starlette, fastapi
⚠️ Successfully installed fastapi-0.115.0 starlette-0.38.6 uvicorn-0.31.0

📗解决方法

多次运行 /kaniko/executor

script 中,你执行了两次 /kaniko/executor 命令,
分别用于构建 webuiapi 的 Docker 镜像。

改进建议:将 webui 和 api 的构建拆分成单独的任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
build_webui:
stage: build
image:
name: test-executor:v1.23.2-debug
script:
- /kaniko/executor
--context "${CI_PROJECT_DIR}"
--dockerfile "${CI_PROJECT_DIR}/webui/Dockerfile"
--destination "${CI_REGISTRY_IMAGE}/webui:${CI_COMMIT_TAG}"
rules:
- if: $CI_COMMIT_TAG

build_api:
stage: build
image:
name: test-executor:v1.23.2-debug
script:
- /kaniko/executor
--context "${CI_PROJECT_DIR}"
--dockerfile "${CI_PROJECT_DIR}/api/Dockerfile"
--destination "${CI_REGISTRY_IMAGE}/api:${CI_COMMIT_TAG}"
rules:
- if: $CI_COMMIT_TAG

这样,每个任务可以并行执行,减少整体的构建时间。

禁用 Kaniko 的缓存

你还可以禁用 Kaniko 的缓存来确保每次都重新构建

1
2
3
4
5
- /kaniko/executor
--context "${CI_PROJECT_DIR}"
--dockerfile "${CI_PROJECT_DIR}/api/Dockerfile"
--destination "${CI_REGISTRY_IMAGE}/api:${CI_COMMIT_TAG}"
--no-cache
本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明