Dockerfile在使用distroless镜像时出现错误。

huangapple go评论117阅读模式
英文:

Dockerfile giving error with distroless image

问题

我正在尝试运行这个Dockerfile使用的distroless镜像(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'。但是,对于带有ENTRYPOINT行的distroless镜像,这个docker run命令可以正常工作,而不带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中的任何配置。

英文:

I am trying to run this Dockerfile with distroless image (gcr.io/distroless/static:nonroot). docker build is happening successfully, but docker run -it image_name is giving me error:

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

Debugging findings

  1. Keeping distroless image if I am removing last line ENTRYPOINT [&quot;/manager&quot;] then docker run -it image_name giving error as-: docker: Error response from daemon: No command specified. See &#39;docker run --help&#39;. <br/>This same docker run command working for distroless(with ENTRYPOINT line) but not working with distroless(without ENTRYPOINT line)
  2. I replaced distroless image with alpine:latest. Here with ENTRYPOINT [&quot;/manager&quot;] (& without USER nonroot:nonroot) I am seeing same error as above ERROR controller-runtime.client.config unable to get kubeconfig... BUT without ENTRYPOINT line, I am able to login to container with docker run -it image_name.

Someone please let me know how to resolve this, so that I can make this dockerfile run with all required configs as in Dockerfile.

NOTE: I am afraid that my egress-operator pod might not run by changing image name, as it can lead to miss any configuration in dockerfile in order to make it run.

答案1

得分: 2

简短回答:

如果你想运行你的镜像,只需执行以下操作:

你有两个选项:

  1. 在 Kubernetes 集群中运行你的镜像。
  2. 将你的 kubeconfig 放置在镜像中的 $HOME/.kube/config

如果你想调试你的镜像,可以尝试以下命令:

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

如果出现 command not found 的情况,请将 bash 替换为 sh


解释:

Dockerfile 部分

根据 Dockerfile 文档关于 entrypoint 的说明

> ENTRYPOINT 允许你配置一个将作为可执行文件运行的容器。docker run &lt;image&gt; 命令行参数将会附加在 exec 形式的 ENTRYPOINT 的所有元素之后。

你的命令是 docker run -it image_name,没有任何参数,因此 Docker 会将其视为:

  1. 在镜像环境中运行。
  2. 运行 entrypoint,即 /manager

/manager 是使用 kubebuilder 构建的,它会尝试加载 kubeconfig,如果找不到则会退出。

如果你不想在执行 docker run 时运行 /manager,你需要使用 --entrypoint 参数来替换它。

Kubebuilder 部分

我注意到你提到你担心 pod 缺少 kubeconfig,因此添加了以下编辑。

kubebuilder 默认会在两个位置查找 kubeconfig:

  1. $HOME/.kube/config:文件系统中的配置文件。
  2. in-cluster:在 Kubernetes 内运行的 pod 可以获取到一个 in-cluster kubeconfig。
英文:

Short answer:

If you want to run your image, just do this:

you have 2 options for it:

  1. Run your image inside a Kubernetes Cluster
  2. Place your kubeconfig inside your image as $HOME/.kube/config

If you are trying to debug your image, try this:

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

replace bash with sh if command not found happened.


Explanation

Dockerfile part

According to the Dockerfile Docs about entrypoint,

> An ENTRYPOINT allows you to configure a container that will run as an executable. Command line arguments to docker run &lt;image&gt; will be appended after all elements in an exec form ENTRYPOINT

Your command is docker run -it image_name without any arg, so that docker will treat it as:

  1. Run it in the image env
  2. Run entrypoint which is /manager

the /manager is built with kubebuilder, it will try to load the kubeconfig and die if not thing found.

If you do not want to run the /manager when execute docker run, you have to replace it by using --entrypoint arg.

Kubebuilder part

As I noticed you mentioned you afraid of missing the kubeconfig for your pod, appending this edit.

kubebuilder would try to find kubeconfig in 2 place by default:

  1. $HOME/.kube/config: the configuration file in the file system.
  2. in-cluster: a pod running inside kubernetes can get an in-cluster kubeconfig.
    /

huangapple
  • 本文由 发表于 2021年7月14日 02:41:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/68367830.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定