Docker基础修炼2--Docker镜像原理及常用命令

时间:2022-05-26 23:15:24

通过前文的讲解对Docker有了基本认识之后,我们开始进入实战操作,本文先演示Docker三要素之镜像原理和相关命令。

本文的演示环境仍然沿用上一篇文章在本地Centos7中安装的环境,如果你本地没有搭建Docker环境,也可以直接使用前文提到的Docker练习场(play-with-docker)在线进行练习。

在正式开始之前,我们先回顾下几个常用的命令,尤其是Docker帮助命令是掌握众多命令的万能钥匙,一定要多用。

一、Docker帮助命令

1.1 查看Docker版本命令

查看Doceker版本信息可以使用docker version命令或-v参数(--version),其中-v参数是--version的缩写。

docker -v

[root@docker ~]# docker -v
Docker version 19.03.6, build 369ce74a3c

docker --version

[root@docker ~]# docker --version
Docker version 19.03.6, build 369ce74a3c

docker version

[root@docker ~]# docker version
Client: Docker Engine - Community
Version: 19.03.6
API version: 1.40
Go version: go1.12.16
Git commit: 369ce74a3c
Built: Thu Feb 13 01:29:29 2020
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.6
API version: 1.40 (minimum version 1.12)
Go version: go1.12.16
Git commit: 369ce74a3c
Built: Thu Feb 13 01:28:07 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.2.10
GitCommit: b34a5c8af56e510852c35414db4c1f4fa6172339
runc:
Version: 1.0.0-rc8+dev
GitCommit: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
docker-init:
Version: 0.18.0
GitCommit: fec3683

1.2 查看Docker详细信息命令

我们还可以使用docker info命令查看docker相关的更广泛的操作系统范围内的信息

docker info

[root@docker ~]# docker info
Client:
Debug Mode: false
Server:
Containers: 1
Running: 0
Paused: 0
Stopped: 1
Images: 1
Server Version: 19.03.6
Storage Driver: devicemapper
Pool Name: docker-253:1-1912367-pool
...省略部分内容
Docker Root Dir: /var/lib/docker
...省略部分内容
[root@docker ~]#

显示内容太多了,我省略了一部分,其中可以查看容器总数、有多少容器在运行、有多少容器已经停止、镜像总数以及内存、容量等信息。

1.3 万能帮助命令

命令何其多,不一定能全记住,也没必要全记住。就像可以在Linux下可以通过man命令查看各个命令的用法一样,Docker也提供了帮助命令。

docker --help

[root@docker ~]# docker --help
Usage: docker [OPTIONS] COMMAND
...省略

里边包含了每个命令的各种详细用法,根据需要查询即可。

二、Docker镜像原理

前文已提到Docker三要素:镜像、容器、仓库。镜像是最基础的,就像我们在做面向对象编程开发时写的实体类,只有有了类才能生成实例对象。接下来我们分析下镜像的原理和特点。

2.1 Docker镜像原理及UnionFS

2.1.1 Docker镜像是什么

我们搞技术不像搞数据公式,要明确给事物一个非常严苛的名称。对于一门技术的命名或定义,个人认为只要理解就好,至于名称你可以任意给他取。

我给Docker的定义是一个轻量级可运行的独立软件包,只不过这个软件包除了包含我们自己开发的业务代码软件之外,还包含了运行该软件所需的所有环境,也就是他包含了代码、运行时环境、库、配置文件等等软件运行所需的所有内容。

2.1.2 Docker镜像原理

Docker镜像本质就是一个文件,底层依赖于联合文件系统(UnionFS)

  • 什么是UnionFS?

UnionFS是一种分层、轻量级、高性能的文件系统,支持对文件系统的修改作为一次提交来层层叠加。这很类似于我们生活中的千层饼或鸡蛋,由蛋黄、蛋清、蛋壳一层一层的最终构成了一个鸡蛋。

  • UnionFS的特性

联合文件系统最大特点就是分层联合加载

在加载时可以一次同时加载多层文件系统,通过联合加载把各层文件系统叠加起来,从外部看只能看到一个文件系统,最终的文件系统保护所有底层的文件和目录。

  • Docker镜像分层结构及加载原理

由于docker镜像底层采用联合文件系统,自然而然docker镜像也是分层的。docker采用的联合文件系统为aufs (advanced multi layered unification filesystem),是一种可堆叠的联合文件系统。

按照docker官网的说法,docker文件系统分为两层:bootfs和rootfs

bootfs层

Docker基础修炼2--Docker镜像原理及常用命令

bootfs包含了bootloader和linux内核,用户是不能对这层作任何修改的,在内核启动之后,bootfs实际上会unmount掉。

rootfs则包含了一般系统上的常见目录结构,类似于/dev, /proc, /bin等等以及一些基本的文件和命令。

rootfs层

