每个 docker 容器直接只提供一个 shell 吗?
我有一个 python 图像:
$ sudo docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
python 2.7-slim 48e3247f2a19 10 days ago 120MB
我原本以为它向我展示了Python。
但我无法直接在容器中运行 python 命令:
$ sudo docker run 48e3 print("hello")
bash: syntax error near unexpected token `('
我可以直接在容器中运行命令,就像在 shell 中一样:
$ sudo docker run 48e3 ls
bin
boot
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
$ sudo docker run 48e3 python --version
Python 2.7.16
答案1
容器如何执行取决于它的构建方式。在构建器中Dockerfile
可能有CMD
和ENTRYPOINT
选项。
例如,这是一个从不调用 的容器/bin/sh
。
首先,我们要运行的程序。我把它写下来go
只是因为它很容易演示。
$ cat small.go
package main
import "fmt"
import "os"
func main() {
fmt.Println("Hello")
fmt.Print("You entered ")
fmt.Println(os.Args[1:])
}
$ go build small.go
现在是构建容器的说明:
$ cat Dockerfile
FROM scratch
ADD small /
ENTRYPOINT ["/small"]
$ docker build -t small .
Sending build context to Docker daemon 1.642MB
Step 1/3 : FROM scratch
--->
Step 2/3 : ADD small /
---> Using cache
---> 6171cecbf91b
Step 3/3 : ENTRYPOINT ["/small"]
---> Using cache
---> 14af8187a035
Successfully built 14af8187a035
Successfully tagged small:latest
现在运行容器:
$ docker run --rm small some options passed
Hello
You entered [some options passed]
事实上,这个容器只包含一个文件,即small
程序,除此之外什么也没有!没有 shell,没有库,什么都没有。
python
现在,如果您正确运行并且不传递任何参数,您正在查看的 docker 映像将落入其中
$ docker run --rm -it python:2.7-slim
Python 2.7.16 (default, Mar 27 2019, 09:57:44)
[GCC 6.3.0 20170516] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
如果我们检查图像,我们可以看到......
$ docker inspect python:2.7-slim
...
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"python2\"]"
],
所以我们可以看到它是CMD
使用 中的选项构建的Dockerfile
。这告诉它默认如果没有其他命令传递给docker run
调用,则要运行的命令。
因此,对于这个容器,python
如果没有被告知运行其他任何东西,它就会运行。
这意味着我们可以做一些有趣的事情,比如
$ echo 'print("hello")' | docker run --rm -i python:2.7-slim
hello