Docker学习笔记之使用镜像
概述
在上一篇文章 Docker学习笔记之安装 中,我们学习了docker在Centos7中的安装,接下来我们学习Docker镜像的使用。这一篇中,关于镜像的使用所涉及的命令有:pull、images、ls、tag、inspect、search、rm、rmi、run、commit、import、build、save、load、push等命令,但由于篇幅有限,对于相关的命令的参数,无法一一介绍,有兴趣的同学,需要自己在使用中细细的理解,对于有些理解有误的,也请多多指正。
获取镜像:pull命令
镜像是运行容器的前提,在官方的Docker Hub 网站上已经有几十万个镜像可以供大家下载,打开后,简单注册一下登录,即可,这里我们先学习pull子命令。可以通过 docker [image] pull 命令从Docker hub 镜像下载到指定的镜像,命令格式为:docker [image] pull name[:TAG] ,其中,[image]指的就是镜像的意思,可以忽略,name 是镜像在仓库的名称,[:TAG]是镜像的标签,一般来说指的是镜像的版本信息,如果不输入的话,则默认为:latest ,也可以指定TAG信息,下面以 ubuntu 为例:
[root@localhost ~]# systemctl start docker
[root@localhost ~]# docker image pull ubuntu:14.04
查看镜像:images 命令
这里下载了ubuntu 14.04 版本的镜像,下载的过程,会有进度提示,下载完成后,可以通过命令 docker images 查看机器中现存在的docker
[root@localhost ~]# docker images
可以看到 红色框住的镜像为前面下载到的镜像,我机器上之前有操作过其他的镜像,显示的列表信息会跟你们的不同。REPOSITORY 为镜像的名称,TAG 就是上面提到的 标签(版本信息),IMAGE ID 为容器的ID,CREATED 为容器被创建的时间,我们可以看到 ubuntu 14:04 这版本的容器被创建的时间为 6 months ago ,并不是上面的下载到本地的时间。SIZE 为容器的大小
值得一说的是,如果有其他特殊的需要,我们也可以从指定的仓库下载到指定的镜像,例如:
[root@localhost ~]# docker pull hub.c.163.com/public/centos:6.5
这里pull 指定的 centos:6.5版本的镜像,默认是从Docker hub 下载
运行镜像:run命令
镜像下载完成后,我们即可使用run命令运行镜像,例如利用镜像创建一个容器,在其中运行bash应用,执行打印命令:
[root@localhost ~]# docker run -it ubuntu:14.04 bash
说到run命令,我们这里也顺便提一下Dockerfile文件,我们可以新建Dockerfile文件,用于将一些命令通过Dockerfile运行(不等于shell文件),用于构建自己的镜像,比如:我们使用Dockerfile创建一个.Net Core 的Web项目的镜像,然后运行,又或者是JAR的Web项目,这都是可以的。这里不详细展开,将在在后续的文章中说明。
从上面的图片,我们可以看到有 7f7c716106b6 的这样标识,这个就是容器的ID,说明通过run进入了 ubuntu:14.04镜像内部,并且可以通过参数i用于接收用户的输入,同进可以通过ps查看到镜像里面,运行了 bash和ps 两个程序,参数说明:
i:打开STDIN,用于控制台交互;
t:分配置tty设备,可以支持终端登录,默认为false;
其他常用的参数有:
P:指定容器暴露的端口;
d:指定容器运行于前台还是后台,默认为false;
v:给容器挂载存储卷,挂载到容器的某个目录;
w:指定容器的工作目录;
run的参数还有很多,这里就不一一说明了,需要大家使用的过程中慢慢体会。
添加镜像标签:tag 命令
为了方便在使用过程中的识别,常常需要使用到tag命令,该命令可以用来为本地镜像任意添加新的标签,例如:添加一个新的 myubuntu:latest镜像标注:
[root@localhost ~]# docker tag ubuntu:latest myubuntu:latest
从上面的图片中,我们可以看到,新增了 名称为 myubuntu 的镜像,但细心的同学,可能会发现 它的镜像ID 为 825d55fb6340,这与 名称 为 ubuntu TAG 为 latest 的镜像ID 是一致的,这是什么原因?它们实际上指向了同一个镜像文件,只是名称不同而已,docker tag 命令添加标签,实际上只是起到了类似链接的作用,而已并不是新增镜像文件。
查看详细信息:inspect命令
使用 docker [image] inspect 命令可以查看镜像的详细信息,包括制作者、适应架构、版本等、显示出来的信息,默认是以JSON格式展示的。例如,查看 ubuntu:latest 的信息:
[root@localhost ~]# docker inspect ubuntu:latest
这里只截取部分信息的图片,在不加其他参数的情况下,展示的信息类似上图所示,但如果你只想显示你想要的那部分信息,而且你也知道这个信息的位置(层级),那么,你可以使用 format 参数,只展示你想要的那部分信息,如:
[root@localhost ~]# docker inspect ubuntu:latest --format='{{.ContainerConfig.Hostname}}'
如上图,便可以只展示 Hostname 的信息了。
搜索镜像:search命令
可以通过search子命令搜索Docker Hub官方仓库中的镜像,用法为:docker search [option] keyword
有如下参数:
-f, --filter filter:过滤输出内容;
--format string:格式化输出内容;
--limit int:限制输出结果个数,默认为25个;
--no-trunc:不截断输出结果;
例如,搜索官方的ubuntu镜像:
[root@localhost ~]# docker search --filter=is-official=true ubuntu
删除和清理:rmi、rm和prune 命令
接下来我们学习 rmi 命令删除镜像,命令格式为 docker rmi IMAGE [IMAGE], 其中 IMAGE 可以是标签,也可以是 镜像ID,删除多个镜像,则镜像之间用空格分开,按顺序逐个删除,如其中有镜像因其他原因无法删除时,则停止删除。
可选参数有:
-f, -force:强制删除镜像,即使是有容器依赖或使用它;
-no-prune:不要清理未带标签的父镜像;
例如删除 镜像ID为 a7876479f1aa 的镜像,可以使用 命令:
[root@localhost ~]# docker rmi a7876
如上图所示 a7876 为镜像ID a7876479f1aa 的前5个字符,在多个镜像时,可以使用镜像名称中前几个唯一识别镜像名称的部分字符即可,也可以使用 镜像的名称,如存在多个镜像名称相同的镜像中,则需要加上TAG,
如:docker rmi ubuntu:14.04 ,如果TAG没有指定,默认为 latest。
rm删除容器。命令格式为 docker rm CONTAINER ID ,其中 CONTAINER ID 为容器的ID
它的参数有:
-f:强制删除;
-l:移除容器间的网络连接,而非容器本身;
-v:删除与容器关联的卷
为了删除例子,我们先运行一个容器:
[root@localhost ~]# docker run -itd ubuntu:14.04 bash
a4de125a8ce69b89a1df51b8e38ecb05dd9b4d39ba3ee589bd2c7f01c4c515d9
然后,我们使用 docker ps 命令查看运行的容器:
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a4de125a8ce6 ubuntu:14.04 "bash" 9 seconds ago Up 8 seconds clever_hellman
现在,我们尝试使用命令删除容器:
[root@localhost ~]# docker rm a4de125a8ce6
Error response from daemon: You cannot remove a running container a4de125a8ce69b89a1df51b8e38ecb05dd9b4d39ba3ee589bd2c7f01c4c515d9. Stop the container before attempting removal or force remove
很显然,这个容器已经在运行,我们无法正常删除它,那么这个时候,想要删除它,就必需要对它进行强制删除了,命令如下:
[root@localhost ~]# docker rm -f a4de125a8ce6
说到删除,这里也不得不说一下 **prune** 命令,它是用来删除不再使用的 docker 对象的,什么意思?就是用于释放一些可释放而又没有被释放的资源,常用的用法有:
1、清理没有使用的数据,包括镜像数据,已经停止的容器
[root@localhost ~]# docker system prune
2、删除所有未被 tag 标记和未被容器使用的镜像:
docker image prune
3、删除所有未被容器使用的镜像:
docker image prune -a
4、删除所有停止运行的容器:
docker container prune
5、删除所有未被挂载的卷:
docker volume prune
6、删除所有网络:
docker network prune
创建镜像:commit、import和build命令
1、基于已有的容器创建,命令格式为:docker [container] commit [OPTIONS] CONTAINER [REPOSITORY[:tag]] 。
OPTIONS说明有:
-a, --author="":作者信息;
-c,--change=[]:提交的时候执行Dockerfile指令,包括CMD|ENTRYPOINT|ENV|EXPOSE|LABEL|ONBUILD|USER|VOLUME|WORKDIR等;
-m,--message="":提交信息;
-p,--pause=true:提交时暂停容器运行。
示例如下:
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 f5cbed4244ba 13 days ago 63.2MB
[root@localhost ~]# docker run -itd f5cbed4244ba bash
6443da401f83f7ab1379047f2b78ac6b1a9a05d0cabc2e324177d1d6733b5dc7
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6443da401f83 f5cbed4244ba "bash" 13 seconds ago Up 11 seconds nostalgic_rosalind
[root@localhost ~]# docker commit -a "jlonghe" -m "Hello cnlbogs" 6443da401f83 cnblogs-ubuntu:v1
sha256:d5ffb9a720b2178cbc491768a49794f8bdf4afa9501bf31a7ae21e14b3ee64bb
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
cnblogs-ubuntu v1 d5ffb9a720b2 10 minutes ago 63.2MB
ubuntu 18.04 f5cbed4244ba 13 days ago 63.2MB
从上面的示例中,可以看到,首先以镜像 ubuntu:18.04 为基础,运行了一个ID为6443da401f83的容器,然后再以ID为6443da401f83的容器为基础,通过commit 命令创建了一个名称为 cnblogs-ubuntu 的容器。
2、基于本地模板的导入 可以通过网站 OpenVZ 提供的模板,导入镜像,下载地址:https://download.openvz.org/template/precreated/,在这里,我选择的是 ubuntu 14.04 的模板,下载地址:https://download.openvz.org/template/precreated/ubuntu-14.04-x86_64-minimal.tar.gz 首先 在宿主机上创建一个目录(目录换成自己的):
[root@localhost ~]# mkdir home/www/docker-test
[root@localhost ~]# cd /home/www/docker-test
[root@localhost docker-test]# wget https://download.openvz.org/template/precreated/ubuntu-14.04-x86_64-minimal.tar.gz
--2022-04-19 10:42:28-- https://download.openvz.org/template/precreated/ubuntu-14.04-x86_64-minimal.tar.gz
正在解析主机 download.openvz.org (download.openvz.org)... 130.117.225.97
正在连接 download.openvz.org (download.openvz.org)|130.117.225.97|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:78421150 (75M) [application/x-gzip]
正在保存至: “ubuntu-14.04-x86_64-minimal.tar.gz”
100%[=======================================================================================================================================================================================================>] 78,421,150 6.99MB/s 用时 17s
2022-04-19 10:42:46 (4.47 MB/s) - 已保存 “ubuntu-14.04-x86_64-minimal.tar.gz” [78421150/78421150])
[root@localhost docker-test]# ls
ubuntu-14.04-x86_64-minimal.tar.gz
[root@localhost docker-test]# cat ubuntu-14.04-x86_64-minimal.tar.gz | docker import - ubuntu:v14.04
sha256:2ebc9dbb347f5eda5519f81f1d4668a701b2e4a6b7ed18f1c89a4311a65eb95d
[root@localhost docker-test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu v14.04 2ebc9dbb347f 12 seconds ago 215MB
通过上面的操作,可以可看到创建一个 名称 ubuntu:v14.04 的镜像(因为我本地存在 14.04 的镜像,所在这里导入TAG为 v14.04 ,以免冲突),这里需要注意一下 docker import 后面是有一个 "-" 字符的。
3、基于Dockerfile文件的创建
基于Dockerfile创建是很常见的方式,Dockerfile是一个文本文本,没有后缀名,利用编写的指令描述基于父镜创建新镜像的过程。下面的示例为基于debian:stretch-slim镜像安装Python3环境,构建一个新的python:3镜像:
在宿主机上指定的一个目录下,创建 Dockerfile 文件,编辑 Dockerfile文件的内容如下:
FROM debian:stretch-slim
LABEL version="1.0" maintainer="jlonghe<jlonghe@mail.com>"
RUN apt-get update && apt-get install -y python3 && apt-get clean && rm -rf /var/lib/apt/lists/*
Dockerfile 中的 maintainer 的值,不要有空格,否则可能会报错,执行如下命令:
[root@localhost python]# ls
Dockerfile
[root@localhost python]# docker build -t python:3.0 .
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM debian:stretch-slim
---> 431201ea8a27
Step 2/3 : LABEL version="1.0" maintainer="jlonghe<jlonghe@mail.com>"
---> Using cache
---> b9a89b4bbe71
Step 3/3 : RUN apt-get update && apt-get install -y python3 && apt-get clean && rm -rf /var/lib/apt/lists/*
---> Using cache
---> b8da5b2aa3b4
Successfully built b8da5b2aa3b4
Successfully tagged python:3.0
[root@localhost python]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
python 3.0 b8da5b2aa3b4 1 minutes ago 95.3MB
这里需要注意的是 docker build -t python:3.0 . 命令后尾是有一个 点 的。
保存和载入镜像:save 和 load 命令
save 命令。对于镜像,我们可以通过保存镜像的方式导出指定的镜像,命令的格式为:docker [image] save 。该命令支持的参数有:
-o、 -output string:导出镜像到指定的文件中。示例如下:
[root@localhost docker-test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu v14.04 2ebc9dbb347f About an hour ago 215MB
cnblogs-ubuntu v1 d5ffb9a720b2 2 hours ago 63.2MB
[root@localhost docker-test]# ls
[root@localhost docker-test]# docker save -o ubuntu_14.04.tar 2ebc9dbb347f
[root@localhost docker-test]# ls
ubuntu_14.04.tar
load 命令。可以使用load命令,将导出的tar文件再导入到本地的镜像库中,命令格式为:docker [image] load 。
支持参数有:-i、 -input string 选项,从指定文件中载入镜像库。示例如下:
[root@localhost docker-test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu v14.04 2ebc9dbb347f 3 hours ago 215MB
[root@localhost docker-test]# ls
ubuntu_14.04.tar
[root@localhost docker-test]# docker load < ubuntu_14.04.tar
Loaded image ID: sha256:2ebc9dbb347f5eda5519f81f1d4668a701b2e4a6b7ed18f1c89a4311a65eb95d
[root@localhost docker-test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu v14.04 2ebc9dbb347f 3 hours ago 215MB
从上面的执行结果来看,当本地的镜像存在同一版本镜像时,虽然docker提示载入成功,但细心查看,输出的镜像ID,实际是与前面的镜像ID一致的,而且没有载入的进度提示,因此镜像并不会多次载入重。我们可以尝试把原来的镜像删除后,再载入,输出的信息,将会有所区别。
[root@localhost docker-test]# docker rmi 2ebc9dbb347f
Untagged: ubuntu:v14.04
Deleted: sha256:2ebc9dbb347f5eda5519f81f1d4668a701b2e4a6b7ed18f1c89a4311a65eb95d
Deleted: sha256:fd58c1324b91bf2a58fa7267ac56de93048f689454d0530cc17ac8b9cbb7ab9d
[root@localhost docker-test]# docker load < ubuntu_14.04.tar
fd58c1324b91: Loading layer [==================================================>] 225.8MB/225.8MB
Loaded image ID: sha256:2ebc9dbb347f5eda5519f81f1d4668a701b2e4a6b7ed18f1c89a4311a65eb95d
上传镜像:push命令
接下来我们学习push命令,这个命令可以使我们在本地的镜像上传到Docker Hub的官方仓库。
在操作之前,我们要在Docker 官方网站注册一个账号,注册地址:https://hub.docker.com/ ,注册完成后,我们可以通过注册的账号在控制台上登录,然后再能上传镜像到我们在Docker官网的账号下。
登录的命令的格式如下:docker login -u USERNAME -p PASSWORD 。
对于本地的镜像,在push之前,通常我们需要更改镜像的名称,例如,例如本机存在一个名称为 ubuntu TAG 为 18.04 的镜像,那么我们需要将名称更改为 [USERNAME]/ubuntu:18.04,这样子,才能在push的时候,上传到Docker对应的用户仓库下,示例如下:
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 f5cbed4244ba 13 days ago 63.2MB
[root@localhost ~]# docker tag ubuntu:18.04 jlonghe/ubuntu:18.04
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 825d55fb6340 13 days ago 72.8MB
jlonghe/ubuntu 18.04 f5cbed4244ba 13 days ago 63.2MB
ubuntu 18.04 f5cbed4244ba 13 days ago 63.2MB
[root@localhost ~]# docker push jlonghe/ubuntu:18.04
The push refers to repository [docker.io/jlonghe/ubuntu]
95c443da13bf: Mounted from library/ubuntu
18.04: digest: sha256:512274f1739676880585e70eea6a883db7b6d92841b02647b6c92b478356572c size: 529
上传成功后,在Docker Hub 会有对应的镜像记录,如下图所示:
感谢您能看到这里,在下一篇 Docker学习笔记之容器的操作(1),我们将学习Docker的相关操作。