Docker——理解好镜像和容器的关系

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: Docker——理解好镜像和容器的关系镜像也是 docker 的核心组件之一,镜像时容器运行的基础,容器是镜像运行后的形态。前面我们介绍了容器的用法,今天来和大家聊聊镜像的问题。​本文是本系列的第四篇,阅读前面文章有助于更好的理解本文:1.Docker 入门及安装[Docker 系列-1]2.Docker 容器基本操作[Docker 系列-2]3.Docker 容器高级操作[Docker 系列-3]总体来说,镜像是一个包含程序运行必要以来环境和代码的只读文件,它采用分层的文件系统,将每一层的改变以读写层的形式增加到原来的只读文件上。

Docker——理解好镜像和容器的关系
镜像也是 docker 的核心组件之一,镜像时容器运行的基础,容器是镜像运行后的形态。前面我们介绍了容器的用法,今天来和大家聊聊镜像的问题。

​本文是本系列的第四篇,阅读前面文章有助于更好的理解本文:

1.Docker 入门及安装[Docker 系列-1]

2.Docker 容器基本操作[Docker 系列-2]

3.Docker 容器高级操作[Docker 系列-3]

总体来说,镜像是一个包含程序运行必要以来环境和代码的只读文件,它采用分层的文件系统,将每一层的改变以读写层的形式增加到原来的只读文件上。这有点像洋葱,一层一层的,当我们后面学习了 Dockerfile ,相信大家对于这样的架构理解将更为准确。

镜像与容器的关系
前文已经向读者介绍过容器的使用了,细心的读者可能已经发现,容器在启动或者创建时,必须指定一个镜像的名称或者 id ,其实,这时镜像所扮演的角色就是容器的模版,不同的镜像可以构造出不同的容器,同一个镜像,我们也可以通过配置不同参数来构造出不通的容器。如下命令:

docker run -itd --name nginx nginx
命令中的最后一个 nginx 即表示创建该容器所需要的镜像(模版),当然这里还省略了一些信息,例如版本号等,这些我们后文会详细介绍。

镜像的体系结构
镜像的最底层是一个启动文件系统(bootfs)镜像,bootfs 的上层镜像叫做根镜像,一般来说,根镜像是一个操作系统,例如 Ubuntu、CentOS 等,用户的镜像必须构建于根镜像之上,在根镜像之上,用户可以构建出各种各样的其他镜像。
从上面的介绍读者可以看出,镜像的本质其实就是一系列文件的集合,一层套一层的结构有点类似于 Git ,也有点类似于生活中的洋葱

镜像的写时复制机制
通过 docker run 命令指定一个容器创建镜像时,实际上是在该镜像之上创建一个空的可读写的文件系统层级,可以将这个文件系统层级当成一个临时的镜像来对待,而命令中所指的模版镜像则可以称之为父镜像。父镜像的内容都是以只读的方式挂载进来的,容器会读取共享父镜像的内容,用户所做的所有修改都是在文件系统中,不会对父镜像造成任何影响。当然用户可以通过其他一些手段使修改持久化到父镜像中,这个我们后面会详细介绍到。

简而言之,镜像就是一个固定的不会变化的模版文件,容器是根据这个模版创建出来的,容器会在模版的基础上做一些修改,这些修改本身并不会影响到模版,我们还可以根据模版(镜像)创建出来更多的容器。

如果有必要,我们是可以修改模版(镜像)的。

镜像查看
用户可以通过 docker images 命令查看本地所有镜像,如下:

这里一共有五个参数,含义分别如下:

TAG: TAG用于区分同一仓库中的不同镜像,默认为latest。

IMAGE ID: IMAGE ID是镜像的一个唯一标识符。

CREATED: CREATED表示镜像的创建时间。

SIZE: SIZE表示镜像的大小。

REPOSITORY:仓库名称,仓库一般用来存放同一类型的镜像。仓库的名称由其创建者指定。如果没有指定则为 。一般来说,仓库名称有如下几种不同的形式:

使用 docker images 命令可以查看本地所有的镜像,如果镜像过多,可以通过通配符进行匹配,如下:

如果需要查看镜像的详细信息,也可以通过上文提到的 docker inspect 命令来查看。

镜像下载
当用户执行 docker run 命令时,就会自动去 Docker Hub 上下载相关的镜像,这个就不再重复演示,开发者也可以通过 search 命令去 Docker Hub 上搜索符合要求的镜像,如下:

其中:

NAME:表示镜像的名称。

DESCRIPTION:表示镜像的简要描述。

STARS:表示用户对镜像的评分,评分越高越可以放心使用。

OFFICIAL:是否为官方镜像。

AUTOMATED:是否使用了自动构建。

在执行 docker run 命令时再去下载,速度会有点慢,如果希望该命令能够快速执行,可以在执行之前,先利用 docker pull 命令将镜像先下载下来,然后再运行。

运行命令如下:

镜像删除
镜像可以通过 docker rmi 命令进行删除,参数为镜像的id或者镜像名,参数可以有多个,多个参数之间用空格隔开。如下:

有的时候,无法删除一个镜像,大部分原因是因为该镜像被一个容器所依赖,此时需要先删除容器,然后就可以删除镜像了,删除容器的命令可以参考本系列前面的文章。

通过前面文章的阅读,读者已经了解到所谓的容器实际上是在父镜像的基础上创建了一个可读写的文件层级,所有的修改操作都在这个文件层级上进行,而父镜像并未受影响,如果读者需要根据这种修改创建一个新的本地镜像,有两种不同的方式,先来看第一种方式:commit。

创建容器
首先,根据本地镜像运行一个容器,如下:

命令解释:

首先执行 docker images 命令,查看本地镜像。

根据本地镜像中的 nginx 镜像,创建一个名为 nginx 的容器,并启动。

将宿主机中一个名为 index.html 的文件拷贝到容器中。

访问容器,发现改变已经生效。

接下来再重新创建一个容器,名为 nginx2.

访问 nginx2 ,发现 nginx2 中默认的页面还是 nginx 的默认页面,并未发生改变。

commint 创建本地镜像
接下来,根据刚刚创建的第一个容器,创建一个本地镜像,如下:

命令解释:

参数 -m 是对创建的该镜像的一个简单描述。

--author 表示该镜像的作者。

ce1fe32739402 表示创建镜像所依据的容器的 id。

sang/nginx 则表示仓库名,sang 是名称空间,nginx 是镜像名。

v1 表示仓库的 tag。

创建完成后,通过 docker images 命令就可以查看到刚刚创建的镜像。

通过刚刚创建的镜像运行一个容器,访问该容器,发现 nginx 默认的首页已经发生改变。

这是我们通过 commint 方式创建本地镜像的方式,但是 commit 方式存在一些问题,比如不够透明化,无法重复,体积较大,为了解决这些问题,可以考虑使用 Dockerfile ,实际上,主流方案也是 Dockerfile。

Dockerfile
Dockerfile 就是一个普通的文本文件,其内包含了一条条的指令,每一条指令都会构建一层。先来看一个简单的例子。

首先在一个空白目录下创建一个名为 Dockerfile 的文件,内容如下:

命令解释:

FROM nginx 表示该镜像的构建,以已有的 nginx 镜像为基础,在该镜像的基础上构建。

MAINTAINER 指令用来声明创建镜像的作者信息以及邮箱信息,这个命令不是必须的。

RUN 指令用来修改镜像,算是使用比较频繁的一个指令了,该指令可以用来安装程序、安装库以及配置应用程序等,一个 RUN 指令执行会在当前镜像的基础上创建一个新的镜像层,接下来的指令将在这个新的镜像层上执行,RUN 语句有两种不同的形式:shell 格式和 exec 格式。本案例采用的 shell 格式,shell 格式就像 linux 命令一样,exec 格式则是一个 JSON 数组,将命令放到数组中即可。在使用 RUN 命令时,适当的时候可以将多个 RUN 命令合并成一个,这样可以避免在创建镜像时创建过多的层。

COPY 语句则是将镜像上下文中的 hello.html 文件拷贝到镜像中。

文件创建完成后,执行如下命令进行构建:

命令解释:

-t 参数用来指定镜像的命名空间,仓库名以及 TAG 等信息。

最后面的 . 是指镜像构建上下文。

注意:

Docker 采用了 C/S 架构,分为 Docker 客户端(Docker 可执行程序)与 Docker 守护进程,Docker 客户端通过命令行和 API 的形式与 Docker 守护进程进行通信,Docker 守护进程则提供 Docker 服务。因此,我们操作的各种 docker 命令实际上都是由 docker 客户端发送到 docker 守护进程上去执行。我们在构建一个镜像时,不可避免的需要将一些本地文件拷贝到镜像中,例如上文提到的 COPY 命令,用户在构建镜像时,需要指定构建镜像的上下文路径(即前文的 . ), docker build 在获得这个路径之后,会将路径下的所有内容打包,然后上传给 Docker 引擎。

