docker基础知识--镜像

简介: Docker的核心组件包括:Docker 客户端:ClientDocker 服务器:Docker daemonDocker 镜像:ImageRegistryDocker 容器:Container

docker 架构

Docker的核心组件包括:

  • Docker 客户端:Client
  • Docker 服务器:Docker daemon
  • Docker 镜像:Image
  • Registry
  • Docker 容器:Container

image.png

Docker 采用的是 Client/Server 架构。客户端向服务器发送请求,服务器负责构建、运行和分发容器。

  1. Docker 客户端

常用的客户端就是 docker 命令,除了 docker 命令行工具,也可以通过 RESTAPI 与服务器通信。

  1. Docker 服务器

Docker daemon是服务器组件,以Linux后台服务的方式运行。Docker daemon 运行在Docker host上,负责创建、运行、监控容器,构建、存储镜像。

image.png

  1. Docker 镜像

镜像可以看做是一个只读模板,通过镜像可以生成容器。 镜像的生成:

  • 从零构建一个镜像
  • 下载使用别人构建的镜像
  • 在现有的镜像上构建新的镜像
  1. Docker 容器

容器就是镜像的运行实例。

  1. Registry

Registry 是存放 Docker 镜像的仓库,Registry 分私有和公有两种。 Docker Hub(htps:/hub.docker.com/)是默认的Registry,由Docker公司维护,上面的镜像,用户可以自由下载和使用。

用户也可以创建自己的私有Registry。

docker pull 命令可以从 Registry下载镜像。 docker run 命令则是先下载镜像(如果本地没有),然后再启动容器。

Docker 镜像

镜像常用命令:

  • images: 显示镜像列表
  • history: 显示镜像构建历史
  • commit: 从容器创建新镜像
  • build: 从Dockerfile构建镜像
  • tag: 给镜像打tag
  • pull: 从registry下载镜像
  • push: 将镜像上传到registry
  • rmi: 删除Docker host中的镜像
  • search: 搜索Docker Hub中的镜像

hello-world

hello-world 是 Docker 官方提供的一个镜像,通常用来验证Docker是否安装成功。

我们使用命令 docker pull hello-world 拉取镜像,使用命令 docker images 查看镜像信息。

image.png

base 镜像

base 镜像:

  • 不依赖其他镜像,从 scratch 构建
  • 其他镜像可以以此为基础进行扩展

所以,base 镜像通常都是各linux 发行版的 docker 镜像。

Linux 操作系统由内核空间和用户空间组成,内核空间是 kernel,用户空间的文件系统是 rootfs(包含 /dev、/proc、/bin等)。base 镜像底层直接使用 Host 的 kernel,自己只提供 rootfs。所以 docker 构建的系统镜像非常小。 容器只能使用 host 的kernel,不能修改,如果容器对 kernel 版本有要求,则不建议用容器,使用虚拟机也许更适合。

镜像的分层结构

新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。

这样的话,最大的一个好处就是:共享资源。

比如:有多个镜像都从相同的base镜像构建而来,那么Docker Host只需在磁盘上保存一份base镜像;同时内存中也只需加载一份base镜像,就可以为所有容器服务了,而且镜像的每一层都可以被共享。

当某个容器修改了基础镜像的内容,并不会影响其他容器的基础镜像,修改会被限制在单个容器内,这就是容器 Copy-on-Wite特性

Copy-on-Wite

当容器启动时,一个新的可写层被加载到镜像的顶部。这一层被称为“容器层”,所有对容器的改动(添加、删除,修改)都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。

image.png

镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如/a,上层的/a会覆盖下层的/a,也就是说用户只能访问到上层中的文件/a。在容器层中,用户看到的是一个叠加之后的文件系统。

(1)添加文件。在容器中创建文件时,新文件被添加到容器层中。

(2)读取文件。在容器中读取某个文件时,Docker会从上往下依次在各镜像层中查找此文件。一且找到,打开并读入内存。

(3)修改文件。在容器中修改已存在的文件时,Docker会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。

(4)删除文件。在容器中删除文件时,Docker也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。

只有当需要修改时才复制一份数据,这种特性被称作Copy-on-Wite。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。 容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。

构建镜像

docker commit 构建

使用 docker commit 构建主要包含三步:

  • 运行容器。
  • 修改容器。
  • 将容器保存为新的镜像。

