• Docker核心概念:镜像、容器、仓库


    1. 镜像

    镜像是什么呢?通俗地讲,它是一个只读的文件和文件夹组合。它包含了容器运行时所需要的所有基础文件和配置信息,是容器启动的基础。所以你想启动一个容器,那首先必须要有一个镜像。镜像是 Docker 容器启动的先决条件。

    简单来讲,镜像是一个特殊的文件系统,它提供了容器运行时所需的程序、软件库、资源、配置等静态数据。即镜像不包含任何动态数据,镜像内容在构建后不会被改变。

    如果你想要使用一个镜像,你可以用这两种方式:

    1. 自己创建镜像。通常情况下,一个镜像是基于一个基础镜像构建的,你可以在基础镜像上添加一些用户自定义的内容。例如你可以基于centos镜像制作你自己的业务镜像,首先安装nginx服务,然后部署你的应用程序,最后做一些自定义配置,这样一个业务镜像就做好了。
    2. 从功能镜像仓库拉取别人制作好的镜像。一些常用的软件或者系统都会有官方已经制作好的镜像,例如nginx、ubuntu、centos、mysql等,你可以到 Docker Hub 搜索并下载它们。

    镜像的实现原理:

    镜像是由一系列的镜像层(layer )组成,每一层代表了镜像构建过程中的一次提交,当我们需要修改镜像内的某个文件时,只需要在当前镜像层的基础上新建一个镜像层,并且只存放修改过的文件内容。分层结构使得镜像间共享镜像层变得非常简单和方便。

    更具体的讲解见:Docker镜像实现原理

    2. 容器

    2.1 容器的概念

    镜像和容器的关系,就像是面向对象程序设计中的实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

    容器的本质是一个进程,但与直接在宿主执行的进程不同,容器进程有自己独立的命名空间隔离和资源限制。因此容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。在容器内部,无法看到主机上的进程、环境变量、网络等信息,这是容器与直接运行在主机上进程的本质区别。

    容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。

    通俗地讲,容器是镜像的运行实体。

    1. 容器是基于镜像创建的可运行实例,并且单独存在,一个镜像可以创建出多个容器。运行容器化环境时,实际上是在容器内部创建该文件系统的读写副本。 这将添加一个容器层,该层允许修改镜像的整个副本。
    2. 容器文件系统的本质是在镜像层上面创建的读写层,运行中的容器对任何文件的修改都存在于该读写层,当容器被删除时,容器中的读写层也会随之消失。
    3. 容器的文件系统设计成写时复制,而不是每一个容器都单独拷贝一份镜像文件,写时复制是指在容器中,只有需要修改某个文件时,才会把文件从镜像层复制到容器层,写时复制的操作将会复制整个文件,如果文件过大,将会大大降低文件系统的性能,因此当我们有大量文件需要被修改时,可能会出现明显的延迟。好在,写时复制操作只在第一次修改文件时触发,对日常使用没有太大影响。当文件或目录被删除时,并不会真正从镜像中删除它,因为镜像层是只读的,会创建一个特殊的文件或文件夹,这种特殊的文件或文件夹会阻止容器的访问。

    这里不理解的话可以查看docker联合文件系统的内容:Docker底层:联合文件系统 。

    如图 1 所示。

    为什么要设置成写时复制呢?

    每个容器单独拷贝一份镜像文件会占用较多的磁盘空间。假设我有3个程序都用到了jdk镜像,那该jdk镜像就得复制3份。如果改成写时复制的话,只需要一份jdk镜像,新的内容写在顶层即可。比如用docker images查看镜像的时候,把所有镜像的SIZE加起来可能有十几个G,但是到目录下查看,实际上只有几个G,这是因为很多镜像复用了同一个底层的镜像,起到了节省磁盘空间的作用。

    一方面保护镜像文件,另一方面可以共享相同的镜像层。

    2.2 容器的生命周期

    容器的生命周期是容器可能处于的状态,容器的生命周期分为 5 种。

    created:初建状态

    running:运行状态

    stopped:停止状态

    paused:暂停状态

    deleted:删除状态

    各生命周期之前的转换关系如图所示:

    3. 仓库

    仓库(Repository)是存储和分发 Docker 镜像的地方。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。以 Ubuntu 镜像 为例,ubuntu 是仓库的名字,其内包含有不同的版本标签,如,16.04, 18.04。我们可以通过 ubuntu:16.04,或者 ubuntu:18.04 来具体指定所需哪个版本的镜像。如果忽略了标签,比如 ubuntu,那将视为 ubuntu:latest。仓库名经常以 两段式路径 形式出现,比如 jwilder/nginx-proxy,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务。

    镜像仓库分为公共镜像仓库和私有镜像仓库。

    • 公共镜像仓库一般是 Docker 官方或者其他第三方组织(阿里云,腾讯云,网易云等)提供的,允许所有人注册和使用的镜像仓库。使用docker pull命令可以从仓库拉取镜像,Docker 默认会从 docker.io 拉取镜像。使用docker login命令登录镜像服务器后,可以使用docker push命令推送镜像到自己创建的仓库中。
    • 除了公开镜像仓库,你也可以构建自己的私有镜像仓库,搭建教程:搭建私有镜像仓库教程

    注册服务器(Registry)和仓库(Repository)的区别:

    注册服务器是存放仓库的实际服务器,而仓库则可以被理解为一个具体的项目或者目录;注册服务器可以包含很多个仓库,每个仓库又可以包含多个镜像。例如我的镜像地址为 docker.io/centos,docker.io 是注册服务器,centos 是仓库名。 它们之间的关系如图 1 所示。最常使用的 Registry 公开服务是官方的 Docker Hub,这也是默认的 Registry,并拥有大量的高质量的官方镜像。注册服务器的地址(镜像源)可以在 /etc/docker/daemon.json 文件中查看与修改。

    4. 镜像、容器、仓库,三者之间的联系

    从图中可以看到,镜像是容器的基石,容器是由镜像创建的。一个镜像可以创建多个容器,容器是镜像运行的实体。仓库就非常好理解了,就是用来存放和分发镜像的。

    本文源自:拉勾教育课程:由浅入深吃透 Docker,讲师:郭少 前 360 高级容器技术专家

    参考文章:K8S|Docker的基本概念(镜像,容器,仓库)

  • 相关阅读:
    ReactNative 分享解决listView的一个郁闷BUG
    SDWebImage 图片下载缓存框架 常用方法及原理
    巧谈GCD
    Core Bluetooth下实现两个设备进行互联
    iOS开发Delegate,Notification,Block使用心得
    iOS开发之性能优化
    iOS开发之git学习
    iOS开发之自定义输入框(利用UITextField及UITextView)
    iOS开发之网络请求(基于AFNetworking的再封装)
    iOS开发之设置界面的抽取
  • 原文地址:https://www.cnblogs.com/FengZeng666/p/14160496.html
Copyright © 2020-2023  润新知