如何将oci.pull()拉取的镜像作为tar层加入oci_image?
解决Bazel中oci.pull镜像转为tar层加入自定义oci_image的问题
问题本质
直接将@r_base(oci.pull拉取的镜像目标)传给oci_image的tars参数会报错,因为oci.pull生成的是包含镜像元数据和分层文件的目录结构,并非单个可直接引用的tar文件,Bazel无法将其识别为合法的tar层输入。
正确实现步骤
1. 确认MODULE.bazel的镜像拉取配置
确保r-base镜像的拉取声明正确,示例:
oci.pull( name = "r_base", image = "docker.io/library/r-base:latest", digest = "sha256:xxxxxx", # 替换为目标镜像的实际digest值 )
2. 用oci_extract提取镜像层tar
在BUILD.bazel中,通过oci_extract规则将r-base镜像的层提取为tar文件:
load("@rules_oci//oci:defs.bzl", "oci_image", "oci_extract") # 提取所有层合并为单个tar文件 oci_extract( name = "r_base_combined_tar", image = "@r_base", output_tar = True, ) # 或者提取为多个独立层tar(保留原镜像分层结构) oci_extract( name = "r_base_layers", image = "@r_base", output_tars = True, )
3. 在自定义oci_image中引用提取的tar
将提取后的tar文件传入oci_image的tars参数:
# 单tar层的情况 oci_image( name = "custom_databricks_image", base = "@databricksruntime", tars = [":r_base_combined_tar"], # 按需添加其他配置:entrypoint、cmd、env等 ) # 多tar层的情况(需按原镜像层顺序引用) oci_image( name = "custom_databricks_image", base = "@databricksruntime", tars = [ ":r_base_layers_tar_0", ":r_base_layers_tar_1", # 按实际生成的tar文件依次添加 ], )
4. 替代方案:链式镜像构建
如果不需要单独提取tar层,也可以通过链式base叠加实现:
oci_image( name = "r_base_on_databricks", base = "@databricksruntime", tars = [":r_base_files_tar"], ) # 先将r-base镜像内的文件打包为tar pkg_tar( name = "r_base_files_tar", srcs = ["@r_base//files"], # 引用镜像内的文件组 package_dir = "/", # 保留原文件路径结构 )
注:此方案需要确保@r_base//files的文件组声明正确,推荐优先使用oci_extract方法。
关键注意事项
- 确保
rules_oci版本≥1.0.0(oci_extract规则在较新版本中才支持),可在MODULE.bazel中更新依赖:
bazel_dep(name = "rules_oci", version = "1.5.0") # 替换为最新稳定版
- 使用多tar层时,需严格遵循原镜像的层顺序,避免文件覆盖或依赖错误。
内容的提问来源于stack exchange,提问作者Stephen Gross
相关产品推荐
相关产品推荐

