Bazel docker容器映像未复制文件



我正在尝试模拟您将在Bazel docker容器映像规则中显示的docker文件中设置的un步骤,但由于container_image规则没有复制功能,我正在尝试使用可用的内容。

RUN GRPC_HEALTH_PROBE_VERSION=v0.3.1 && 
wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && 
chmod +x /bin/grpc_health_probe
go_image(
name = "go_auth_image",
embed = [":go-auth_lib"],
visibility = ["//visibility:public"],
)
container_image(
name = "go_auth_api",
visibility = ["//visibility:public"],
base = ":go_auth_image",
ports = ["5001", "5002"],
files = ["grpc_health_probe-linux-amd64"],
symlinks = {
"grpc_health_prob-linux-amd64": "/bin/grpc_health_probe",
},
cmd = [
"apk add --no-cache git",
"chmod +x /bin/grpc_health_probe",
],
)

注:file_map似乎不是container_image的参数

当我将这个映像部署到k8s时,映像运行良好,但是当描述pod时,活动探测(下面描述)失败了。

livenessProbe:
exec:
command: ["/bin/grpc_health_probe", "-addr=:5002"]
initialDelaySeconds: 5
periodSeconds: 30
timeoutSeconds: 2
successThreshold: 1
failureThreshold: 3
Warning  Unhealthy  6m42s                  kubelet            Liveness probe errored: rpc error: code = Unknown desc = failed to exec in container: failed to start exec "b6c89b7ec907e572f80be59e8d4b5cad6535a3479d67a3563a09e0d1d2f7ca03": OCI runtime exec failed: exec failed: container_linux.go:370: starting container process caused: exec: "/bin/grpc_health_probe": stat /bin/grpc_health_probe: no such file or directory: unknown

用Bazel设置这个探针的正确方法是什么(我已经确认这与Dockerfile设置一起工作)

container_run_and_commit与RUN最接近。像这样的内容是直接等价的:

load("@io_bazel_rules_docker//docker/util:run.bzl", "container_run_and_commit")
GRPC_HEALTH_PROBE_VERSION = "v0.3.1"
container_run_and_commit(
name = "install_stuff",
image = ":go_auth_image.tar",
commands = [
"wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/%s/grpc_health_probe-linux-amd64" % GRPC_HEALTH_PROBE_VERSION,
"chmod +x /bin/grpc_health_probe",
],
)

container_image(
name = "go_auth_api",
visibility = ["//visibility:public"],
base = ":install_stuff",
... # everything else you're doing with container_image
)

它运行命令构建一个新映像,然后使用container_image向结果添加东西。

然而,使用bazel做更多的构建将更好地利用bazel的缓存,并且更具可重复性。我认为这就是你对grpc_health_probe-linux-amd64源文件所做的。这个方法看起来像这样:

load("@io_bazel_rules_docker//docker/util:run.bzl", "container_run_and_commit")
container_image(
name = "add_stuff",
base = ":go_auth_image",
ports = ["5001", "5002"],
files = ["grpc_health_probe-linux-amd64"],
symlinks = {
"grpc_health_prob-linux-amd64": "/bin/grpc_health_probe",
},
)
container_run_and_commit(
name = "go_auth_api",
visibility = ["//visibility:public"],
image = ":add_stuff.tar",
commands = [
"apk add --no-cache git",
"chmod +x /bin/grpc_health_probe",
],
)

首先使用container_image添加东西,然后再运行命令。

另外,您可以使用pkg_tar来打包文件+symlink(它有一个symlinks属性,就像container_image一样),而不是运行chmod +x,然后设置mode = 0755container_image.tars将获取tar文件并将其添加到映像中。一般来说,pkg_tar为构建文件提供了很大的灵活性,而container_image则直接为简单的用例提供了其功能的子集。

container_image。cmd相当于Dockerfile中的CMD。它只是在使用容器时设置信息,在构建容器时不做任何事情。我认为你根本不想用它。

感谢@Brian-Silverman的帮助,我能够分类我所有的问题,并与这个解决方案着陆。

go_image(
name = "go_auth_image",
embed = [":go-auth_lib"],
visibility = ["//visibility:public"],
)
GRPC_HEALTH_PROBE_VERSION = "v0.4.5"

container_run_and_commit_layer(
name = "health_probe",
image = "@grpc_health_image//image",
commands = [
"apk add --no-cache git",
"wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/%s/grpc_health_probe-linux-amd64" % GRPC_HEALTH_PROBE_VERSION,
"chmod +x /bin/grpc_health_probe",
],
)
container_image(
name = "go_auth_api",
base = ":go_auth_image",
layers = [":health_probe",],
visibility = ["//visibility:public"],
ports = ["5001"],
)

我已经回应了你的github问题,但是在这里发布答案也是为了可见性:我会在Bazel中通过在我想要的位置制作包含grpc_health_probe二进制文件的TAR并将其添加到container_image规则的tars部分来实现这一点。我尽量避免RUN之类的规则,因为它们引入了对docker工具链的依赖,并且它们不能保证是密封的/可复制的。这里有一个公开的问题:https://github.com/bazelbuild/rules_docker/issues/1961.

您可以将有问题的二进制文件声明为WORKSPACE中的依赖项(或由WORKSPACE调用的宏),如下所示:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
GRPC_HEALTH_PROBE_VERSION = "v0.4.5"
GRPC_HEALTH_PROBE_SHA256 = "8699c46352d752d8f533cae72728b0e65663f399fc28fb9cd854b14ad5f85f44"
http_file(
name = "grpc_health_probe_linux_amd64",
executable = True,  # Here is your `chmod +x` from the `container_run_and_commit`
sha256 = GRPC_HEALTH_PROBE_SHA256,
downloaded_file_path = "grpc_health_probe",  # This is necessary to remove `-linux-amd64` from the end of the file name.
urls = ["https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/{}/grpc_health_probe-linux-amd64".format(GRPC_HEALTH_PROBE_VERSION)],
)

完成了这些,并包含了rules_docker工具链配置,然后可以将这个二进制文件添加到一个容器映像中,其构建文件如下所示:

load("@rules_pkg//:pkg.bzl", "pkg_tar")
load("@io_bazel_rules_docker//container:container.bzl", "container_image")
# This rule creates a TAR file containing the executable file
# /bin/grpc_health_probe.
pkg_tar(
name = "health_probe_linux_amd64",
srcs = ["@grpc_health_probe_linux_amd64//file"],
package_dir = "/bin",  # specifying the path of the file
)
# Here, we add that health probe to our base image. In this case
# I've used the ubuntu image for a minimal example.
container_image(
name = "health_probe_image",
base = "YOUR_BASE_IMAGE_HERE",
tars = [":health_probe_linux_amd64"],
)

Github回复:https://github.com/bazelbuild/rules_docker/issues/1943#issuecomment-998400122

最新更新