例如:我们使用 docker run -it CONTAINER  进入容器,在容器中安装了某些程序,退出容器执行 docker commit CONTAINER [REPOSITORY[:TAG]]。这样就创建了一个新的镜像。

但是并不建议使用此方式构建镜像,原因是不可复用构建过程,且构建过程不直观,存在安全隐患。

Dockerfile 构建

Dockerfile 是一个文本文件,记录的是镜像构建的所有步骤。

执行 docker build -t 新镜像名 . 构建镜像。

  • -t : 指定构建的新镜像名称
  • .:指定 build context 为当前目录。(build context 为镜像构建提供所需的文件或目录)
  • Docker 默认从 build context 中查找 Dockerfile 文件,也可以通过 -f 参数指定 Dockerfile 的位置。

build context 目录下的所有文件和子目录都会发送给 Docker daemon,所以使用 build context 应当注意,不要将多余的文件放到其中,否则会构建缓慢甚至失败。

构建完成功,我们可以使用 docker history 镜像名 来查看镜像的Dockerfile 执行过程。

镜像缓存特性

Docker 会缓存已有镜像的镜像层,构建新镜像时,如果某镜像层已经存在,就直接使用,无须重新创建。

若希望在构建镜像时不使用缓存,可以在 docker build 命令中加上-no-cache参数。

Dockerfile 中每一个指令都会创建一个镜像层,上层是依赖于下层的。无论什么时候,只要某一层发生变化,其上面所有层的缓存都会失效。

也就是说,如果我们改变 Dockerfile 指令的执行顺序,或者修改或添加指令,都会使缓存失效。

调试 Dockerfile

Dockerfile构建镜像的过程:

  • (1)从base镜像运行一个容器。
  • (2)执行一条指令,对容器做修改。
  • (3)执行类似docker commit的操作,生成一个新的镜像层。
  • (4)Docker再基于刚刚提交的镜像运行一个新容器。
  • (5)重复2~4步,直到Dockerfile中的所有指令执行完毕。

从这个过程可以看出,如果Dockerfile由于某种原因执行到某个指令失败了,我们也将能够得到前一个指令成功执行构建出的镜像,这对调试 Dockerfile非常有帮助。我们可以运行最新的这个镜像定位指令失败的原因。

方法是通过 docker run -it 镜像,启动镜像的一个容器,根据报错信息来进行调试。


image.png

image.png

Dockerfile 常用指令

1.. #

Dockerfile 支持“#”开头的注释。

  1. FROM
    指定base镜像。
  2. MAINTAINER
    设置镜像的作者,可以是任意字符串。
  3. COPY
    将文件从 build context 复制到镜像。
    COPY支持两种形式:COPY src dest 与 COPY["src","dest"]。
    注意:src 只能指定 build context中的文件或目录。
  4. ADD
    与COPY类似,从build context复制文件到镜像。不同的是,如果 src 是归档文件(tar、zip、gz、xz等),文件会被自动解压到dest。
  5. ENV
    设置环境变量,环境变量可被后面的指令使用。
  6. EXPOSE
    指定容器中的进程会监听某个端口,Docker可以将该端口暴露出来。
  7. VOLUME
    将文件或目录声明为 volume。
  8. WORKDIR
    为后面的 RUN、CMD、ENTRYPOINT、ADD或 COPY 指令设置镜像中的当前工作目录。
  9. RUN
    在容器中运行指定的命令。
  10. CMD
    容器启动时运行指定的命令。
    Dockerfile 中可以有多个CMD指令,但只有最后一个生效。CMD可以被docker run 之后的参数替换。
  11. ENTRYPOINT
    设置容器启动时运行的命令。
    Dockerfile中可以有多个ENTRYPOINT指令,但只有最后一个生效。CMD或docker run 之后的参数会被当作参数传递给 ENTRYPOINT。

RUN/CMD/ENTRYPOINT

  • (1)RUN: 执行命令并创建新的镜像层,RUN经常用于安装软件包。
  • (2)CMD: 设置容器启动后默认执行的命令及其参数,但CMD能够被docker run后面跟的命令行参数替换。
  • (3)ENTRYPOINT: 配置容器启动时运行的命令。ENTRYPOINT 看上去与CMD 很像,它们都可以指定要执行的命令及具参数。区别是 ENTRYPOINT不会被忽略,一定会被执行,即使运行docker run时指定了其他命令。

