第一部分:问题
虽然知道image和container,一个是镜像一个是实例,但还是理解不太深刻docker镜像和容器的区别,特别是在使用过程中。
第二部分:回答
一、两者命名
1)镜像
方法一:docker-compose.yml中确定名称
# docker-compose.yml
version: '3.8'
services:
jupyter:
image: my-jupyter-image:latest
ports:
- "8888:8888"
volumes:
- ./work:/home/jovyan/work
environment:
JUPYTER_TOKEN: "your_secure_token"
command: "start-notebook.sh --NotebookApp.token='your_secure_token'"
volumes:
work:
方法二:启动时命令行命名镜像
当你使用 docker build
命令构建镜像时,可以使用 -t
选项为镜像指定一个名称和标签。例如:
docker build -t my-jupyter-image:latest
在这个命令中:
my-jupyter-image
是镜像名称。latest
是标签(tag),默认值是latest
。
你可以根据需要选择镜像名称和标签,标签用于区分同一镜像的不同版本。
2)容器
在 docker-compose.yml
文件中,容器名可以通过两种方式定义:
- 使用
container_name
属性:你可以显式地为服务定义一个容器名。 - 默认命名:如果没有显式定义,
docker-compose
会根据项目名和服务名生成一个默认的容器名。
方法一:显式定义-使用 container_name
属性
你可以在 docker-compose.yml
文件中通过 container_name
属性显式地定义容器名。例如:
version: '3.8'
services:
jupyter:
image: my-jupyter-image:latest
container_name: my_jupyter_container
ports:
- "8888:8888"
volumes:
- ./work:/home/jovyan/work
environment:
JUPYTER_TOKEN: "your_secure_token"
command: "start-notebook.sh --NotebookApp.token='your_secure_token'"
在这个示例中,容器名被显式地设置为 my_jupyter_container
。
方法二:隐式定义-默认命名
如果你没有显式定义容器名,docker-compose
会使用默认命名规则。默认的容器名格式是 项目名_服务名_索引
。例如,如果你的项目名是 myproject
,服务名是 jupyter
,且这是该服务的第一个容器,默认容器名将是 myproject_jupyter_1
。
检查容器名
你可以使用 docker ps
命令来查看当前正在运行的容器及其名称:
docker ps
输出示例:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 my-jupyter-image:latest "start-notebook.sh ..." 2 minutes ago Up 2 minutes 0.0.0.0:8888->8888/tcp my_jupyter_container
在这个示例中,NAMES
列显示了容器的名称。
二、两者关系
在 Docker 中,image镜像是一个静态的、不可更改的文件,它包含了用于运行容器的文件系统内容和运行时配置。而container容器是镜像的运行实例,每个容器都是根据同一个镜像创建的,但它们之间是独立的、隔离的运行环境。
在 Docker 中,可以根据同一个镜像创建多个容器实例,每个容器实例都具有独立的文件系统和运行时配置,它们彼此之间相互隔离。每次启动一个容器,都会产生一个新的、唯一的容器实例。这些容器实例可以通过不同的名称(由 Docker 自动生成或者显式指定)来标识和引用。
因此,可以把一系列配置和依赖打包成一个镜像,并且根据需要在不同的环境中启动多个容器实例来运行你的应用程序。每个容器实例都是相互独立的,它们之间不会相互影响,可以并行运行,提供高度的灵活性和可伸缩性。