对于linux上不同版本的问题,docker可以同时运行多个rootfs。

Docker基础修炼2--Docker镜像原理及常用命令

Docker的文件系统是分层的,它的rootfs在mount之后会转为只读模式, Docker在它上面添加一个新的文件系统,来达成它的只读。由于共享一个内核,这也是为什么docker比虚拟机消耗资源更少的根本原因

images层

从下图中,我们能看到多个只读的文件系统,Docker中把他们称为层。image是只读的,container部分则是可写的。如果用户想要修改底层只读层上的文件,这个文件就会被先拷贝到上层,修改后驻留在上层,并屏蔽原有的下层文件。

Docker基础修炼2--Docker镜像原理及常用命令

container层

最后一部分是容器(container), 容器是可读写的。

在系统启动时,Docker会首先一层一层的加载image,直到最先面的base image,这些image都是只读的。最后,在最上层添加可读写的一个容器, 这里存放着诸如unique id,网络配置之类的信息。

Docker基础修炼2--Docker镜像原理及常用命令

既然是可读写的,就会有状态。容器共有两种状态:running 和 exited。用户也可以用docker commit 命令将一个容器压制为image,供后续使用。

  • docker镜像为什么要分层

docker镜像采用基于联合文件系统的分层结构主要是为了共享公用文件,除了节约存储空间,还能实现对文件的高效管理。

镜像可以通过分层来进行继承,基于父镜像可以制作各种具体的应用镜像。如果你有面向对象编程语言的开发经验,这就很好理解,它类似于继承与多态,子类可以继承父类功能并能派上新功能。

关于镜像的分层,在使用后续的docker pull命令时可以很好的进行验证。比如使用docker pull命令下载一个mysql镜像,将会看到是一层一层的下载。另外如果不同镜像包含相同的公用部分(层),假设之前已经下载过包含了公用层的镜像的话,再下载包含公用层的其他镜像,会提示这些公用层已经存在于本地了,这个镜像的下载过程就不在去下载公用层,整个过程就会明显快很多。

2.2 Docker镜像的特点

由于docekr镜像采用了联合文件系统,因此也继承了联合文件系统过的特点。

总结起来就是:分层、只读、可继承,如前所述,镜像是一层一层叠加起来,并且是只读的,子镜像可以继承父镜像并派生出新的镜像。

镜像是只读的,但是当我们基于镜像创建容器是希望能进行读写操作,那是怎么做到的呢?

当一个docker容器启动时,一个新的可写层被加载到镜像顶部,这一层称为“容器层”,容器层下边是“镜像层”,我们读写操作都是在容器层进行,我们的程序也是运行在这一层的。

2.3 Docker架构图

我们之前已经执行了一些命令,这些命令的执行流程是怎么样的呢?先要搞清楚Docker的架构以及命令执行过程,我们才能更好的使用docker。

Docker架构图

Docker基础修炼2--Docker镜像原理及常用命令

从官方的架构图中可以看到主要包含几个部分:客户端Client、Docker daemon、仓库Registry

我们输入命令的工具称之为客户端Client,当我们在客户端输入命令时,命令会发送到docker所在主机的daemon进程,由该进程执行命令。当执行的是创建容器的命令时,如果对应的镜像不存在于本地,那么daemon会向远程docker仓库请求下载镜像,等镜像下载到本地后在创建容器。

下图包含了docker的镜像、容器、仓库相关的命令,接下来主要演示与镜像相关的命令,其他的命令将在后续的文章中继续演示。

docker命令图

Docker基础修炼2--Docker镜像原理及常用命令

ps:这部分内容比较抽象,可以先大概了解,经过后边的学习之后再返回来看就会有更深刻的理解。

三、Docker镜像常用命令

3.1 查看本地镜像

命令格式:

docker images [选项] [仓库:版本]

参数:

参数 作用
-a 即--all,查看所有本地镜像(默认情况不显示中间镜像)
-q 只显示镜像id
--digests 显示摘要
--no-trunc 不截断输出(默认显示的镜像id为12位)

可以使用docker images --help或man docker images查看具体的用法和各项参数的意义,并且支持tab补全命令。

案例:

