用 doker 发布程序的正确打开方式

2021-02-28 13:02:43 +08:00
 wellhome
下面两种,哪个正确。

1. 每次发布用 DockerFile 打包一份新 image
然后把 image tag latest 发布

2. 在上次打包的 image 基础上 运行 docker commit,产生一个最新 image 。

目前我用方法 1 。每个 image 都是独立的 commit,之间是没父子关系。
我的疑惑是,docker commit 这个机制是不是可以淘汰了。
4534 次点击
所在节点    程序员
30 条回复
jdhao
2021-02-28 13:08:15 +08:00
当然是 dockerfile 的方式,便于知道里面到底装了啥,做了什么操作,docker commit 到最后变成黑箱,你都不知道里面有啥。
去如果只追求能跑就行,用哪种方式都随便
mimzy
2021-02-28 13:09:20 +08:00
Docker 的机制是可以复用之前的层,加快 build 速度减少体积占用,每次都 docker commit 相当于都没法复用了,所以 1 正确。
boris93
2021-02-28 13:42:35 +08:00
1 正确

你要想让镜像之间有父子关系的话,后面构建就 FROM 上一版本镜像,虽然不知道有什么意义
muzuiget
2021-02-28 13:44:32 +08:00
我一向用 1,docker 本来就是可以自动复用之前的层的,但是把改动都写到 dockerfile 了清晰好多。
mimzy
2021-02-28 13:52:59 +08:00
@mimzy #2 我这里之前理解得不对,commit 也可以复用,问题在于这个复用会在上一层原封不动的基础上修改,镜像会越来越臃肿…
dangyuluo
2021-02-28 14:38:04 +08:00
第一步:正确拼写 docker
dangyuluo
2021-02-28 14:39:17 +08:00
在正确掌握拼写的基础上,我们公司使用的是第一种策略
jim9606
2021-02-28 15:05:43 +08:00
2 只适合增量的情况(同版本增加插件和可选依赖),如果是替换(更新依赖、更新程序本体)应该用 1,因为多层 commit 会保留中间层中被删除的部分,空占体积。

虽然直接发布 dockerfile 才是最高效的方式,不过考虑到网络情况很多人不喜欢用。

2 还应该善用多阶段构建来节省最终镜像体积,不要把工具链和中间产物留在镜像里。
fiveelementgid
2021-02-28 15:44:30 +08:00
Docker 写 Dockerfile 叠千层饼比较好(云 docker 玩家路过
xuanbg
2021-02-28 15:52:05 +08:00
1
wellhome
2021-02-28 16:01:43 +08:00
感谢诸位老哥的回答。个人感觉 docker 本身的 commit 的使用场景不多。快速打个系统的补丁。如果是程序发布了话,还是需要每次都是一个干净的 image 。
wellhome
2021-02-28 16:02:15 +08:00
@dangyuluo 批评的对
konakona
2021-02-28 17:05:33 +08:00
肯定不會是 2,你會後悔的。
正確答案是 1 。
JamesMackerel
2021-02-28 17:14:11 +08:00
@wellhome

我觉得楼主的疑问在于,既然我每次发布的时候都不从上一个版本的 docker image commit,那这个命令到底有什么用?

其实在看这个命令有什么用的时候,不应该只从自己面前遇到的这个场景来看。docker commit 的这个设计的目的是增加存储层的复用程度。如果是 docker image 的终端用户(意思是你作出的镜像不会再被别人 FROM 或者 commit 新的东西)可能并没有什么感受,但想象以下的场景:

A 制作了一个最简单最干净的 Ubuntu 镜像
- B 基于上述镜像做了一个 Python runtime 镜像,只要基于该镜像起一个容器就能直接跑 python 脚本
- - C 基于 B 制作了一个 uwsgi 镜像,只要把 wsgi 脚本放进去就能起一个服务
- - D 基于 B 制作了一个安装了一些数据分析软件包的镜像,使用者只要起一个容器就能直接在 Ipython 中进行简单的数据分析操作

这样其实 BCD 都复用了 A,CD 复用了 B 。试想如果没有这个 commit 的功能,这五个镜像就是五份完全独立的文件,由于 BCD 的改动并不多,其实相当于用 4*A 的大小,但是实际上只做了一点(真正)微小的工作。而基于 commit 机制的这些镜像在都保存在 docker registry 时,应该只占用比 A 的大小稍大一点的空间。

这种机制对于社区来说是非常有益的,因为它提供给了镜像制作者一种非常廉价的复用他人已有工作的方式,同时节省了许多存储空间。
Lemeng
2021-02-28 17:16:53 +08:00
我说呢,docker
fannas
2021-02-28 17:25:38 +08:00
个人经验:
正确姿势是第一个,第二层是运行时,第三层 dependency,第四层 config,第五层代码。
jvm 例子:Base+jdk+所有 dependency+logconfig+class code
python 例子:Base + python+dependency (不要远程安装)+ config + code
fannas
2021-02-28 17:26:21 +08:00
哦,java 最简单的方式是 jib
wellhome
2021-02-28 21:06:55 +08:00
@JamesMackerel 受教了。👍
wellhome
2021-02-28 21:08:32 +08:00
@fannas 👍。config 为什么不在 code 后面
fannas
2021-02-28 21:11:53 +08:00
@wellhome 按照修改频率升序排列,只是个人经验哈。因为这样可以更高效的运用已有的层,在建立 image 的时候更好地利用缓存,publish 的时候节省更多带宽与空间。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/756928

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX