英文:
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
调试结果
- 如果我删除最后一行
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行的则不行。 - 我用
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
- Keeping distroless image if I am removing last line
ENTRYPOINT ["/manager"]thendocker run -it image_namegiving error as-:docker: Error response from daemon: No command specified. See 'docker run --help'. <br/>This samedocker runcommand working for distroless(with ENTRYPOINT line) but not working with distroless(without ENTRYPOINT line) - I replaced distroless image with
alpine:latest. Here withENTRYPOINT ["/manager"](& withoutUSER nonroot:nonroot) I am seeing same error as aboveERROR controller-runtime.client.config unable to get kubeconfig...BUT without ENTRYPOINT line, I am able to login to container withdocker 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
简短回答:
如果你想运行你的镜像,只需执行以下操作:
你有两个选项:
- 在 Kubernetes 集群中运行你的镜像。
- 将你的 kubeconfig 放置在镜像中的
$HOME/.kube/config。
如果你想调试你的镜像,可以尝试以下命令:
docker run --rm -it --entrypoint bash image_name
如果出现 command not found 的情况,请将 bash 替换为 sh。
解释:
Dockerfile 部分
根据 Dockerfile 文档关于 entrypoint 的说明:
> ENTRYPOINT 允许你配置一个将作为可执行文件运行的容器。docker run <image> 命令行参数将会附加在 exec 形式的 ENTRYPOINT 的所有元素之后。
你的命令是 docker run -it image_name,没有任何参数,因此 Docker 会将其视为:
- 在镜像环境中运行。
- 运行 entrypoint,即
/manager。
/manager 是使用 kubebuilder 构建的,它会尝试加载 kubeconfig,如果找不到则会退出。
如果你不想在执行 docker run 时运行 /manager,你需要使用 --entrypoint 参数来替换它。
Kubebuilder 部分
我注意到你提到你担心 pod 缺少 kubeconfig,因此添加了以下编辑。
kubebuilder 默认会在两个位置查找 kubeconfig:
$HOME/.kube/config:文件系统中的配置文件。- 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:
- Run your image inside a Kubernetes Cluster
- 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 <image> 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:
- Run it in the image env
- 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:
$HOME/.kube/config: the configuration file in the file system.- in-cluster: a pod running inside kubernetes can get an in-cluster kubeconfig.
/
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论