我已经阅读了Docker的所有文档页面。
但我仍然不理解为什么需要提供"基础镜像"(例如Ubuntu Base Image)来在容器中安装/创建应用环境。
我的问题:
- 什么是基础镜像,它为什么是必须的?
- 为什么不能像Python的virtualenv一样直接创建容器并将应用程序放入其中?
一张图片只是文件系统和依赖项的快照,或者是特定应用程序/软件的一组目录。所谓快照,是指在容器环境中仅复制运行该软件所需的那些文件(例如mysql、redis等)及基本配置。当您使用图像创建容器时,系统的一小部分资源将通过命名空间和cgroups被隔离,然后将图像内的文件复制到这个隔离的资源环境中。
让我们了解一下什么是基础镜像:
基础镜像是我们最终想要创建的镜像的起点或初始步骤。
假设您想要一个运行redis的映像(这是一个愚蠢的例子,您可以通过其他方式达到相同的效果,但只是为了说明,请认为您在docker hub上找不到该映像)。您需要一个起点来创建该映像。因此,我们以Alpine镜像作为基础图像。
Alpine是最轻的镜像,仅包含运行基本命令的文件(例如:ls、cd、apk add在容器内)。
使用以下命令创建Dockerfile:
FROM alpine
RUN apk add --update redis
CMD ["redis-server"]
docker build .
命令时,它会输出以下内容: Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM alpine
---> a24bb4013296
Step 2/3 : RUN apk add --update redis
---> Running in 535bfd2d1ff1
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz
fetch http://dl-
cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz
(1/1) Installing redis (5.0.9-r0)
Executing redis-5.0.9-r0.pre-install
Executing redis-5.0.9-r0.post-install
Executing busybox-1.31.1-r16.trigger
OK: 7 MiB in 15 packages
Removing intermediate container 535bfd2d1ff1
---> 4c288890433b
Step 3/3 : CMD ["redis-server"]
---> Running in 7f01a4da3209
Removing intermediate container 7f01a4da3209
---> fc26d7967402
Successfully built fc26d7967402
redis-server
命令。RUN
命令仅在构建镜像过程中执行。
进一步解释该输出超出了本问题的范围。
因此,当您从Docker Hub下载一个镜像时,它只有运行基本要求的配置。 当您需要向镜像添加自己的要求和配置时,您需要创建一个Dockerfile
并逐层添加依赖项到基本镜像上,以根据您的需求运行它。
来自Docker文档,
"容器只是一个运行的进程,通过添加一些封装特性对其进行隔离,以使其与主机和其他容器隔离开来。
容器隔离最重要的方面之一是*每个容器都与其自己的私有文件系统交互;这个文件系统是由Docker镜像(像任何Linux操作系统的镜像一样——也是基础镜像)提供的。" 最终镜像可能包括多个层,这些层仅仅是一些其他文件系统更改。例如,运行Java应用程序时,您可以在基础Linux镜像上放置JDK层。
*鸣谢:图片来自Educative.io