注意:使用 RUN 安装包时,运行 apt-get update && gpt-get install.... ,这样放在一个 RUN 指令中执行,能够保证每次安装的是最新的包,否则使用 apt-get update创建的镜像层,很可能是很久前的缓存。


相关文章
|
22天前
|
Docker 容器
将本地的应用程序打包成Docker镜像
将本地的应用程序打包成Docker镜像
|
6天前
|
NoSQL PHP MongoDB
docker push推送自己搭建的镜像
本文详细介绍了如何搭建和复盘两个Web安全挑战环境:人力资源管理系统和邮件管理系统。首先,通过Docker搭建MongoDB和PHP环境,模拟人力资源管理系统的漏洞,包括nosql注入和文件写入等。接着,复盘了如何利用这些漏洞获取flag。邮件管理系统部分,通过目录遍历、文件恢复和字符串比较等技术,逐步绕过验证并最终获取flag。文章提供了详细的步骤和代码示例,适合安全研究人员学习和实践。
24 3
docker push推送自己搭建的镜像
|
22天前
|
数据库 Docker 容器
Docker在现代软件开发中扮演着重要角色,通过Dockerfile自动化构建Docker镜像,实现高效、可重复的构建过程。
Docker在现代软件开发中扮演着重要角色,通过Dockerfile自动化构建Docker镜像,实现高效、可重复的构建过程。Dockerfile定义了构建镜像所需的所有指令,包括基础镜像选择、软件安装、文件复制等,极大提高了开发和部署的灵活性与一致性。掌握Dockerfile的编写,对于提升软件开发效率和环境管理具有重要意义。
42 9
|
1月前
|
缓存 Linux 网络安全
docker的镜像无法下载如何解决?
【10月更文挑战第31天】docker的镜像无法下载如何解决?
1820 30
|
22天前
|
存储 缓存 运维
Docker镜像采用分层存储,每层代表镜像的一部分,如基础组件或应用依赖,多层叠加构成完整镜像
Docker镜像采用分层存储,每层代表镜像的一部分,如基础组件或应用依赖,多层叠加构成完整镜像。此机制减少存储占用,提高构建和传输效率。Docker还通过缓存机制提升构建和运行效率,减少重复工作。文章深入解析了Docker镜像分层存储与缓存机制,包括具体实现、管理优化及实际应用案例,帮助读者全面理解其优势与挑战。
43 4
|
2月前
|
缓存 监控 持续交付
|
1月前
|
存储 关系型数据库 Linux
【赵渝强老师】什么是Docker的镜像
Docker镜像是一个只读模板,包含应用程序及其运行所需的依赖环境。镜像采用分层文件系统,每次修改都会以读写层形式添加到原只读模板上。内核bootfs用于加载Linux内核,根镜像相当于操作系统,上方为应用层。镜像在物理存储上是一系列文件的集合,默认存储路径为“/var/lib/docker”。
|
1月前
|
存储 监控 Linux
docker构建镜像详解!!!
本文回顾了Docker的基本命令和管理技巧,包括容器和镜像的增删改查操作,容器的生命周期管理,以及如何通过端口映射和数据卷实现容器与宿主机之间的网络通信和数据持久化。文章还详细介绍了如何使用Docker部署一个简单的Web应用,并通过数据卷映射实现配置文件和日志的管理。最后,文章总结了如何制作自定义镜像,包括Nginx、Python3和CentOS镜像,以及如何制作私有云盘镜像。
156 2
|
1月前
|
关系型数据库 MySQL Docker
docker环境下mysql镜像启动后权限更改问题的解决
在Docker环境下运行MySQL容器时,权限问题是一个常见的困扰。通过正确设置目录和文件的权限,可以确保MySQL容器顺利启动并正常运行。本文提供了多种解决方案,包括在主机上设置正确的权限、使用Dockerfile和Docker Compose进行配置、在容器启动后手动更改权限以及使用 `init`脚本自动更改权限。根据实际情况选择合适的方法,可以有效解决MySQL容器启动后的权限问题。希望本文对您在Docker环境下运行MySQL容器有所帮助。
172 1