Docker是Go语言开发实现的容器。2013年发布至今,倍受推崇。相关文档、学习资料非常详细。近日公司docker项目要加快,得重新学习一下。博客以笔记。

1容器诞生背景及优势

(1)软件开发和运维中,环境布署、配置,不胜其烦。举例说明,Python开发和布署都必须配置Python类库;运维过程中,有时测试环境能通过,并且到线上却报错,究其缘由,是环境不一致。

传统运维过程中,线上有十台机器linux基础教程,每降低一台都须要重新布署一次,简直就是“体力劳动”。

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

-资源占用多虚机启动须要占用几百M的显存。

-冗余步骤多系统级别的操作步骤,常常难以跳过,例如用户登入。

-启动慢,常常几分钟启动操作系统须要多久,启动虚拟机就须要多久。

(3)容器优势

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

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

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

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

传统虚拟化示意图:

docker rm images_docker rm images_docker rm images

docker虚拟化示意图:

docker rm images_docker rm images_docker rm images

2Docker基本概念

(1)镜像image

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

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

image文件是通用的,一台机器的image文件拷贝到另一台机器,照样可以使用。通常来说,为了节约时间,我们应当尽量使用他人制做好的image文件,而不是自己制做。虽然要订制,也应当基于他人的image文件进行加工,而不是从零开始制做。

为了便捷共享linux系统镜像下载,image文件制做完成后,可以上传到网上的库房。Docker的官方库房DockerHub是最重要、最常用的image库房。据悉,转让自己制做的image文件也是可以的。

(2)容器Container

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

docker rm images_docker rm images_docker rm images

(3)库房Repository

镜像建立完成后,可以很容易的在当前宿主机上运行,然而,假若须要在其它服务器上使用这个镜像,我们就须要一个集中的储存、分发镜像的服务,DockerRegistry就是这样的服务。

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

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

回到底部

3安装docker

CentOS为例:

DockerCE支持64位版本CentOS7,但是要求内核版本不高于3.10。CentOS7满足最低内核的要求,但因为内核版本比较低,部份功能(如overlay2储存层驱动)难以使用,而且部份功能可能不太稳定。

docker rm images_docker rm images_docker rm images

(6)创建docker用户组

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

为此,更好地做法是将须要使用docker的用户加入docker用户组。

docker rm images_docker rm images_docker rm images

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

docker rm images_docker rm images_docker rm images

4获取镜像

从Docker镜像库房获取镜像的命令是dockerpull。其命令格式为:

dockerpull[选项][DockerRegistry地址[:端标语]/]库房名[:标签]

具体的选项可以通过dockerpull--help命令看见,这儿我们说一下镜像名称的格式。

比如,从镜像库房获取nginx:

docker rm images_docker rm images_docker rm images

1)原告命令中没有指定Docker镜像库房地址,因而将会从DockerHub获取镜像。

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

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

docker rm images_docker rm images_docker rm images

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

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

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

docker rm images_docker rm images_docker rm images

以ubuntu镜像为例,运行镜像

dockerrun-it--rmubuntu:16.04bash

(1)dockerrun就是运行容器的命令,具体格式可在前面论述。

(2)-it:这是两个参数,一个是-i:交互式操作,一个是-t终端。我们这儿准备步入bash执行一些命令并查看返回结果,因而我们须要交互式终端。

(3)--rm:这个参数是说容器退出后骤然将其删掉。默认情况下,为了排障需求,退出的容器并不会立刻删掉,除非自动dockerrm。我们这儿只是随意执行个命令,瞧瞧结果,不须要排障和保留结果,因而使用--rm可以防止浪费空间。

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

(5)bash:置于镜像名后的是命令,这儿我们希望有个交互式Shelldocker rm images,因而用的是bash。

运行再审命令后会步入ubuntu镜像示例的的shell界面,我们查看系统,结果如下:

+ViewCode

exit退出当前容器。

5列举镜像

列举镜像的命令:

dockerimagels

示例:

[@sjs_123_183~]#dockerimagels

REPOSITORYTAGIMAGEIDCREATEDSIZE

nginxlatestc5c4e8fa2cf76daysago109MB

ubuntu16.04f975c50357484weeksago112MB

hello-worldlatestf2a91732366c4monthsago1.85kB

每列的涵义:

REPOSITORY:库房名

docker rm images_docker rm images_docker rm images

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

IMAGEID:镜像ID,是镜像的惟一标示

CREATED:创建时间

SIZE:所占用的空间

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

例如,ubuntu:16.04镜像大小,在这儿是112MB,而且在DockerHub显示的却是43MB。这是由于:

(1)DockerHub中显示的容积是压缩后的容积。减少网路传输流量。

(2)dockerimagels显示的是镜像下载到本地后,展开的大小,确切说,是展开后的各层所占空间的总和,由于镜像到本地后,查看空间的时侯,更关心的是本地c盘空间占用的大小。

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

因为Docker使用UnionFS,相同的层只须要保存一份即可,因而实际镜像硬碟占用空间很可能要比这个列表镜像大小的总和要小的多。

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

