Docker学习(二): 镜像的使用与构建
特别声明:
博文主要是学习过程中的知识整理,以便之后的查阅回顾。部分内容来源于网络(如有摘录未标注请指出)。内容如有差错,也欢迎指正!
=============系列文章=============
3. Docker学习(三): Dockerfile指令介绍
=================================
获取镜像
获取镜像命令: docker pull [选项] [Docker Registry地址]<仓库名>:<标签>
Docker Registry地址:格式一般是<域名/IP>[:端口号], 默认是Docker Hub
仓库名:<用户名>/<软件名>,Docker Hub默认用户名为library
例:docker pull ubuntu:14.04,从Docker Hub获取镜像,即library/ubuntu:14.04
运行镜像命令:docker run [选项] <仓库名:标签 或 镜像ID> [COMMAND]
例:docker run -it --rm ubuntu:14.04 bash
-it:-i 交互式操作,-t 终端,即交互式终端。
--rm:容器退出后随之将其删除,避免空间浪费;一般情况需要docker rm手动删除容器
bash:命令,bash为获取交互式Shell
exit:退出容器,返回宿主机
列出镜像命令:docker images
需要注意docker images列表中的镜像体积总和并非是所有镜像实际硬盘消耗。由于Docker镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层。由于Docker使用Union FS,相同的层只需要保存一份即可,因此实际镜像硬盘占用空间很可能要比这个列表镜像大小的总和要小很多。
虚悬镜像:对于既没有仓库名,也没有标签,均为<none>的镜像称为虚悬镜像(dangling image),产生的原因的是同仓库名和标签的镜像由于镜像更新被转移到了新的镜像身上。
显示虚悬镜像命令:docker images -f dangling=true
删除虚悬镜像命令:docker rmi $(docker images -f dangling=true)
显示中间层镜像命令:docker images -a
列出部分镜像命令:
a. 根据仓库名:docker images ubuntu
b. 过滤器参数:docker images -f since=mongo:3.2 (列出mongo:3.2之后建立的镜像)
c. 过滤器-label: docker images -f label=com.example.version=0.1
列出特定格式的镜像:
只列出镜像的ID:docker images -q
Go的模板语法:docker images --format "{{.ID}}: {{.Repository}}"
构建镜像
一、commit(将容器的存储层保存下来成为镜像,原有镜像基础上加上存储层)
命令:docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
例:docker commit --author "konrad" --message "update msg" webserver nginx:v2
查看提交历史命令:docker history <仓库名>[:<标签>]
注:慎用!!!!会有大量无关内容被添加进来,会导致镜像臃肿。生成的镜像是黑箱镜像,别人不知道具体里面做了什么。
二、Dockerfile
镜像构建透明的,Dockerfile本身就是一个文本文件,内包含了一条条的指令;每条指令构建一层,因此每一条指令的内容,就是描述该层应该如何构建。
Dockerfile实例:
FROM nginx RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
FROM:指定哪个镜像为基础,在其上进行定制。必须是第一条指令
RUN:用来执行命令行命令的
shell格式:RUN <命令> ,就像直接在命令行中输入的命令一样
exec格式:RUN ["可执行文件", "参数1", "参数2"],像函数调用中的格式
注:虽然RUN像Shell脚本一样可以执行命令,但是每条命令就是一层镜像,把每个命令都对应RUN会构建出很多层镜像,镜像会包括一些没有用的东西。Union FS是有最大层数限制的,比如AUFS,最大不得超过127层。所以正确的写法如下:
FROM debian:jessie RUN buildDeps='gcc libc6-dev make' \ && apt-get update \ && apt-get install -y $buildDeps \ && wget -O redis.tar.gz "http://download.redis.io/releases/r edis-3.2.5.tar.gz" \ && mkdir -p /usr/src/redis \ && tar -xzf redis.tar.gz -C /usr/src/redis --strip-component s=1 \ && make -C /usr/src/redis \ && make -C /usr/src/redis install \ && rm -rf /var/lib/apt/lists/* \ && rm redis.tar.gz \ && rm -r /usr/src/redis \ && apt-get purge -y --auto-remove $buildDeps
使用&&将各个所需命令串联起来,仅使用一个RUN命令,所以只构建了1层。行尾\表示换行,这里在最后还进行了清理工作,清理了下载、展开的文件等。
构建镜像
一、docker build [选项] <上下文路径/URL/->
-t:执行镜像的名称<名称>:<标签>
上下文路径:.并非表示Dockerfile文件所在的当前路径,而是指上下文路径。因为docker build命令构建镜像,并非在本地构建,而是在服务端,也就是Docker引擎中构建的。用户指定构建的上下文的路径,docker build命令得知这个路径后,会将路径下的所有内容打包,然后上传给Docker引擎。
二、从rootfs压缩包导入
命令:docker import [选项] <文件>|<URL>|- [<仓库名>[:<标签>]]
压缩包可以是本地文件、远程web文件,甚至标准输入中得到。压缩包将会在镜像/目录展开,并直接作为第一次提交。
三、docker save 和 docker load
docker save:将镜像保存为归档文件
示例:docker save alpine | gzip > alpine-latest.tar.gz
docker load:加载镜像
示例:docker load -i alpine-latest.tar.gz
从一个机器将镜像迁移到另一个机器
docker save <镜像名> | bzip2 | pv | ssh <用户名>@<主机名> ‘cat | docker laod’
管理本地镜像
删除本地镜像:docker rmi [选项] <镜像1> [<镜像2> ...]
<镜像>:可以是镜像短ID(一般取前3位)、镜像长ID、镜像名或者镜像摘要
Untagged:表示取消镜像的标签
Deleted:真正的删除镜像动作
也可配合docker images命令来删除指定的镜像
镜像实现基本原理
Union FS用途:一方面可以实现不借助LVM、RAID将多个disk挂到同一个目录下,另一个更常用的就是将一个只读的分支和一个可写的分支联合在一起,Live CD正式基于此方法可以允许在镜像不变的基础上允许用户在其上进行一些些操作。Docker在AUFS上构建的容器也是利用了类似的原理。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
参考:《docker_practice》