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创建的镜像层,很可能是很久前的缓存。


相关文章
|
2天前
|
缓存 Linux 网络安全
docker的镜像无法下载如何解决?
【10月更文挑战第31天】docker的镜像无法下载如何解决?
103 28
|
16天前
|
缓存 监控 持续交付
|
4天前
|
存储 监控 Linux
docker构建镜像详解!!!
本文回顾了Docker的基本命令和管理技巧,包括容器和镜像的增删改查操作,容器的生命周期管理,以及如何通过端口映射和数据卷实现容器与宿主机之间的网络通信和数据持久化。文章还详细介绍了如何使用Docker部署一个简单的Web应用,并通过数据卷映射实现配置文件和日志的管理。最后,文章总结了如何制作自定义镜像,包括Nginx、Python3和CentOS镜像,以及如何制作私有云盘镜像。
47 2
|
6天前
|
关系型数据库 MySQL Docker
docker环境下mysql镜像启动后权限更改问题的解决
在Docker环境下运行MySQL容器时,权限问题是一个常见的困扰。通过正确设置目录和文件的权限,可以确保MySQL容器顺利启动并正常运行。本文提供了多种解决方案,包括在主机上设置正确的权限、使用Dockerfile和Docker Compose进行配置、在容器启动后手动更改权限以及使用 `init`脚本自动更改权限。根据实际情况选择合适的方法,可以有效解决MySQL容器启动后的权限问题。希望本文对您在Docker环境下运行MySQL容器有所帮助。
14 1
|
7天前
|
存储 Java 开发者
成功优化!Java 基础 Docker 镜像从 674MB 缩减到 58MB 的经验分享
本文分享了如何通过 jlink 和 jdeps 工具将 Java 基础 Docker 镜像从 674MB 优化至 58MB 的经验。首先介绍了选择合适的基础镜像的重要性,然后详细讲解了使用 jlink 构建自定义 JRE 镜像的方法,并通过 jdeps 自动化模块依赖分析,最终实现了镜像的大幅缩减。此外,文章还提供了实用的 .dockerignore 文件技巧和选择安全、兼容的基础镜像的建议,帮助开发者提升镜像优化的效果。
|
12天前
|
存储 缓存 Java
Java应用瘦身记:Docker镜像从674MB优化至58MB的实践指南
【10月更文挑战第22天】 在容器化时代,Docker镜像的大小直接影响到应用的部署速度和运行效率。一个轻量级的Docker镜像可以减少存储成本、加快启动时间,并提高资源利用率。本文将分享如何将一个Java基础Docker镜像从674MB缩减到58MB的实践经验。
22 1
|
18天前
|
Docker 容器
docker:记录如何在x86架构上构造和使用arm架构的镜像
为了实现国产化适配,需将原x86平台上的Docker镜像转换为适用于ARM平台的镜像。本文介绍了如何配置Docker buildx环境,包括检查Docker版本、安装buildx插件、启用实验性功能及构建多平台镜像的具体步骤。通过这些操作,可以在x86平台上成功构建并运行ARM64镜像,实现跨平台的应用部署。
193 2
|
22天前
|
网络协议 Docker 容器
docker pull命令拉取镜像失败的解决方案
docker pull命令拉取镜像失败的解决方案
489 0
|
30天前
|
Java Docker 微服务
SpringBoot微服务打包Docker镜像
SpringBoot微服务打包Docker镜像
|
23天前
|
Go Docker Python
docker的python与go镜像的制作
docker的python与go镜像的制作
26 1