命令:

dockersystemdf

示例:

+ViewCode

7虚悬镜像

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

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

不仅dockerpull可能造成这些情况,dockerbuild也同样可以造成这些现象。因为新旧镜像同名,旧镜像名称被取消,因而出现库房名、标签均为的镜像。

虚悬镜像示例:

00285df0df875daysago342MB

显示虚悬镜像命令:

dockerimagels-fdangling=true

删掉虚悬镜像:

dockerimageprune

8中间层镜像

为了加速镜像建立、重复借助资源,Docker会借助中间层镜像。所以在使用一段时间后,可能会听到一些依赖的中间层镜像。默认的dockerimagels列表中只会显示顶楼镜像,假如希望显示包括中间层镜像在内的所有镜像的话,须要加-a参数。

dockerimagels-a

这样会看见好多无标签的镜像,与之前的虚悬镜像不同,这种无标签的镜像好多都是中间层镜像,是其它镜像所依赖的镜像。这种无标签镜像不应当删掉,否则会造成下层镜像由于依赖遗失而出错。

实际上,这种镜像也没必要删掉,由于之前说过,相同的层只会存一遍,而这种镜像是别的镜像的依赖,因而并不会由于它们被列下来而多存了一份,无论怎样你也会须要它们。只要删掉这些依赖它们的镜像后,这种依赖的中间层镜像也会被连带删掉。

9按需列举镜像

(1)列举部份镜像

命令:

dockerimagelsredis按库房名过滤

dockerimagelsredis:3.2按库房名和标签过滤

dockerimagels-fsince=redis:3.2.11列举redis:3.2.11然后完善的镜像

dockerimagels-fbefore=redis:3.2列举redis:3.2之前构建的镜像

示例:

+ViewCode

(2)自定义输出格式

dockerimages--filter”条件”按条件过滤

示例:

+ViewCode

(3)使用go语言模板句型

dockerimages--format”{{.ID}}{{.Repository}}”#按ID库房名格式列举

dockerimages--format”table{{.ID}}t{{.Repository}}t{{.Tag}}”#按ID库房标签的格式列举

示例:

+ViewCode

常用go语言模板:

.ID#镜像ID

docker rm images_docker rm images_docker rm images

.Repository#镜像库房名

.Tag#镜像标签

.Digest#镜像摘要

.CreatedSince#镜像创建到现今的历时

.CreatedAt#镜像创建时间

.Size#镜像大小

10删掉镜像

10.1单台删掉

删掉本地镜像的命令是dockerimagerm,用法如下:

dockerimagerm[选项][…]

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

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

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

注意:删掉行为分为两类,一类是Untagged,另一类是Deleted。

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

因而当我们使用前面命令删掉镜像的时侯,实际上是在要求删掉某个标签的镜像。

(1)所以首先须要做的是将满足我们要求的所有镜像标签都取消,这就是我们看见的Untagged的信息。由于一个镜像可以对应多个标签,因而当我们删掉了所指定的标签后,可能还有别的标签指向了这个镜像,倘若是这些情况,这么Delete行为就不会发生。所以并非所有的dockerrmi就会形成删掉镜像的行为docker rm images,有可能仅仅是取消了某个标签而已。

(2)当该镜像所有的标签都被取消了,该镜像很可能会丧失了存在的意义,因而会触发删掉行为。镜像是多层储存结构,因而在删掉的时侯也是从下层向基础层方向依次进行判别删掉。镜像的多层结构让镜像复用变动十分容易,因而很有可能某个其它镜像正依赖于当前镜像的某一层。这种情况,仍然不会触发删掉该层的行为。直至没有任何层依赖当前层时,就会真实的删掉当前层。这就是为何,有时侯会奇怪,为何明明没有别的标签指向这个镜像,而且它还是存在的诱因,也是为何有时侯会发觉所删掉的层数和自己dockerpull听到的层数不一样的源。

(3)不仅镜像依赖以外,还须要注意的是容器对镜像的依赖。假如有用这个镜像启动的容器存在(虽然容器没有运行),这么同样不可以删掉这个镜像。之前讲过,容器是以镜像为基础,再加一层容器储存层,组成这样的多层储存结构去运行的。因而该镜像假如被这个容器所依赖的,那么删掉必然会造成故障。倘若这种容器是不须要的,应当先将它们删掉,之后再来删掉镜像。

docker rm images_docker rm images_docker rm images

10.2批量删掉

用dockerimagels命令来配合批量删掉本地镜像。

dockerimagerm$(dockerimagels-qredis)#删掉所有库房名为redis的镜像

dockerimagerm$(dockerimagels-q-fbefore=mongo:3.2)#删掉所有在mongo:3.2之前的镜像

示例:

+ViewCode

Tagged:
Author

这篇优质的内容由TA贡献而来

刘遄

《Linux就该这么学》书籍作者,RHCA认证架构师,教育学(计算机专业硕士)。

发表回复