镜像构建成功后,可以通过 docker images 命令查看,如下:

然后创建容器并启动,就可以看到之前的内容都生效了。

总结
本文主要向大家介绍了 Docker 中镜像的基本操作,操作其实并不难,关键是理解好镜像和容器的关系,以及镜像洋葱式的文件结构。
原文地址https://www.cnblogs.com/justdojava/p/11271246.html

相关文章
|
22小时前
|
监控 安全 数据安全/隐私保护
【Docker专栏】Docker容器安全:防御与加固策略
【5月更文挑战第7天】本文探讨了Docker容器安全,指出容器化技术虽带来便利,但也存在安全隐患,如不安全的镜像、容器逃逸、网络配置不当等。建议采取使用官方镜像、镜像扫描、最小权限原则等防御措施,并通过安全的Dockerfile编写、运行时安全策略、定期更新和访问控制等加固容器安全。保持警惕并持续学习安全实践至关重要。
【Docker专栏】Docker容器安全:防御与加固策略
|
22小时前
|
前端开发 API 数据库
【Docker专栏】Docker Compose实战:编排多容器应用
【5月更文挑战第7天】Docker Compose是Docker的多容器管理工具,通过YAML文件简化多容器应用部署。它能一键启动、停止服务,保证开发、测试和生产环境的一致性。安装后,创建`docker-compose.yml`文件定义服务,如示例中的web和db服务。使用`docker-compose up -d`启动服务,通过`docker-compose ps`、`stop`、`down`和`logs`命令管理服务。
【Docker专栏】Docker Compose实战:编排多容器应用
|
22小时前
|
缓存 安全 数据安全/隐私保护
【Docker专栏】深入理解Docker镜像的构建与推送
【5月更文挑战第7天】本文介绍了Docker镜像的核心作用及基础概念,包括镜像作为容器模板的特性。文章详细阐述了Dockerfile的编写,例如设置基础镜像、工作目录、安装依赖及定义启动命令。通过`docker build`命令构建镜像,并提示了优化构建过程的技巧。此外,还讲解了如何将镜像推送到远程仓库,包括选择仓库、认证、标签和推送镜像的步骤,以及镜像安全性的考虑,如扫描漏洞和遵循最小权限原则。本文旨在帮助读者掌握Docker镜像的构建与推送,以高效管理容器化应用。
【Docker专栏】深入理解Docker镜像的构建与推送
|
22小时前
|
应用服务中间件 持续交付 nginx
【Docker专栏】Docker入门指南:快速构建你的第一个容器
【5月更文挑战第7天】Docker 入门指南:容器化应用利器。了解 Docker 核心概念——镜像、容器和仓库。安装 Docker 后,运行官方 `hello-world` 验证安装,再尝试运行 `nginx` Web 服务器。通过端口映射访问容器内服务,学习管理容器命令。创建自定义镜像,编写 Dockerfile,实现 Python Web 应用容器化。Docker 助力高效开发与运维,探索更多自动化部署与微服务场景。
【Docker专栏】Docker入门指南:快速构建你的第一个容器
|
23小时前
|
运维 Linux Apache
Docker详解(十二)——Docker容器权限问题
Docker详解(十二)——Docker容器权限问题
15 5
|
23小时前
|
存储 运维 Linux
Docker详解(十)——Docker容器CPU资源限额配置
Docker详解(十)——Docker容器CPU资源限额配置
11 3
|
1天前
|
前端开发 算法 数据中心
Docker consul的容器服务更新与发现
服务注册与发现解决分布式架构中服务定位和管理问题,允许动态更新与发现服务网络位置,减少配置维护。Consul是Google开源的多数据中心、高可用服务管理工具,提供服务发现、健康检查和配置共享功能。采用Raft算法确保高可用性,节点运行Agent,有Server和Client两种模式。Server模式负责信息持久化和同步,而Client模式只转发服务。每个数据中心推荐3-5个Server节点以保证数据安全和选举稳定性。
|
1天前
|
运维 Linux 数据安全/隐私保护
Docker详解(九)——Docker镜像发布
Docker详解(九)——Docker镜像发布
17 2
|
1天前
|
运维 Linux Apache
Docker详解(八)——Docker镜像制作
Docker详解(八)——Docker镜像制作
27 1
|
7天前
|
存储 Linux 文件存储
Linux使用Docker部署Traefik容器并实现远程访问管理界面-1
Linux使用Docker部署Traefik容器并实现远程访问管理界面