是Go语言开发实现的容器。2013年发布至今,备受推崇。相关文档、学习资料十分详尽。近期公司项目要推进,得重新学习一下。博客以笔记。

1 容器诞生背景及优势

(1)软件开发和运维中,环境部署、配置,不胜其烦。举例说明,开发和部署都必须配置解释器;运维过程中,有时测试环境能通过,但是到线上却报错,究其原因,是环境不一致。

传统运维过程中,线上有十台机器,每增加一台都需要重新部署一次,简直就是“体力劳动”。

(2)虚拟机在一定程度可以解决这些问题,但是存在几个缺点:

– 资源占用多 虚机启动需要占用几百M的内存。

– 冗余步骤多 系统级别的操作步骤,往往无法跳过,比如用户登录。

– 启动慢,往往几分钟 启动操作系统需要多久,启动虚拟机就需要多久。

(3)容器优势

容器不是模拟一个操作系统,而是对进程进行隔离。属于进程级别。

– 启动快, 相当于启动本机底层系统的一个进程,而不是虚拟机内部的进程,速度快很多。

– 占用资源少,容器只占用需要的资源,不占用那些没有用到的资源;多个容器可以共享资源,虚拟机是独享资源。

– 体积小,容器只要包含用到的组件即可,而虚拟机是整个操作系统的打包,所以容器文件比虚拟机文件要小很多。

传统虚拟化示意图:

虚拟化示意图:

2 基本概念

(1)镜像image

把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 容器。image 文件可以看作是容器的模板。 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。

image 是二进制文件。实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成。举例来说,你可以在 的 image 基础上,往里面加入 服务器,形成你的 image。

image 文件是通用的,一台机器的 image 文件拷贝到另一台机器,照样可以使用。一般来说,为了节省时间,我们应该尽量使用别人制作好的 image 文件,而不是自己制作。即使要定制,也应该基于别人的 image 文件进行加工,而不是从零开始制作。

为了方便共享,image 文件制作完成后,可以上传到网上的仓库。 的官方仓库 Hub 是最重要、最常用的 image 仓库。此外,出售自己制作的 image 文件也是可以的。

(2)容器

image 文件生成的容器实例,本身也是一个文件,称为容器文件。也就是说,一旦容器生成,就会同时存在两个文件: image 文件和容器文件。而且关闭容器并不会删除容器文件,只是容器停止运行而已。

(3)仓库

镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务, 就是这样的服务。

一个 中可以包含多个仓库();每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。

通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 : 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 作为默认标签。

回到顶部

3 安装

以为例:

CE 支持 64 位版本 7,并且要求内核版本不低于 3.10。 7 满足最低内核的要求,但由于内核版本比较低,部分功能(如存储层驱动)无法使用,并且部分功能可能不太稳定。

(6)创建用户组

默认情况下, 命令会使用 Unix 与 引擎通讯。而只有 root 用户和 组的用户才可以访问 引擎的 Unix 。出于安全考虑,一般 Linux 系统上不会直接使用 root 用户。

因此,更好地做法是将需要使用 的用户加入 用户组。

注意:本次使用的是root用户。

4 获取镜像

从 镜像仓库获取镜像的命令是 pull。其命令格式为:

pull [选项] [ 地址[:端口号]/]仓库名[:标签]

具体的选项可以通过 pull –help命令看到,这里我们说一下镜像名称的格式。

例如,从镜像仓库获取nginx:

1)上诉命令中没有指定 镜像仓库地址,因此将会从 Hub 获取镜像。

(2)而镜像名称是 nginx,因此将会获取官方镜像 /nginx 仓库中标签为 的镜像。

(3)从下载过程中可以看到我们之前提及的分层存储的概念,镜像是由多层存储所构成。下载也是一层层的去下载,并非单一文件。

下载过程中给出了每一层的 ID 的前 12 位。并且下载结束后,给出该镜像完整的 的摘要,以确保下载一致性。

(4)官方镜像是一直在维护,你所看到的层 ID 以及 的摘要可能和此处不一样。

我们再获取一个官方的镜像看看:

以镜像为例,运行镜像

run -it –rm :16.04 bash

(1) run 就是运行容器的命令,具体格式可在后面阐述。

(2)-it:这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。

(3)–rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 rm。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 –rm 可以避免浪费空间。

(4):16.04:这是指用 :16.04 镜像为基础来启动容器。

(5)bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 bash。

运行上诉命令后会进入镜像示例的的shell界面,我们查看系统,结果如下:

+ View Code

exit退出当前容器。

5 列出镜像

列出镜像的命令:

image ls

示例:

[@ ~]# image ls

TAG IMAGE ID SIZE

nginx 6 days ago 109MB

16.04 4 weeks ago 112MB

hello-world 4 ago 1.85kB

每列的含义:

:仓库名

TAG:标签, 一个镜像可以对应多个标签

IMAGE ID:镜像 ID,是镜像的唯一标识

:创建时间

SIZE:所占用的空间

注意:此处看到所占用空间与 Hub 上看到的镜像大小不同。

比如,:16.04 镜像大小,在这里是 112 MB,但是在 Hub 显示的却是 43 MB。这是因为:

(1) Hub 中显示的体积是压缩后的体积。减小网络传输流量。

(2) image ls 显示的是镜像下载到本地后,展开的大小,准确说,是展开后的各层所占空间的总和,因为镜像到本地后,查看空间的时候,更关心的是本地磁盘空间占用的大小。

(3) image ls 列表中的镜像体积总和并非是所有镜像实际硬盘消耗。由于 镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层。

