最近公司上线一个临时的项目,因为是临时使用,开发人员也没有想要做一个很标准的镜像,就直接在开发环境的本机进行了镜像的调试,调试完成后直接用docker commit
提交了更改,并且使用docker save
打包了镜像交付。
当在内网生产环境进行部署的时候,由于该项目也没打算直接上Kubernetes,于是就找了一个节点直接在docker上运行,并且在导入镜像的时候鬼使神差就使用了docker import
,于是就掉坑里了。
在执行docker import
过后,系统返回了
sha256:6b67c983aaff3aa4f180467f8d41a599de9b52ca7a2aae131c3d5826c6035afb
看起来似乎是正常导入了,运行docker import
,也能看到导入了新的镜像。
但是一旦运行docker run
去启动容器,就会报错
docker: Error response from daemon: No command specified. See 'docker run --help'.
因为镜像本身的基础镜像是用的CentOS系统,所以直接运行的时候指定最后的运行命令为/bin/bash
进行测试
[root@test01 ~]# docker run -it 6b67c983aaff /bin/bash docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory": unknown.
据开发人员自己的说明,镜像在他开发环境本地是运行良好的,但是因为他本地没有权限访问仓库,才没办法直接push镜像。这时候我们已经在考虑使用公网上面的镜像仓库服务进行曲线救国了,突然发现了了些许问题。
依稀记得docker import
是处理docker export
导出的数据,那么docker save
出来的数据也是这么使用的么,或者说export跟save的区别在哪里呢。
运行docker help save
[root@test01 ~]# docker help save Usage: docker save [OPTIONS] IMAGE [IMAGE...] Save one or more images to a tar archive (streamed to STDOUT by default) Options: -o, --output string Write to a file, instead of STDOUT
然后运行docker help export
[root@test01 ~]# docker help export Usage: docker export [OPTIONS] CONTAINER Export a container's filesystem as a tar archive Options: -o, --output string Write to a file, instead of STDOUT
可以看到,一个是保存镜像到tar archive,一个是导出容器文件系统到tar archive,似乎是破案了。
尝试直接打开研发交付的tar进行查看,可以看到是由很多名称为sha256命名的文件夹构成的一个档案,判断其为save保存出来的镜像档案无误,再回头看看docker help import
[root@test01 ~]# docker help import Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]] Import the contents from a tarball to create a filesystem image Options: -c, --change list Apply Dockerfile instruction to the created image -m, --message string Set commit message for imported image --platform string Set platform if server is multi-platform capable
可以看出来,import是把档案当做一个文件系统进行导入了,似乎跟当前的场景有明显出入。再后头找找docker help
的命令,一个最靓的仔出现在了眼前docker load
,查看其用法
[root@test01 ~]# docker help load Usage: docker load [OPTIONS] Load an image from a tar archive or STDIN Options: -i, --input string Read from tar archive file, instead of STDIN -q, --quiet Suppress the load output
似乎这才是我们所需要的功能吧,立马尝试下,可以看到在进行分层文件系统的依次导入,查看镜像,启动容器一气呵成。
由于平时的镜像交付都是使用dockerfile进行构建,save/load一类的方法用得较少,由此踩坑特意记录一下,说到底还是吃了英语不好的亏啊~