容器镜像管理命令
1. 创建实验资源
开始实验之前,您需要先创建ECS实例资源。
- 在体验实验室,单击创建资源。
- (可选)在实验室⻚⾯左侧导航栏中,单击云产品资源列表,可查看本次实验资源相关信息(例如IP地址、⽤户信息等)。
说明:资源创建过程需要1~3分钟。
2. 镜像的下载,显示和删除
在docker中镜像保存了容器创建时的基础文件内容和相关的配置信息,镜像一旦创建其中的文件就不可修改了。用户在通过镜像启动容器之后所有对文件的操作,都保存在容器对象当中而不会影响原有的容器镜像。接下来我们来讲解镜像相关的命令。
- 实验资源准备
通过之前实验的学习我们已经了解到,通过docker pull可以实现镜像的下载,通过docker images可以显示。此处我们下载一个新的镜像debian来进行测试相关的操作。
docker pull debian docker images
- 镜像的查看
对于已经保存在本地的镜像,我们可以使用docker inspect命令来查看镜像的详细信息,其用法为docker inspect 镜像名,接下来我们来查看debian镜像的属性。会发现docker inspect命令会输出大量JSON格式的镜像详细信息。
docker inspect debian
- 镜像的删除
当镜像下载之后,我们可以通过docker rmi命令进行删除。
docker run -itd --name debian-3 debian docker rm -f debian-3 docker images
要注意的是docker rmi无法删除已经创建了容器的镜像,如果需要删除需要先停止相关的容器,并添加--force参数。接下来我们再来测试通过镜像创建容器,然后在删除容器之后删除debian镜像。
docker rmi --force debian docker images
3. 镜像的保存和加载
一般情况下我们可以通过docker pull的方式通过镜像仓库将镜像下载到本地docker内部。但是这种方法需要保证docker宿主机可以访问到外网且访问速度有保证。如果用户在网络条件不好的情况下希望获取镜像,则可以将镜像的保存到本地文件,然后通过文件复制到容器宿主机上加载方式获得镜像。本小节将为大家介绍这种方法。
- 镜像的本地保存
首先我们可以通过docker save命令可以将docker内部的一个或多个镜像导出成文件。下面的命令中我们先下载nginx,hello-world两个镜像,然后再将镜像导出到images.tar文件中。docker save的格式为:docker save -o [导出文件名] [需要导出的镜像列表]...
docker pull hello-world docker pull nginx docker save -o images.tar nginx hello-world ll images.tar
- 删除已有镜像
上一步已经将nginx,hello-world两个镜像保存到文件images.tar。接下面我们将现有的两个镜像从docker内部删除。为后面的镜像读取做准备。
docker rmi hello-world docker rmi nginx docker images
- 从本地加载镜像文件
接下来我们通过docker load命令将images.tar中的两个镜像导入回docker内部。即可实现在没有网络访问的情况更新镜像。docker load的格式为:docker load -i [导入文件名]。要注意的是:如果docker内部已经存在了相关的镜像,文件中的镜像会被忽略。
在镜像导入完毕之后,我们可以通过docker image进行验证。
docker load -i images.tar docker images
4. 容器快照的导出和导入
上一个小节我们学习了通过docker save和 docker load的方法实现docker内部的镜像保存和加载。在docker中我们除了可以对镜像进行保存和加载,还可以对已经已经创建的容器进行保存和加载。接下来我们就来带领大家学习相关的命令。
- 创建实验容器
首先我们创建一个容器ubuntu-3,然后在ubuntu-3创建一个文本文件。此处我们可以使用docker exec bash -c "命令行" 方式直接在宿主机执行命令。我们通过echo命令在容器中创建名为snapshot.txt的文件。在创建之后再使用cat命令验证容器中的文件。
docker run -itd --name python-1 python docker exec python-1 bash -c "echo snapshot > snapshot.txt" docker exec python-1 bash -c "cat snapshot.txt"
- 容器快照的导出
当容器文件修改之后,我们可以通过docker export命令将容器以快照的形式导出到文件。其命令的格式为docker export 容器名 > 快照文件名。和镜像导出不同,快照的导出,会将容器的镜像,和容器在镜像之上的修改部分同时导出。
docker export python-1 > python-snapshot.tar ll python-snapshot.tar
- 容器快照的导入
对于通过docker export导出的容器快照文件。我们可以通过docker import命令将其导入到docker中,在这里需要特别注意的是:docker import是以镜像而不是容器的形式导入快照。也就是说导入的快照并不能直接运行,而是需要根据此快照镜像再次创建容器才可以使用。docker import命令的格式为docker import 快照文件 导入镜像名称:版本号
docker import python-snapshot.tar python-snapshot:latest
快照导入后,我们可以利用导入的快照镜像创造一个新的容器。并验证通过快照创建的容器中包含着之前容器中创建的文件。
docker run -itd --name snapshot python-snapshot /bin/bash docker exec snapshot cat snapshot.txt
5. 镜像的内部层次关系
镜像是docker中非常重要的资源,因此了解镜像的内部结构对学习docker来说相当重要,事实上docker镜像采用的是多个只读结构层叠的方式进行实现和存储的。本小节我们来学习如何查看镜像的层级关系。
- inspect过滤器的使用
上面的小节我们了解到通过docker inspect命令查看镜像属性,会获得一个非常庞大的JSON格式字符串的详细信息。为了能从字符串中只获得我们需要的内容,我们可以使用-f参数对详细信息进行过滤和格式化。
在使用-f参数时其语法为docker inspect -f "模板字符串" 镜像名,其中模板字符串为go语言的模板语法,在后面的实验中我们会详细讲解。在本次实验中我们要求docker inspect输出JSON格式的结果,为了便于显示,我们在参数后面再加入 | jq,将docker inspect的输出结果交给jq命令进行格式化和美化。
docker pull python docker inspect -f "{\"Id\":{{json .Id}},\"RepoTags\":{{json .RepoTags}}}" python | jq
- 镜像的层次关系
当docker设计镜像底层结构时,为了节约存储控件,会将镜像设计成只读的分层结构。这样每一层只记录和前一层的文件差别。如果两个不同的镜像底层使用了相同的镜像层,则只需要存储一份就可以。这样就大大减小了冗余镜像存储的情况。
通过docker inspect命令我们同样可以查看镜像的层次信息。通过在镜像信息的.RootFS.Layers位置,保存的就是镜像的层次信息。通过下面的命令,我们发现,python镜像中包含了9层。
docker inspect -f "{{json .RootFS.Layers}}" python | jq
- 普通镜像和快照镜像的区别
接下来我们来查看普通镜像和快照镜像直接的层次区别,通过观察我们可以发现,通过docker import导入的镜像快照。会将所有的层压缩成一层。
docker inspect -f "{{json .RootFS.Layers}}" python-snapshot | jq
同时我们通过docker images和ls -ll命令我们可以看到快照镜像,快照镜像虽然体积较大,有比较多的冗余内容,但是不会依赖其他的镜像;因此比较适合导出到文件和导入的操作。
docker images | grep python-snapshot ls -ll | grep python-snapshot.tar
实验链接:https://developer.aliyun.com/adc/scenario/f2e67c3c92e6444aaf8797740aa38490