文章目录
Docker镜像
镜像是Docker的三大组件之一
Docker运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker会从镜像仓库下载(默认是Docker Hub)
本笔记主要介绍关于镜像的内容有:
1、从仓库获取镜像;
2、管理本地主机上的镜像;
3、介绍镜像实现的基本原理。
Docker镜像管理命令:
docker image
1.1 基本操作
Docker Hub上有大量的高质量的镜像可以用,先熟悉如果获取这些镜像并运行
1.1.1 命令介绍
从Docker Registry获取镜像的命令是 docker pull,格式如下
docker pull [选项] [Docker Registry地址]<仓库名>:<标签>
上面命令中的Docker Registry地址,可以不写,不写默认从Docker Hub或者个人配置的国内镜像仓库获取镜像
查看具体选项(帮助):
docker pull --help
运行结果:
镜像名称的格式:
- Docker Registry 地址:地址的格式一般是 <域名/IP>[:端口号] 。默认地址是 Docker Hub。
- 仓库名:如之前所说,这里的仓库名是两段式名称,即 <用户名>/<软件名> 。对于 Docker Hub,如果不给出用户名,则默认为 library ,也就是官方镜像。
1.1.2 获取镜像
以获取 ubuntu:14.04 镜像举例
命令:
docker pull ubuntu:14.04
docker image pull unbuntu:17.10
Docker1.13+ 版本中推荐使用docker image来管理镜像
运行结果:
上面的命令中没有给出 Docker Registry 地址,因此将会从 Docker Hub 获取镜像。而镜像名称是 ubuntu:14.04 ,因此将会获取官方镜像 library/ubuntu 仓库中标签为 14.04 的镜像。
1.1.3 运行
以上面ubuntu:14.04为例的交互式操作
docker run -it --rm ubuntu:14.04 bash
运行结果:
在上图的:/$#号后面输入命令,查看版本相关信息:
cat /etc/os-release
输入 exit可以退出
docker run 就是运行容器的命令,讲一讲上面的参数
- -it :这是两个参数,一个是 -i :交互式操作,一个是 -t 终端。我们这里打算进入
- bash 执行一些命令并查看返回结果,因此我们需要交互式终端。
- –rm :这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容
- 器并不会立即删除,除非手动 docker rm 。我们这里只是随便执行个命令,看看结果,
- 不需要排障和保留结果,因此使用 --rm 可以避免浪费空间。
- ubuntu:14.04 :这是指用 ubuntu:14.04 镜像为基础来启动容器。
- bash :放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 bash 。
1.1.4 列出镜像-查看
1、查看命令:
docker images
docker image ls
在 Docker 1.13+ 版本中推荐使用 docker image ls 来查看镜像列表。
2、查看镜像、容器、数据卷所占用的空间:
docker system df
3、查看中间层镜像
docker images -a
为了加速镜像构建、重复利用资源,Docker 会利用 中间层镜像,默认的 docker images 列表中只会显示顶层镜像
4、条件查询
列出某个名称的镜像
docker images ubuntu
列出某个特定的镜像,指定名称与标签
docker images ubuntu:16.04
没有,嘿嘿~
5、过滤器 --filter
docker image -f 条件=值
6、展示id
docker images -q
7、格式化展示
#展示镜像ID和仓库名
docker images --format "{{.ID}}: {{.Repository}}"
#表格等距显示,并且有标题行,和默认一样,不过自己定义列:
docker images --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"
1.2 镜像构成
1.2.1 从commit理解镜像构成
镜像是容器的基础,每次执行 docker run 的时候都会指定哪个镜像作为容器运行的基础。在之前的例子中,我们所使用的都是来自于 Docker Hub 的镜像。直接使用这些镜像是可以满
足一定的需求,而当这些镜像无法直接满足需求时,我们就需要定制这些镜像。接下来的几节就将讲解如何定制镜像。
定制Web服务器举例
1.2.1.1、初始化容器
docker run --name webserver -d -p 80:80 nginx
这条命令会用 nginx 镜像启动一个容器,命名为 webserver ,并且映射了 80 端口,这样我们可以用浏览器去访问这个 nginx 服务器。
输入:
curl http://localhost
显示如下:Nginx欢迎页面的HTML,如果是桌面系统,可以直接在浏览器中输入http://localhost打开网页
1.2.1.2、定制首页
修改主页文字
#docker exec 命令(进入容器)
docker exec -it webserver bash
#进入容器后输入修改主页文字的脚本 命令
echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
修改完成后,使用exit退出容器,然后使用curl http://localhost,如图
我们修改了容器的文件,也就是改动了容器的存储层。我们可以通过 docker diff 命令看到具体的改动。
#查看webserver的改动
docker diff webserver
1.2.1.3、制作镜像
上面修改完成算是定制好了变化 ,下一步可以用docker commit命令将其制成镜像
docker commit的语法格式:
docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
命令:
docker commit --author "hunwei" --message "修改了默认网页" webserver nginx:v2
查看镜像:
docker images
查看镜像历史记录(docker history)
docker history nginx:v2
1.2.1.4、运行定制镜像
#这里我们命名为新的服务为 web2 ,并且映射到 81 端口
docker run --name web2 -d -p 81:80 nginx:v2
访问:
curl http://localhost:81
1.2.2 使用Dockerfile定制镜像
Dockerfile是一个文本文件上,包含一条条指令(Instruction),每一条指令构建一层。
有这么一个文件记录,能清清楚楚知道每一层构建的记录
1.2.2.1、新增Dockerfile
以nginx镜像为例
#新增一个目录,在目录下添加一个Dockerfile
mkdir mynginx
cd mynginx
touch Dockerfile
在Dockerfile里添加
FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
FROM 指定基础镜像,在文件中是必备且是第一条命令
- 在 Docker Store 上有非常多的高质量的官方镜像,有可以直接拿来使用的服务类的镜像,如nginx 、 redis 、 mongo 、 mysql 、 httpd 、 php 、 tomcat 等;也有一些方便开发、构建、运行各种语言应用的镜像,如 node 、 openjdk 、 python 、 ruby 、 golang 等。可以 在其中寻找一个最符合我们最终目标的镜像为基础镜像进行定制。
- 如果没有找到对应服务的镜像,官方镜像中还提供了一些更为基础的操作系统镜像,如ubuntu 、 debian 、 centos 、 fedora 、 alpine 等,这些操作系统的软件库为我们提供了更广阔的扩展空间。
- 除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 scratch 。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。
RUN 执行命令
最常用定制镜像的指令之一,有丙格格式
- shell 格式: RUN <命令> ,就像直接在命令行中输入的命令一样。刚才写的 Dockerfile 中的 RUN 指令就是这种格式
- exec 格式: RUN [“可执行文件”, “参数1”, “参数2”] ,这更像是函数调用中的格式。
1.2.2.2、构造镜像
命令格式:
docker build [选项] <上下文路径/URL/->
制定上面Dokerfile里的镜像,在其目录下运行下面命令
docker build -t nginx:v3 .
查看
上下文路径注解:
指定上下文的目录, docker build 命令会将该目录下的内容打包交给Docker 引擎以帮助构建镜像
批定上下文与 COPY 、ADD指令联动
1.2.2.2.1、docker build其他用法
#url构建
docker build https://github.com/twang2218/gitlab-ce-zh.git#:8.14
#给定tar压缩包构建
docker build http://server/context.tar.gz
#读取Dockerfile构建
docker build - < Dockerfile
#或
cat Dockerfile | docker build -
#从标准输入中读取上下文压缩包进行构建
docker build - < context.tar.gz
如果发现标准输入的文件格式是 gzip 、 bzip2 以及 xz 的话,将会使其为上下文压缩包,
直接将其展开,将里面视为上下文,并开始构建。
Docker 1.13+版本命令
docker image build
1.3 多阶段构建
构建过程编全部放入一个Dockerfile里会有一些问题
- Dockerfile 特别长,可维护性降低
- 镜像层次多,镜像体积较大,部署时间变长
- 源代码存在泄露的风险
略~~~暂时还不熟悉
1.4、其他生成镜像方法
1.4.1 从rootfs压缩包导入
格式:
docker import [选项] <文件>|<URL>|- [<仓库名>[:<标签>]]
压缩包可以是本地文件、远程 Web 文件,甚至是从标准输入中得到。压缩包将会在镜像 /目录展开,并直接作为镜像第一层提交。
举例:
docker import http://download.openvz.org/template/precreated/ubuntu-14.04-x86_64-minimal.tar.gz
\
openvz/ubuntu:14.04
这条命令自动下载了 ubuntu-14.04-x86_64-minimal.tar.gz 文件,并且作为根文件系统展开导入,并保存为镜像 openvz/ubuntu:14.04
1.4.2 保存迁移
docker save 、docker load
docker load 和 docker save 命令,用以将镜像保存为一个 tar 文件,然后传输到另一个位置上,再加载进来。这是在没有 Docker Registry 时的做法、不推荐
1.4.3 、删除本地镜像
命令:
docker rmi
格式:
- docker rmi [选项] <镜像1> [<镜像2> …]
其中, <镜像> 可以是 镜像短 ID 、 镜像长 ID 、 镜像名 或者 镜像摘要 。
1.5 镜像的实现原理
- Docker 镜像是怎么实现增量的修改和维护的? 每个镜像都由很多层次构成,Docker 使用Union FS 将这些不同的层结合到一个镜像中去。
- 通常 Union FS 有两个用途, 一方面可以实现不借助 LVM、RAID 将多个 disk 挂到同一个目录下,另一个更常用的就是将一个只读的分支和一个可写的分支联合在一起,Live CD 正是基于此方法可以允许在镜像不变的基础上允许用户在其上进行一些写操作。Docker 在 AUFS 上构建的容器也是利用了类似的原理。