通过网盘分享的文件MD文档笔记链接: https://pan.baidu.com/s/1ao2wfyLEdN50YmIqdzfGYQ?pwd5w5z 提取码: 5w5z–来自百度网盘超级会员v6的分享一.镜像基础1.镜像简介镜像是一种轻量级、可执行的独立软件包(也可以说是一个精简的操作系统)镜像中包含应用软件及应用软件的运行环境具体来说镜像包含运行某个软件所需的所有内容(包括代码、库、环境变量和配置文件等),几乎所有应用直接打包为 Docker 镜像后就可以运行镜像中不包含内核,其共享宿主机的内核,镜像中只包含简单的 Shell或没有 Shell2.镜像分层(1).什么是分层docker镜像由一些松耦合的只读镜像层组成Docker Daemon负责堆叠这些镜像层并将它们关联为一个统一的整体(即对外表现出的是一个独立的对象)通过docker pull命令拉取指定的镜像时每个Pull complete结尾的行就代表下载完毕了一个镜像层例如下面的redis:latest 镜像就包含7个镜像层dockerpull redis(2).为什么分层采用这种分层结构的优势很多不会破坏原分层每个分层都是只读的所有对分层的修改都是以新分层的形式出现并不会破坏原分层内容节省空间每个分层只记录变更内容所以有利于节省存储空间等资源共享在不同镜像间实现资源共享即不同镜像对相同下层镜像的复用对于docker pull命令在拉取之前会先获取到其要拉取镜像的所有 ImageID,然后在本地查找是否存在这些分层如果存在则不再进行拉取而是共享本地的该分层,大大节点的存储空间与网络带宽,提升了拉取效率(3).镜像ID所有镜像都是通过一个 64 位十六进制字符串来标识的为简化使用,前12个字符可以组成一个短ID,可以在命令行中使用短ID还是有一定的碰撞机率,所以服务器总是返回长ID(4).镜像层构成每个镜像层由两部分构成,这两部分具有相同的镜像ID镜像文件系统镜像文件系统就是对镜像占有的磁盘空间进行管理的文件系统,拥有该镜像所有镜像层的数据内容镜像 json 文件镜像json 文件则是用于描述镜像的相关属性的集合通过 docker inspect [镜像] 就可以直观看到(5).联合文件系统(UnionFS)UnionFS可以把多个目录内容联合挂载到同一个目录下而目录的物理位置是分开的UnionFS允许只读和可读写目录并存(也就是说可同时删除和增加内容)它支持对文件系统的修改作为一次提交来一层层的叠加UnionFS文件系统是 Docker 镜像的基础镜像可以通过分层来进行继承,基于基础镜像(没有父镜像)可以制作各种具体的应用镜像不同的Linux版本实现unionFS的技术可能不一样查看镜像信息语法dockerinfo比如我的机器上实现技术是overlay23.镜像构成一个 docker 镜像的文件系统由多层只读的镜像层组成每层都完成了特定的功能这些只读镜像层根据其位置与功能的不同可分为两类基础镜像层扩展镜像层3.1.基础镜像层(1).bootfsbootfs主要包含引导加载程序(bootloader)“和内核(kernel)”Linux刚启动时会加载bootfs文件系统,当bootfs加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs同样内核版本的不同的 Linux 发行版其bootfs都是一致的(2).rootfsrootfs在bootfs之上(就是各种不同的操作系统发行版,如Ubuntu、Centos等)包含典型的目录结构/dev/proc/bin/etc/lib/usr/tmp如这张图里的这些文件夹Linux 系统在启动时roofs 首先会被挂载为只读模式,然后在启动完成后被修改为读写模式,随后它们就可以被修改了由于rootfs不包含内核,这就意味着如果你的应用程序需要配置内核参数、加载额外的内核模块,以及跟内核进行直接的交互就需要注意了:这些操作和依赖的对象都是宿主机操作系统的内核,它对于该机器上的所有容器来说是一个全局变量,牵一发而动全身平时我们安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M这是因为对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs 就行了由此可见对于不同的linux发行版bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs3.2.扩展镜像层在基础镜像层之上的镜像层称为扩展镜像层(顾名思义是对基础镜像层功能的扩展)在 Dockerfile 中每条指令都是用于完成某项特定功能的,而每条指令都会生成一个扩展镜像层3.3.容器层一旦镜像运行了起来就形成了容器,而容器就是一个运行中的 Linux 系统,其也是具有文件系统的容器的这个文件系统是在docker 镜像最外层之上增加了一个可读写的容器层,对文件的任何更改都只存在于容器层,因此任何对容器的操作都不会影响到镜像本身修改容器层如果需要修改某个文件系统,会从容器层开始向下一层层的查找该文件直到找到为止,容器层会首先把在镜像层找到的文件copy到容器层,然后再进行修改,任何对于文件的操作都会记录在容器层删除删除文件也只会将存在于容器层中的文件副本删除3.4.LinuxOS 启动过程一个linux系统按启动顺序可以划分为:引导加载程序(bootloader)、内核(kernel)、文件系统、应用程序4.镜像摘要每个镜像都有一个长度为 64 位的 16 进制字符串作为其摘要 digest(1).查看摘要在 docker pull 镜像结束后会给出该拉取的镜像的摘要 digestdockerpull 镜像通过 docker inspect 命令可以查看指定镜像的详细信息,其中就包含该镜像的摘要信息dockerinspect 镜像:版本号通过 docker images --digests 命令也可以查看到镜像的摘要信息dockerimages 镜像--digests(2).摘要是什么摘要(digest)是镜像内容的一个 Hash 值,即所谓的内容散列只要镜像内容发生了变更,其内容散列值就一定会发生改变也就是说一个镜像一旦创建完毕,其 digest 就不会发生改变了(因为镜像是只读的)Docker 默认采用的 Hash 算法是 SHA256(即 Hash 值是一个长度为 256 位的二进制值)但是Docker 使用16进制表示,即变为了长度为 64 位的字符串(3).摘要有何用摘要的主要作用是区分相同repository:tag的不同镜像例如镜像 xxx:2.8 在生产运行过程中发现存在一个 BUG,现对其进行了修复并使用原标签将其 push 回了仓库,那么原镜像被覆盖但生产环境中遗留了大量运行中的修复前镜像的容器,此时通过镜像标签已经无法区分镜像是修复前的还是修复后的了,因为它们的标签是相同的此时通过查看镜像的 digest 就可以区分出修改前后版本,因为内容发生了变化digest 一定会变为了确保再次拉取到的是修复后的镜像,可通过 digest 进行镜像拉取其用法是dockerpullrepositorydigest下面的例子是先查出 redis:7.4.2镜像的 digest,然后将该镜像删除,然后再通过 digest 对其进行拉取不过不方便的是镜像的摘要需要由运维人员在本地进行手工维护(4).分发散列值在 push 或 pull 镜像时都会对镜像进行压缩以减少网络带宽和传输时长,但压缩会改变镜像内容,会导致经过网络传输后镜像内容与其 digest 不相符为了避免该问题,Docker 又为镜像配置了Distribution Hash(分发散列值)在镜像被压缩后立即计算分发散列值,然后使该值随压缩过的镜像一同进行发送在接收方接收后立即计算压缩镜像的分发散列值,再与携带的分发散列值对比,如果相同说明传输没有问题5.镜像仓库分类镜像中心存储着大量的镜像仓库,每个镜像仓库中包含着大量相关镜像根据这些镜像发布者的不同形成了四类不同的镜像仓库5.1.官方镜像仓库Docker 官方镜像仓库(Docker Official Image)该类仓库中的镜像由Docker官方构建发布代码质量较高安全有较完善的文档镜像会及时更新一般常用的系统、工具软件、中间件都有相应的官方镜像仓库例如:Zookeeper、Redis、Nginx 等官方镜像仓库的名称repository一般直接为该类软件的名称software-name5.2.非官方镜像仓库除了官方镜像仓库其它都是非官方镜像仓库非官方镜像仓库名称repository一般由发布者用户名与软件名称两部分构成形式为:username/software-name(1).第三方镜像仓库第三方镜像仓库(Verified Publisher)已验证发布者仓库该类仓库中的镜像由非 Docker 官方的第三方发布但该第三方是由 Docker 公司审核认证过的(一般为大型企业、团体或组织),审核通过后Docker 公司会向其颁发VERIFIED PUBLISHER标识这种仓库中镜像的质量还有有保证的(2).个人镜像仓库个人镜像仓库(Sponsored OSS)由 Docker 公司赞助开发的镜像仓库该类仓库中的镜像也由非Docker官方的第三方发布(该类型的第三方一般为个人、团队或组织),但该镜像的开发是由 Docker 公司赞助的这种仓库中镜像的质量也是有保证的(3).无认证仓库没有以上任何标识的仓库这种仓库中镜像的质量良莠不齐,质量上无法保证,在使用时需谨慎6.第三方镜像中心镜像中心默认使用的都是 Docker 官方的 Docker Hub不过镜像中心是可配置的,可以使用指定的第三方镜像中心对于第三方镜像中心中的仓库名称repository由三部分构成domain-name/username/software-name其中的domain-nam 指的是第三方镜像中心的域名或 IP7.镜像定位对于任何镜像都可通过repository:tag进行唯一定位其中tag一般称为镜像的版本号tag中有一个比较特殊的版本(latest),如果不指定默认tag即为 latest不过虽然其字面意思是最新版,一般其也的确存放的是最新版,但并不能保证其真的就是最新版,因为可以在发布完latest后又发布了新版本,但是新版本直接直接定了tag没有指定成latest版本,这样latest就不是最新版8.多架构镜像(1).什么是多架构镜像Multi-architecture Image(即多架构镜像)是某repository中的某tag镜像针对不同操作系统/系统架构的不同镜像实现即多架构镜像中包含的镜像repository:tag都是相同的,但它们针对的操作系统/系统架构是不同的(2).多架构镜像原理无论用户使用的是什么操作系统/系统架构,其通过docker pull命令拉取到的一定是针对该操作系统/系统架构的镜像,无需用户自己考虑操作系统/系统架构问题Docker Hub 能够根据提交 pull 请求的 Docker 系统的架构自动选择其对应的镜像在 Docker Hub 中镜像的多架构信息保存在 Manifest 文件中在拉取镜像时Docker会随着 pull 命令将当前 Docker 系统的 OS 与架构信息一并提交给 Docker HubDocker Hub 首先会根据镜像的repository:tag查找是否存在 Manifest如果不存在则直接查找并返回repository:tag镜像即可如果存在则会在 Manifest 中查找是否存在指定系统/架构的镜像如果存在该系统/架构则根据 Manifest 中记录的地址找到该镜像的位置二.镜像相关命令1.拉取镜像从镜像仓库中拉取或者更新指定镜像1.1.语法格式语法格式dockerpull[OPTIONS]NAME[:TAG|DIGEST]选项说明(不加OPTIONS选项默认拉取最新镜像)-a,–all-tags下载镜像仓库中的所有镜像(慎用)–disable-content-trust跳过镜像验证(默认为true)如果下载的是官方镜像则可以不用验证如果下载的是个人的镜像最好开启验证,因为质量不能保证–platform string如果服务器支持多平台,则设置平台-q,–quiet简化输出格式1.2.使用示例(1).通过标签拉取通过docker pull 镜像名称:tag标签命令可以将指定的镜像从 docker hub 拉取到本地dockerpull 镜像名称:tag标签【示例】下面的命令是拉取 zookeeper 的 3.7.1 版本镜像dockerpull zookeeper:3.7.1(2).通过 digest 拉取docker pull可通过镜像的 digest 进行拉取(从 docker Hub 中具体镜像中可查看到其 digest)语法格式为dockerpullrepositorydigest【示例】dockerpull redissha256:fbdbaea47b9ae4ecc2082ecdb4e1cea81e32176ffb1dcf643d422ad07427e5d9(3).拉取最新镜像pull 命令中的tag可以使用latest拉取最新镜像也可以不写tag默认拉取的tag为 latest【示例】dockerpull redis(4).简化日志输出加上选项-q 后就可简化拉取过程中的日志输出dockerpull-qredis(5).不指定镜像如果没有指定镜像则会抛出一个Error2.列出本地所有镜像docker images命令列出本地镜像2.1.语法格式语法格式dockerimages[OPTIONS][REPOSITORY[:TAG]]选项说明-a,–all列出本地所有的镜像–digests显示镜像的摘要信息–digests 选项可以查看所有镜像或指定镜像的digest 信息-f,–filter filter显示满足条件的镜像–format string指定返回值的模板文件–no-trunc显示完整的镜像信息默认的 docker images 显示的镜像 id 是经过截取后的显示结果,仅显示了前 12 位使用 --no-trunc 参数后显示的是完成的镜像 id【示例】dockerimages --no-trunc-q,–quiet只显示镜像ID2.2.使用示例(1).基础用法查看本地所有镜像资源信息dockerimages这些镜像会按照镜像被创建的时间由近及远排序REPOSITORY:镜像仓库名称TAG:镜像版本号IMAGE ID:镜像的唯一标识CREATE:镜像的创建时间SIZE:镜像大小(2).查看指定镜像查看指定镜像的信息dockerimages 仓库名称【示例】(3).-a,–all查询本地所有镜像列出本地所有的镜像dockerimages--all【示例】(4).–digests查看摘要–digests 选项可以查看所有镜像或指定镜像的digest 信息dockerimages--digests【示例】(5).–filter过滤本地镜像过滤本地镜像dockerimages--filter过滤条件danglingtrue用于过滤出悬虚镜像,即没有 Repository 与 Tag 的镜像对于悬虚镜像的REPOSITORY 与 TAG,显示的是-f before用于列举出本地镜像中指定镜像创建时间之前创建的所有镜像【示例】dockerimages-fbeforenginx-f since用于列举出本地镜像中指定镜像创建时间之后的创建的所有镜像dockerimages-fsincehello-world-f reference用于列举出repository:tag与指定表达式相匹配的所有镜像【示例】dockerimages-freference*:latestdockerimages-freferencezookeeper:*(6).–no-trunc完整镜像信息dockerimages --no-trunc zookeeper(7).-q仅显示镜像 ID-q 选项可仅显示本地所有镜像的 ImageID该主要是将来与其它命令联合使用3.删除镜像命令删除本地一个或多少镜像,多个镜像之间用空格分开3.1.语法格式语法格式dockerrmi[OPTIONS]IMAGE[IMAGE...]选项说明-f :强制删除–no-prune : 不删除未带 tag 的父镜像,默认移除3.2.使用示例(1).通过镜像ID删除镜像docker rmi 也可通过 ImageID 指定要删除的镜像dockerrmi 镜像ID【示例】(2).根据镜像仓库删除删除指定的本地镜像rmi(remove images)镜像:标签镜像通过repository:tag指定如果省略要删除镜像的 tag默认删除的是 lastest 版本(3).删除多个镜像一次删除多个镜像,多个镜像中间使用空格分隔dockerrmi-ftomcat nginx【示例】(4).强制删除镜像默认情况下,对于已经运行了容器的镜像是不能删除的,必须要先停止并删除了相关容器然后才能删除其对应的镜像不过,也可以通过添加-f 选项进行强制删除【示例】(5).删除所有镜像使用组合命令删除所有镜像当然如果不携带-f 选项则不会删除已打开容器的镜像dockerrmi-f$(dockerimages-q)【示例】4.查找镜像命令通过 docker search 命令可以从 docker hub 上查看指定名称的镜像搜索网站:https://hub.docker.com4.1.语法格式语法格式dockersearch[OPTIONS]镜像名称选项说明-f,–filter filter 根据提供的条件过滤输出–format string 使用Go模板进行漂亮的打印搜索–limit int 最大搜索结果数(默认为25)–no-trunc 不截断输出查询结果NAME镜像仓库源的名称DESCRIPTION镜像的描述OFFICIAL是否 docker 官方发布stars类似 Github 里面的 star,表示点赞、喜欢的意思AUTOMATED是否是自动构建AUTOMATED 表示当前镜像是否是自动化镜像自动化镜像就是使用 Docker Hub 连接一个包含 Dockerfile 文件(专门构建镜像用的文件)的 GitHub 仓库或Bitbucket 仓库的源码托管平台,然后 Docker Hub 就会自动根据 Dockerfile 内容构建镜像这种构建出的镜像会被标记为AUTOMATED,这种构建镜像的方式称为 Trusted Build(受信构建)只要 Dockerfile文件内容发生变化,那么 Docker Hub 就会构建出新的镜像4.2.使用示例(1).过滤检索结果用于过滤查询结果(该命令只显示查询到的官方认证的镜像)【示例】下面的是仅查询出官方提供的镜像dockersearch zookeeper-fis-officialtrue(2).限制检索数量默认 docker search 显示 25 条检索结果,可通过–limit 选项来指定显示的结果数量【示例】dockersearch zookeeper--limit2(3).到 hub 官网查看以上检索方式与从 docker hub 官网 https://hub.docker.com 查看是一样的,但没有官网查看的直观5.创建镜像docker build命令用于使用 Dockerfile 创建镜像5.1.docker build创建镜像5.1.1.语法格式语法格式dockerbuild[OPTIONS]PATH|URL|-PATH: 包含 Dockerfile 的目录路径或 .(当前目录)URL: 指向包含 Dockerfile 的远程存储库地址(如 Git 仓库)-: 从标准输入读取 Dockerfile选项说明常用选项-t, --tag为构建的镜像指定名称和标签格式为 name:tag 或 name可以在一次构建中为一个镜像设置多个标签-f, --file指定 Dockerfile 的路径(默认是 PATH 下的 Dockerfile)–build-arg设置构建参数–no-cache不使用缓存层构建镜像–rm构建成功后删除中间容器(默认开启)–force-rm无论构建成功与否,一律删除中间容器–pull始终尝试从注册表拉取最新的基础镜像尝试去更新镜像的新版本–quiet, -q简化日志输出格式,构建成功后只输出镜像 ID更多选项说明–build-arg[]: 设置构建镜像时的变量–cpu-shares: 设置 CPU 使用权重–cpu-period: 限制 CPU CFS 周期–cpu-quota: 限制 CPU CFS 配额–cpuset-cpus: 指定可使用的 CPU ID–cpuset-mems: 指定可使用的内存节点 ID–disable-content-trust: 忽略内容信任验证(默认启用)-f: 指定 Dockerfile 的路径–force-rm: 强制在构建过程中删除中间容器–isolation: 使用指定的容器隔离技术–label[]: 设置镜像的元数据-m: 设置内存的最大值–memory-swap: 设置交换空间的最大值(内存 交换空间),-1 表示不限制交换空间–no-cache: 构建镜像时不使用缓存–pull: 尝试拉取基础镜像的最新版本–quiet, -q: 安静模式,构建成功后只输出镜像 ID–rm: 构建成功后删除中间容器(默认启用)–shm-size: 设置 /dev/shm 的大小,默认值为 64M–ulimit: 设置 Ulimit 配置–squash: 将 Dockerfile 中所有步骤压缩为一层–network: 在构建期间设置 RUN 指令的网络模式,默认值为 default5.1.2.使用示例(1).构建镜像dockerbuild-tmyimage:latest.这会从当前目录读取 Dockerfile 并构建一个名为 myimage:latest 的镜像(2).指定 Dockerfile 路径dockerbuild-f/path/to/Dockerfile-tmyimage:latest.这会从 /path/to/ 目录读取 Dockerfile 并构建一个名为 myimage:latest 的镜像(3).设置构建参数dockerbuild --build-argHTTP_PROXYhttp://proxy.example.com-tmyimage:latest.这会在构建过程中使用 HTTP_PROXY 环境变量(4).不使用缓存层构建镜像dockerbuild --no-cache-tmyimage:latest.这会在构建镜像时忽略所有缓存层,确保每一步都重新执行5.2.docker import创建镜像从归档文件中创建镜像(1).语法格式语法格式dockerimport[OPTIONS]file|URL|-[REPOSITORY[:TAG]]选项说明-c,–change list应用docker 指令创建镜像-m,–message string提交时的说明文字–platform string如果服务器支持多平台,则设置平台(2).使用示例从镜像归档文件test.tar创建镜像命名为aaadockerimporttest.jar aaa6.查看镜像的创建历史查看指定镜像的创建历史(1).语法语法格式dockerhistory[OPTIONS]IMAGE选项说明–format string使用自定义模板设置输出格式“table”:以带列标题的表格格式打印输出(默认)“table TEMPLATE”:使用给定的Go模板以表格格式打印输出‘json’:以json格式打印‘TEMPLATE’:使用给定的Go模板打印输出-H,–human以可读的格式打印镜像大小和日期,默认为true–no-trunc显示完整的提交记录-q,–quiet简化输出格式仅列出提交记录ID(2).使用示例查看本地镜像7e49ed81b42b的创建历史dockerhistory7e49ed81b42b执行结果7.镜像标签标记本地镜像,将其归入某一仓库7.1.语法格式dockertag SOURCE_IMAGE[:TAG]TARGET_IMAGE[:TAG]7.2.使用示例(1).使用镜像名打标签将镜像redis:latest标记为myredis:v1.0镜像dockertag redis:latest myredis:v1.0(2).使用镜像ID打标签【示例】docker tag 3aaebb1590f5 registry.cn-hangzhou.aliyuncs.com/longdidi/aaa:latest8.导入/导出镜像命令在本地生成一个镜像,想将其导出后在另一电脑上使用,则可通过导出/导入镜像来完成8.1.导出镜像docker save 命令用于将一个或多个镜像导出为 tar 文件(1).语法格式语法格式dockersave[OPTIONS]IMAGE[IMAGE...]选项说明-o,–output输出到的文件(2).使用示例将镜像redis:latest和hello-world:latest生成 “test.tar” 文档dockersave-otest.jar redis:latest nginx:latest执行结果8.2.导入镜像docker load 用于将一个 tar 文件导入并加载为一个或多个镜像(1).语法格式语法格式dockerload[OPTIONS]选项说明-i,–input指定导入的文件,代替 STDIN-q,–quiet精简输出信息(2).使用示例dockerload-itest.jar导入镜像9.上传镜像docker push命令用于将本地的镜像上传到镜像仓库,要先登陆到镜像仓库(1).语法格式语法格式dockerpush[OPTIONS]NAME[:TAG]选项说明-a, --all-tags–disable-content-trust忽略镜像的校验,默认开启-q, --quiet精简打印输出(2).使用示例上传本地镜像aaa到镜像仓库中【示例】# 登录镜像中心dockerlogin--usernamezhl890112 registry.cn-hangzhou.aliyuncs.com# 给镜像打标签dockertag[ImageId]registry.cn-hangzhou.aliyuncs.com/longdidi/aaa:[镜像版本号]# 上传镜像dockerpush registry.cn-hangzhou.aliyuncs.com/longdidi/aaa:[镜像版本号]10.登录/登出镜像仓库10.1.登录镜像仓库docker login命令登陆到一个Docker镜像仓库如果未指定镜像仓库地址则默认为登录官方仓库Docker Hub(1).语法格式语法格式dockerlogin[OPTIONS][SERVER]选项说明-p,–password string 密码–password-stdin 从控制台获取密码-u,–username string 用户名(2).使用示例登陆到Docker Hubdockerlogin-u用户名-p密码登录到阿里云镜像sudo docker login--usernamezhl890112 registry.cn-hangzhou.aliyuncs.com10.2.登出镜像仓库(1).语法格式docker logout命令用于登出一个Docker镜像仓库如果未指定镜像仓库地址则默认为登出官方仓库 Docker Hubfontdockerlogout[SERVER](2).使用示例登出Docker Hubdockerlogout登出阿里云docker logout registry.cn-hangzhou.aliyuncs.com