03 | Docker镜像的使用
镜像是一个只读的 Docker 容器模板,包含启动容器所需要的所有文件系统结构和内容。简单来讲,镜像是一个特殊的文件系统,它提供了容器运行时所需的程序、软件库、资源、配置等静态数据。即镜像不包含任何动态数据,镜像内容在构建后不会被改变。
镜像操作
-
拉取镜像,使用docker pull命令拉取远程仓库的镜像到本地 ;
-
重命名镜像,使用docker tag命令“重命名”镜像 ;
-
查看镜像,使用docker image ls或docker images命令查看本地已经存在的镜像 ;
-
删除镜像,使用docker rmi命令删除无用镜像 ;
-
构建镜像,构建镜像有两种方式。第一种方式是使用docker build命令基于 Dockerfile 构建镜像,也是我比较推荐的镜像构建方式;第二种方式是使用docker commit命令基于已经运行的容器提交为镜像。
拉取镜像
Docker镜像的拉取使用docker pull命令
格式:docker pull [Registry]/[Repository]/[Image]:[Tag]
-
Registry 为注册服务器,Docker 默认会从 docker.io 拉取镜像,如果你有自己的镜像仓库,可以把 Registry 替换为自己的注册服务器。
-
Repository 为镜像仓库,通常把一组相关联的镜像归为一个镜像仓库,library为 Docker 默认的镜像仓库。
-
Image 为镜像名称。
-
Tag 为镜像的标签,如果你不指定拉取镜像的标签,默认为latest
busybox 是一个集成了数百个 Linux 命令(例如 curl、grep、mount、telnet 等)的精简工具箱,只有几兆大小,被誉为 Linux 系统的瑞士军刀。我经常会使用 busybox 做调试来查找生产环境中遇到的问题
$ docker pull docker.io/library/busybox:latest
实际上执行docker pull busybox命令,都是先从本地搜索,如果本地搜索不到busybox镜像则从 Docker Hub 下载镜像。
查看镜像
Docker 镜像查看使用docker images或者docker image ls命令
“重命名”镜像
如果你想要自定义镜像名称或者推送镜像到其他镜像仓库,你可以使用docker tag命令将镜像重命名。docker tag的命令格式:
docker tag [SOURCE_IMAGE][:TAG] [TARGET_IMAGE][:TAG]。
$ docker tag busybox:latest mybusybox:latest
busybox和mybusybox这两个镜像的 IMAGE ID 是完全一样的。为什么呢?实际上它们指向了同一个镜像文件,只是别名不同而已。
删除镜像
你可以使用docker rmi或者docker image rm命令删除镜像。
$ docker rmi mybusybox
构建镜像
两种方式:
-
使用docker commit命令从运行中的容器提交为镜像;
-
使用docker build命令从 Dockerfile 构建镜像。
(1)如何从运行中的容器提交为镜像。依旧使用 busybox 镜像举例,
使用以下命令创建一个名为 busybox 的容器并进入 busybox 容器。
$ docker run --rm --name=busybox -it busybox sh
执行完上面的命令后,当前窗口会启动一个 busybox 容器并且进入容器中。在容器中,执行以下命令创建一个文件并写入内容:
$ touch hello.txt && echo "I love Docker. " > hello.txt
此时在容器的根目录下,已经创建了一个 hello.txt 文件,并写入了 "I love Docker. "。下面,我们新打开另一个命令行窗口,运行以下命令提交镜像:
$ docker commit busybox busybox:hello
sha256:3481553b418e088994f4231784690fc3ef6d21cebccef54e765321785bf2dcee
然后使用上面讲到的docker image ls命令查看镜像:
可以看到主机上新生成了 busybox:hello 这个镜像。
(2)最常用的镜像构建方式:Dockerfile。Dockerfile 是一个包含了用户所有构建命令的文本。通过docker build命令可以从 Dockerfile 生成镜像。
使用 Dockerfile 构建镜像具有以下特性:
-
Dockerfile 的每一行命令都会生成一个独立的镜像层,并且拥有唯一的 ID;
-
Dockerfile 的命令是完全透明的,通过查看 Dockerfile 的内容,就可以知道镜像是如何一步步构建的;
-
Dockerfile 是纯文本的,方便跟随代码一起存放在代码仓库并做版本管理。
Dockerfile 常用的指令。
FROM centos:7
COPY nginx.repo /etc/yum.repos.d/nginx.repo
RUN yum install -y nginx
EXPOSE 80
ENV HOST=mynginx
CMD ["nginx","-g","daemon off;"]
-
第一行表示我要基于 centos:7 这个镜像来构建自定义镜像。这里需要注意,每个 Dockerfile 的第一行除了注释都必须以 FROM 开头。
-
第二行表示拷贝本地文件 nginx.repo 文件到容器内的 /etc/yum.repos.d 目录下。这里拷贝 nginx.repo 文件是为了添加 nginx 的安装源。
-
第三行表示在容器内运行yum install -y nginx命令,安装 nginx 服务到容器内,执行完第三行命令,容器内的 nginx 已经安装完成。
-
第四行声明容器内业务(nginx)使用 80 端口对外提供服务。
-
第五行定义容器启动时的环境变量 HOST=mynginx,容器启动后可以获取到环境变量 HOST 的值为 mynginx。
-
第六行定义容器的启动命令,命令格式为 json 数组。这里设置了容器的启动命令为 nginx ,并且添加了 nginx 的启动参数 -g ‘daemon off;’ ,使得 nginx 以前台的方式启动。
上面这个 Dockerfile 的例子基本涵盖了常用的镜像构建指令,代码我已经放在 GitHub上,如果你感兴趣可以到 GitHub 下载源码并尝试构建这个镜像。
镜像的实现原理
其实 Docker 镜像是由一系列镜像层(layer)组成的,每一层代表了镜像构建过程中的一次提交。下面以一个镜像构建的 Dockerfile 来说明镜像是如何分层的
FROM busybox
COPY test /tmp/test
RUN mkdir /tmp/testdir
上面的 Dockerfile 由三步组成:
第一行基于 busybox 创建一个镜像层;
第二行拷贝本机 test 文件到镜像内;
第三行在 /test 文件夹下创建一个目录 testdir。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KI2rL0pz-1601983409582)(./img/镜像文件系统.png)]
总结一下, Docker 镜像是静态的分层管理的文件组合,镜像底层的实现依赖于联合文件系统.
分层的结构使得 Docker 镜像非常轻量,每一层根据镜像的内容都有一个唯一的 ID 值,当不同的镜像之间有相同的镜像层时,便可以实现不同的镜像之间共享镜像层的效果。(UnionFS)
遇到的问题:
1.使用xshell 的文件/打开来打开另外一个命令行窗口