首页
使用 Docker run 覆盖 ENTRYPOINT

问题

目前在研究kuryr插件,想要进去修改代码,发现无法docker run 进入终端,最后发现是当在 Dockerfile 文件中使用 Entrypoint 后,无法直接运行 docker run -it container 进入交互式终端。

...
USER kuryr
CMD ["--config-dir", "/etc/kuryr"]
ENTRYPOINT [ "kuryr-k8s-controller" ]

运行命令报错:

[root@localhost ~]# docker run -it -uroot --name test kuryr/controller /bin/bash
usage: kuryr-k8s-controller [-h] [--config-dir DIR] [--config-file PATH]
                            [--debug] [--log-config-append PATH]
                            [--log-date-format DATE_FORMAT]
                            [--log-dir LOG_DIR] [--log-file PATH] [--nodebug]
                            [--nouse-journal] [--nouse-json] [--nouse-syslog]
                            [--nowatch-log-file]
                            [--syslog-log-facility SYSLOG_LOG_FACILITY]
                            [--use-journal] [--use-json] [--use-syslog]
                            [--version] [--watch-log-file]
kuryr-k8s-controller: error: unrecognized arguments: /bin/bash

解决

想要覆盖掉默认的可执行文件,例如在一个容器中运行 Shell。这个时候,我们需要显式地指定 --entrypoint 标志。

docker run -it --entrypoint /bin/bash -uroot --name test kuryr/controller

当不指定 --entrypoint 时,默认的 entrypoint 就是 shell,所以如果我们在 dockerfile 中指定了 entry point,那么我们想要运行其他可执行文件时,就必须显式地指定可执行文件了。

Entrypoint和CMD的区别

Docker中的Entrypoint和Cmd都是用于指定容器启动时要运行的命令,它们的区别在于它们的作用和使用方式。

Entrypoint是指定容器启动时要执行的可执行文件或脚本,并且该命令在运行容器时不能被覆盖。Entrypoint可以看作是容器的默认执行命令,它会在运行容器时自动执行。如果在运行容器时指定了其他命令,则这些命令将作为Entrypoint命令的参数传递给容器。

例如,在Dockerfile中指定Entrypoint为一个可执行文件,如下所示:

ENTRYPOINT ["./app"]

在运行容器时可以使用以下命令:

docker run myapp arg1 arg2

这样将运行容器,自动执行Entrypoint命令"./app",并将"arg1"和"arg2"作为参数传递给它。

Cmd是指定容器启动时要执行的默认命令或参数。它可以被覆盖,如果在运行容器时指定了其他命令,则这些命令将替换掉Cmd命令。

例如,在Dockerfile中指定Cmd为一个默认参数,如下所示:

CMD ["--port", "80"]

在运行容器时可以使用以下命令:

docker run myapp --port 8080

这样将运行容器,并使用"--port 8080"替换掉默认的Cmd命令参数"--port 80"。

总结来说,Entrypoint是指定容器启动时要执行的默认命令,它在运行容器时不能被覆盖。而Cmd是指定容器启动时要执行的默认命令参数,它可以被覆盖。通常情况下,Entrypoint用于指定容器启动时要运行的应用程序,而Cmd用于指定应用程序的默认参数。