{{< details >}}
- Tier: 基础版, 专业版, 旗舰版
- Offering: JihuLab.com, 私有化部署
{{< /details >}}
kaniko 是一个用于在容器或 Kubernetes 集群中从 Dockerfile 构建容器镜像的工具。
kaniko 解决了使用 Docker-in-Docker 构建 方法的两个问题:
- Docker-in-Docker 需要特权模式才能运行,这存在重大安全隐患。
- Docker-in-Docker 通常会导致性能下降,可能会非常慢。
先决条件
要在极狐GitLab 中使用 kaniko,需要一个具有以下执行器之一的 runner:
使用 kaniko 构建 Docker 镜像
在使用 kaniko 和极狐GitLab CI/CD 构建镜像时,你应该注意一些重要细节:
- 推荐使用 kaniko 调试镜像 (
gcr.io/kaniko-project/executor:debug
),因为它具有 shell,而使用极狐GitLab CI/CD 需要 shell。 - 需要 覆盖 entrypoint,否则构建脚本不会运行。
在以下示例中,使用 kaniko 来:
- 构建一个 Docker 镜像。
- 然后将其推送到 极狐GitLab 容器注册表。
该作业仅在推送标签时运行。在 /kaniko/.docker
下创建一个 config.json
文件,其中包含从极狐GitLab CI/CD 提供的 预定义 CI/CD 变量 中获取的极狐GitLab 容器注册表凭据。这些凭据会被 Kaniko 工具自动读取。
在最后一步中,kaniko 使用项目根目录下的 Dockerfile
构建 Docker 镜像,并将其推送到项目的容器注册表,同时用 Git 标签标记它:
build:
stage: build
image:
name: gcr.io/kaniko-project/executor:v1.23.2-debug
entrypoint: [""]
script:
- /kaniko/executor
--context "${CI_PROJECT_DIR}"
--dockerfile "${CI_PROJECT_DIR}/Dockerfile"
--destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}"
rules:
- if: $CI_COMMIT_TAG
如果你在 Dependency Proxy 中进行身份验证,则必须将用于身份验证的相应 CI/CD 变量添加到 config.json
文件中:
- echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"},\"$(echo -n $CI_DEPENDENCY_PROXY_SERVER | awk -F[:] '{print $1}')\":{\"auth\":\"$(printf "%s:%s" ${CI_DEPENDENCY_PROXY_USER} "${CI_DEPENDENCY_PROXY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json
此命令会去除 CI_DEPENDENCY_PROXY_SERVER
中的端口,例如 :443
,因此在引用镜像时不必包括它。
在代理后使用 kaniko 构建镜像
如果你在 http(s) 代理后使用自定义极狐GitLab Runner,需要相应地设置 kaniko。这意味着:
- 将
http_proxy
环境变量作为构建参数传递,以便 Dockerfile 指令在构建镜像时可以使用代理。
可以如下扩展前面的示例:
build:
stage: build
variables:
http_proxy: <your-proxy>
https_proxy: <your-proxy>
no_proxy: <your-no-proxy>
image:
name: gcr.io/kaniko-project/executor:v1.23.2-debug
entrypoint: [""]
script:
- /kaniko/executor
--context "${CI_PROJECT_DIR}"
--build-arg http_proxy=$http_proxy
--build-arg https_proxy=$https_proxy
--build-arg no_proxy=$no_proxy
--dockerfile "${CI_PROJECT_DIR}/Dockerfile"
--destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}"
rules:
- if: $CI_COMMIT_TAG
构建多架构镜像
你可以通过使用 manifest-tool
在容器内构建多架构镜像。
使用自定义证书的注册表
当尝试推送到使用自定义 CA 签署的证书的 Docker 注册表时,可能会收到以下错误:
$ /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --no-push
INFO[0000] Downloading base image registry.gitlab.example.com/group/docker-image
error building image: getting stage builder for stage 0: Get https://registry.gitlab.example.com/v2/: x509: certificate signed by unknown authority
可以通过将你的 CA 证书添加到 kaniko 证书存储来解决此问题:
before_script:
- |
echo "-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----" >> /kaniko/ssl/certs/ca-certificates.crt
故障排除
403 错误:“检查推送权限时出错”
如果收到此错误,可能是由于外部代理导致的。设置 http_proxy
和 https_proxy
环境变量 可以解决此问题。
错误:kaniko 应该仅在容器内运行
Docker Engine 20.10 引入了一个已知的不兼容性。
当主机使用 Docker Engine 20.10 或更新版本时,版本低于 v1.9.0 的 gcr.io/kaniko-project/executor:debug
镜像无法按预期工作。
当你尝试构建镜像时,Kaniko 会失败并显示以下信息:
kaniko should only be run inside of a container, run with the --force flag if you are sure you want to continue
要解决此问题,请将 gcr.io/kaniko-project/executor:debug
容器更新到至少 v1.9.0 的版本,例如 gcr.io/kaniko-project/executor:v1.23.2-debug
。
相反的配置(gcr.io/kaniko-project/executor:v1.23.2-debug
镜像和版本为 19.06.x 或更早版本的主机上的 Docker Engine)可以正常工作。为了获得最佳策略,你应该经常测试并更新作业环境版本到最新。这带来了新功能、提高的安全性,并且 - 对于这种特定情况 - 使 runner 主机上底层 Docker Engine 的升级对作业是透明的。