【问题标题】:Dockerfile giving error with distroless imageDockerfile 使用 distroless 映像给出错误
【发布时间】:2021-09-22 19:52:21
【问题描述】:

我正在尝试运行此Dockerfile with distroless image (gcr.io/distroless/static:nonroot)。 docker build 成功发生,但 docker run -it image_name 给我错误:

2021-07-13T18:16:11.441Z   ERROR   controller-runtime.client.config  unable to get kubeconfig    {"error": "could not locate a kubeconfig"}
github.com/go-logr/zapr.(*zapLogger).Error
  /go/pkg/mod/github.com/go-logr/zapr@v0.1.0/zapr.go:128
sigs.k8s.io/controller-runtime/pkg/client/config.GetConfigOrDie
  /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.4.0/pkg/client/config/config.go:146
main.main
  /workspace/main.go:63
runtime.main
  /usr/local/go/src/runtime/proc.go:203

调试结果

  1. 如果我删除最后一行 ENTRYPOINT ["/manager"] 则保留 distroless 映像,然后 docker run -it image_name 给出错误为-:docker: Error response from daemon: No command specified. See 'docker run --help'
    同样的docker run 命令适用于 distroless(带 ENTRYPOINT 行)但不适用于 distroless(不带 ENTRYPOINT 行)
  2. 我用 alpine:latest 替换了 distroless 映像。这里有ENTRYPOINT ["/manager"](&没有USER nonroot:nonroot)我看到与上面相同的错误ERROR controller-runtime.client.config unable to get kubeconfig...但是没有ENTRYPOINT行,我可以使用docker run -it image_name登录到容器。

请告诉我如何解决这个问题,这样我就可以让这个 dockerfile 像在 Dockerfile 中一样使用所有必需的配置运行。

注意:我担心我的 egress-operator pod 可能无法通过更改镜像名称来运行,因为它可能导致错过 dockerfile 中的任何配置以使其运行。

【问题讨论】:

  • 在该镜像中,有一个操作员想要与 Kubernetes 交互?它可能期望一个位于 kubeconfig 文件的 KUBECONFIG env var 来连接到 Kubernetes
  • 您引用的错误消息似乎是来自您的应用程序的错误(正如@AandD 所暗示的,也许是 Kubernetes 控制器?),这意味着 Docker 级别的接线可能或多或少是正确的。您是否有关于如何将 Kubernetes 凭据注入容器的问题?还是别的什么?
  • @David-: 我想修复这个错误,以便 dockerfile 成功运行。
  • ENTRYPOINT[/manager] 命令在做什么?它会 cd 到 /manager 文件夹还是( ./manager )文件?只是想确认它的正确与否

标签: docker go kubernetes dockerfile kubeconfig


【解决方案1】:

简答:

如果你想运行你的图像,只需这样做:

你有两个选择:

  1. 在 Kubernetes 集群中运行您的映像
  2. 将您的 kubeconfig 以$HOME/.kube/config 的形式放入您的镜像中

如果您正在尝试调试图像,请尝试以下操作:

docker run --rm -it --entrypoint bash image_name

如果发生command not found,则将bash 替换为sh


解释

Dockerfile 部分

根据Dockerfile Docs about entrypoint

ENTRYPOINT 允许您配置将作为可执行文件运行的容器。 docker run <image> 的命令行参数将附加在 exec 表单 ENTRYPOINT 中的所有元素之后

你的命令是 docker run -it image_name 没有任何参数,所以 docker 会把它当作:

  1. 在镜像环境中运行
  2. 运行入口点/manager

/manager 是用kubebuilder 构建的,它会尝试加载kubeconfig,如果找不到东西就会死掉。

如果您不想在执行docker run 时运行/manager,则必须使用--entrypoint arg 替换它。

Kubebuilder 部分

我注意到你提到你害怕错过你的 pod 的 kubeconfig,追加这个编辑。

kubebuilder 默认会尝试在 2 处查找 kubeconfig:

  1. $HOME/.kube/config:文件系统中的配置文件。
  2. 集群内:在 kubernetes 内运行的 pod 可以获得集群内 kubeconfig。 /

【讨论】:

  • 如果我在 Kubernetes 集群中运行它,那么相同的 dockerfile 给出的错误如下:OCI 运行时创建失败:container_linux.go:380:启动容器进程导致:exec:“/manager”:stat /manager :没有这样的文件或目录:未知。因此,我单独运行此 dockerfile 以查看哪一行出现故障。我也为它提出了一个单独的问题stackoverflow.com/questions/68360450/…
  • @solveit 显然,这不是同一个错误,它是在问题中找不到 kubeconfig,现在你找不到管理器,如果你确定你有可能是与 libc 有关的东西添加了经理。你现在使用 alpine 作为基础镜像吗?如果是这样,尽量不要
  • 现在我正在尝试使用 ubuntu:18.04 映像在 kubernetes 集群中构建 dockerfile(我知道它比 alpine 和 distroless 重,但想验证映像是否导致问题)并替换了 ENTRYPOINT[ "/manager"] 和 CMD["/manager"]。仅供参考,带有 CMD 的 ubuntu 映像与 docker run -it image_name /bin/bash 分开工作。我能够登录容器并在“/”位置找到管理器文件。所以现在在 Kubernetes 集群中尝试相同的组合。
  • @solveit 查看我的答案,您也可以在使用入口点时执行“docker run xx bash”,只需尝试 docker run 的“-entrypoint”标志。这不是这里的主要问题
猜你喜欢
  • 2018-04-23
  • 1970-01-01
  • 2020-10-17
  • 2022-09-24
  • 2020-05-28
  • 2020-07-18
  • 2018-08-05
  • 1970-01-01
  • 2020-12-12
相关资源
最近更新 更多