[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 14 months ago 1.84kB
[root@docker ~]# docker images -q
fce289e99eb9

输出标题中各项的含义:

REPOSITORY:镜像名称,用于标识镜像

TAG:版本号

IMAGE ID :镜像ID,与镜像名称一样,可以唯一标识一个镜像

CREATED :镜像创建日期

SIZE:镜像大小

3.2 查看远程仓库中的镜像

命令格式:

docker search [选项] 镜像名称

参数:

参数 作用
-f或--filter 根据指定条件过滤
--limit 限制最多返回的条数
--no-trunc 不截断输出

案例:

(1)查询点赞数大于等于5000的mysql镜像

[root@docker ~]# docker search -f=stars=5000 mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9164 [OK]
[root@docker ~]#

你可以先自行执行docker search命令,什么参数都不加,然后对比一下结果。本例中是在Docker Hub上查找stars星级数大于等于5千的mysql的镜像。

(2)只查看官网的mysql镜像

[root@docker ~]#  docker search -f=is-official=true mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9164 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3263 [OK]
[root@docker ~]#

3.3 下载镜像

命令格式:

docker pull [选项] 镜像名称[:TAG]

案例:

下载刚查出的mysql官方镜像

[root@docker ~]# docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
6d28e14ab8c8: Pull complete
dda15103a86a: Pull complete
55971d75ab8c: Pull complete
f1d4ea32020b: Pull complete
61420072af91: Pull complete
05c10e6ccca5: Pull complete
7e0306b13322: Pull complete
900b113c001e: Pull complete
06cd07c30bf4: Pull complete
df0d65aee5aa: Pull complete
53eeb6e0335c: Pull complete
6cf8f9563e97: Pull complete
Digest: sha256:f91e704ffa9f19b9a267d9321550a0772a1b64902226d739d3527fd6edbe3dfe
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest c8ad2be69a22 47 hours ago 465MB
[root@docker ~]#

另外这里也可以很清楚的看到,是一层一层的进行下载,这就是前面讲到的镜像分层结构。

默认会去Docker Hub仓库进行下载,我们也可以直接登录Docker Hub查看mysql镜像

https://hub.docker.com/_/mysql?tab=tags 我们可以看到有很多不同的版本,使用时按需下载即可。

特别注意,如果没指定tab版本号,默认是latest版本,也就是最新版。所以在生产环境中最好是明确指定一个版本。

默认情况下去docker hub下载镜像比较慢,由于是在国外所以不太稳定,自己可以配置为国内的镜像仓库,如阿里云仓库。

下载完成后,就可以在本地通过docker images命令查到该镜像

3.4 删除本地镜像

命令格式:

docker rmi [选项] 镜像名或id

参数:

参数 作用
-f 即为--force,强制删除镜像。当要删除的镜像有容器存在时,只能强制删除

案例:

(1)删除第一篇文章中下载的hello-world镜像

由于当时我们已经用该镜像创建了一个容器,即使此容器没有运行,在删除时也用-f参数强制删除。

[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 14 months ago 1.84kB
[root@docker ~]# docker rmi hello-world
Error response from daemon: conflict: unable to remove repository reference "hello-world" (must force) - container cf1753d712db is using its referenced image fce289e99eb9
[root@docker ~]# docker rmi -f hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:fc6a51919cfeb2e6763f62b6d9e8815acbf7cd2e476ea353743570610737b752
Deleted: sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
[root@docker ~]#

另外如果同一个镜像有不同版本,需要添加tag参数来删除指定镜像。如果要删除多个镜像,只需要在命令末尾以空格分隔多个容器即可。

(2)删除全部镜像

[root@docker ~]# docker  rmi -f $(docker images -qa)

可以结合linux命令获取所有镜像id,然后再全部删除。

3.5 将容器打包为镜像

命令:docker commit

可以通过该命令将当前运行的容器打包为镜像。后文会讲到构建镜像有两种方式:一种是通过容器commit;另外一种是通过编写DocekerFile编辑镜像。

什么场景需要将容器打包成镜像呢?

比如我们想扩展某个镜像的功能,我们可以把镜像运行为一个容器,然后在里边实现各种定制化需求(比如安装特定的软件),然后在重新commit提交为一个镜像,以后就基于新镜像去创建容器。

ps:在后边演示完容器相关命令后,在单独演示commit和push命令。如果你有git或svn的使用经验,这2个pull和push命令很好理解,都是和仓库进行交互。

3.6 将容器上传到远程仓库

命令:docker push

本地通过docker commit打包的镜像,可以通过docker push上传到远程Docker Hub仓库。这个命令与docker pull是相对的,pull则是从远程仓库下载到本地。

要上传到远程仓库,还需要在Docker Hub上注册相应的账号,这在后续的文章中会单独进行演示。

至此,我们大概弄明白了Docker的体系结构以及Docker镜像原理,并演示了大部分Docker镜像相关的命令,如果看完还有些迷茫,先不着急,有个大概的印象即可,等看完后续文章中容器的操作之后就会有更深刻的认识。

下一篇 文章我们将讲解Docker容器相关知识,敬请期待。

如果觉得文章不错,关注一波不迷路!

Docker基础修炼2--Docker镜像原理及常用命令的更多相关文章

  1. Android ADB原理及常用命令

    Android调试桥(ADB, Android Debug Bridge)是一个Android命令行工具,包含在SDK 平台工具包中,adb可以用于连接Android设备,或者模拟器,实现对设备的控制 ...

  2. Docker基础修炼1--Docker简介及快速入门体验

    本文作为Docker基础系列第一篇文章,将详细阐述和分析三个问题:Docker是什么?为什么要用Docker?如何快速掌握Docker技术? 本系列文章中Docker的用法演示是基于CentOS7进行 ...

  3. [转]Docker基础-使用Dockerfile创建镜像

    本文转自:https://www.cnblogs.com/jie-fang/p/7927643.html 1.基本结构 Dockerfile由一行行命令语句组成,并支持以#开头的注释行.例如: # T ...

  4. Docker基础-使用Dockerfile创建镜像

    1.基本结构 Dockerfile由一行行命令语句组成,并支持以#开头的注释行.例如: # This dockerfile uses the ubuntu image # VERSION 2 - ED ...

  5. docker基础属性简介包含镜像 容器 registry服务等概念及关系

    Docker 镜像 我们都知道,操作系统分为内核和用户空间.对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持.而 Docker 镜像(Image),就相当于是一个 r ...

  6. Docker03 Docker基础知识、Docker实战

    1 Docker基础知识 1.1 什么是Docker Docker是一个可以装应用的容器,就像杯子可以装水.书包可以装书一样:docker官网 Docker是Docker公司开发的,并开源到GitHu ...

  7. docker(三) 镜像和容器常用命令

    一.镜像操作 1.搜索镜像 可以直接在Docker Hub 直接搜索镜像,当然也可以使用命令来搜索. docker search 名称 docker search tomcat 2.拉取镜像 dock ...

  8. Docker从入门到精通(四)——常用命令

    话不多说,本篇文章给大家介绍 docker 的常用命令,基本上会覆盖我们日常使用的命令. 1.万能帮助命令 docker 命令 --help 假设你想用某个命令,但是又不知道该命令的一些参数怎么用,这 ...

  9. Git 工作原理以及常用命令操作

    GIT工作原理 要了解GIT工作原理,先了解GIT的这几块区域: 工作区域划分 工作区:指的是本地工作空间,如果刚拉取下来的代码,没有修改的内容,这块区域是空白的 (modified-已修改状态) 暂 ...

随机推荐

  1. 【The Expendables】团队博客目录

    站立式会议: •[alpha版本]第一次站立式会议  •[beta版本]冲刺计划                •[beta版本]冲刺总结 •[alpha版本]第二次站立式会议  •[beta版本]第 ...

  2. [原创]cin、cin.get()、cin.getline()、getline()、gets()、getchar()的区别

    这几个输入函数经常搞不清具体特点和用法,这里稍作总结 一.cin>> 1.最基本用法,输入一个变量值 2.输入字符串,遇“空格”.“TAB”.“回车”结束,比如输入“hello world ...

  3. chcon可实现对文件的SEAndroid安全标签的修改

    chcon可实现对文件的SEAndroid安全标签的修改 参考使用如下: chcon -u u system/app/ chcon -r object_r system/app/ chcon -t s ...

  4. WPF组件开发之组件的基类

    之前在网上看到很多关于组件开发的资料,但真正可以用到框架内的却很少.今天贴出自己做的组件,并适合大部分框架的代码. 组件开发需要先做出组件的基类,然后由其他的各类组件去继承这个基类,下面是组件基类的代 ...

  5. 关于auto和decltype

    auto会忽略顶层const,保留底层const ; const int* const p = &i; auto p2 = p; //p2是const int*,不是const int* co ...

  6. MATLAB垂直搜索图片中的白段

    function [ top, bottom, middle, len ] = classify_by_vertical_white_belt( img ) % 垂直搜索图片中的白段, 记录具体信息. ...

  7. 初探linux子系统集之i2c子系统(二)

    大概也是前年了,一直没有把那个i2c的子系统讲解完,这里偷个懒,把以前整理的i2c相关的知识再梳理一下,做个了结,然后再去学习timer子系统. 先看下i2c在内核中的代码分布: obj-$(CONF ...

  8. 汇编语言--微机CPU的指令系统(五)(标志位操作指令)

    (2)标志位操作指令 标志位操作指令是一组对标志位置位.复位.保存和恢复等操作的指令. 1.进位CF操作指令 Ø 清进位指令CLC(Clear Carry Flag):CF←0 Ø 置进位指令STC( ...

  9. saltstack的封装和内网使用

    0.客户端使用 linux:把linux的ragent文件夹拷贝到内网linux /opt目录下,运行初始化脚本 salt服务端:# @Master:"/opt/ragent/python/ ...

  10. Linux下单独编译安装PHP扩展包

    首先进入PHP源码目录,比如这个: root@vultr:~/php-/ext/soap# 运行下PHP目录下的phpize,接着就可以和普通代码一样,配置,编译,安装了(注意:有些库可能可以配置参数 ...