由于 使用 Union FS,相同的层只需要保存一份即可,因此实际镜像硬盘占用空间很可能要比这个列表镜像大小的总和要小的多。

6 查看镜像、容器、数据卷所占用的空间

命令:

df

示例:

+ View Code

7 虚悬镜像

仓库名和标签均为 ,这类无标签、无仓库名镜像被称 虚悬镜像( image) 。

镜像原本是有镜像名和标签的,比如原来为 mongo:3.2,随着官方镜像维护,发布了新版本后,重新 pull mongo:3.2 时,mongo:3.2 这个镜像名被转移到了新下载的镜像身上,而旧的镜像上的这个名称则被取消,从而成为了 。

除了 pull 可能导致这种情况, build 也同样可以导致这种现象。由于新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为 的镜像。

虚悬镜像示例:

5 days ago 342 MB

显示虚悬镜像命令:

image ls -f =true

删除虚悬镜像:

image prune

8 中间层镜像

为了加速镜像构建、重复利用资源, 会利用 中间层镜像。所以在使用一段时间后,可能会看到一些依赖的中间层镜像。默认的 image ls 列表中只会显示顶层镜像,如果希望显示包括中间层镜像在内的所有镜像的话,需要加 -a 参数。

image ls -a

这样会看到很多无标签的镜像,与之前的虚悬镜像不同,这些无标签的镜像很多都是中间层镜像,是其它镜像所依赖的镜像。这些无标签镜像不应该删除,否则会导致上层镜像因为依赖丢失而出错。

实际上,这些镜像也没必要删除,因为之前说过,相同的层只会存一遍,而这些镜像是别的镜像的依赖,因此并不会因为它们被列出来而多存了一份,无论如何你也会需要它们。只要删除那些依赖它们的镜像后,这些依赖的中间层镜像也会被连带删除。

9 按需列出镜像

(1)列出部分镜像

命令:

image ls redis 按仓库名过滤

image ls redis:3.2 按仓库名和标签过滤

image ls -f since=redis:3.2.11 列出redis:3.2.11之后建立的镜像

image ls -f =redis:3.2 列出redis:3.2之前建立的镜像

示例:

+ View Code

(2)自定义输出格式

— “条件” 按条件过滤

示例:

+ View Code

(3)使用go语言模板语法

— “{{.ID}} {{.}}” # 按 ID 仓库名格式列出

— “table {{.ID}}t{{.}}t{{.Tag}}” # 按ID 仓库 标签的格式列出

示例:

+ View Code

常用go语言模板:

.ID # 镜像ID

. # 镜像仓库名

.Tag # 镜像标签

. # 镜像摘要

. # 镜像创建到现在的耗时

. # 镜像创建时间

.Size # 镜像大小

10 删除镜像

10.1 单台删除

删除本地镜像的命令是 image rm,用法如下:

image rm [选项] [ …]

(1) 可以是 镜像短 ID、镜像长 ID、镜像名 或者 镜像摘要。

(2)也可以使用镜像名,即 : 删除镜像。

(3)更精确的是使用 镜像摘要 删除镜像。

注意:删除行为分为两类,一类是 ,另一类是 。

镜像的唯一标识是其 ID 和摘要,而一个镜像可以有多个标签。

因此当我们使用上面命令删除镜像的时候,实际上是在要求删除某个标签的镜像。

(1)所以首先需要做的是将满足我们要求的所有镜像标签都取消,这就是我们看到的 的信息。因为一个镜像可以对应多个标签,因此当我们删除了所指定的标签后,可能还有别的标签指向了这个镜像,如果是这种情况,那么 行为就不会发生。所以并非所有的 rmi 都会产生删除镜像的行为,有可能仅仅是取消了某个标签而已。

(2)当该镜像所有的标签都被取消了,该镜像很可能会失去了存在的意义,因此会触发删除行为。镜像是多层存储结构,因此在删除的时候也是从上层向基础层方向依次进行判断删除。镜像的多层结构让镜像复用变动非常容易,因此很有可能某个其它镜像正依赖于当前镜像的某一层。这种情况,依旧不会触发删除该层的行为。直到没有任何层依赖当前层时,才会真实的删除当前层。这就是为什么,有时候会奇怪,为什么明明没有别的标签指向这个镜像,但是它还是存在的原因,也是为什么有时候会发现所删除的层数和自己 pull 看到的层数不一样的源。

(3)除了镜像依赖以外,还需要注意的是容器对镜像的依赖。如果有用这个镜像启动的容器存在(即使容器没有运行),那么同样不可以删除这个镜像。之前讲过,容器是以镜像为基础,再加一层容器存储层,组成这样的多层存储结构去运行的。因此该镜像如果被这个容器所依赖的,那么删除必然会导致故障。如果这些容器是不需要的,应该先将它们删除,然后再来删除镜像。

10.2 批量删除

用 image ls 命令来配合批量删除本地镜像。

image rm $( image ls -q redis) # 删除所有仓库名为 redis 的镜像

image rm $( image ls -q -f =mongo:3.2) # 删除所有在 mongo:3.2 之前的镜像

示例:

+ View Code

加入IP合伙人(站长加盟) | 全面包装你的品牌,搭建一个全自动交付的网赚资源独立站 | 晴天实测8个月运营已稳定月入3W+
限时特惠:本站每日持续更新海量内部创业教程,一年会员只需98元,全站资源免费无限制下载点击查看会员权益

站长微信: qtw123cn

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注