如何构建更小的容器

2021-05-13 09:07:03如果你开发容器,你有想过减小镜像的大小吗?较小的镜像有一些好处。这篇文章将会提供一些减小容器镜像大小的技巧。
使用容器工作是很多用户和开发者的日常任务。容器开发者经常需要频繁地(重新)构建容器镜像。如果你开发容器,你有想过减小镜像的大小吗?较小的镜像有一些好处。在下载的时候所需要的带宽更少,而且在云环境中运行的时候也可以节省开销。而且在 Fedora CoreOS、IoT 以及Silverblue 上使用较小的容器镜像可以提升整体系统性能,因为这些操作系统严重依赖于容器工作流。这篇文章将会提供一些减小容器镜像大小的技巧。
工具
以下例子所用到的主机操作系统是 Fedora Linux 33。例子使用 Podman 3.1.0 和Buildah 1.2.0。Podman 和 Buildah 已经预装在大多数 Fedora Linux 变种中。如果你没有安装 Podman 和 Buildah,可以用下边的命令安装:
任务
从一个基础的例子开始。构建一个满足以下需求的 web 容器:
下边的步骤也适用于比较复杂的镜像。
设置
首先,创建一个工程目录。这个目录将会包含你的网站和容器文件:
制作一个简单的登录页面。对于这个演示,你可以将下面的 HTML 复制到 index.html 文件中。
此时你可以选择在浏览器中测试上面的 index.html 文件:
最后,创建一个容器文件。这个文件可以命名为 Dockerfile 或者 containerfile:
现在你应该有了一个工程目录,并且该目录中的文件系统布局如下:
构建
现在构建镜像。下边的每个阶段都会添加一层改进来帮助减小镜像的大小。你最终会得到一系列镜像,但只有一个 Containerfile。
阶段 0:一个基本的容器镜像
你的新镜像将会非常简单,它只包含强制性步骤。在 Containerfile 中添加以下内容:
在上边的文件中有一些注释来解释每一行内容都是在做什么。更详细的步骤:
运行下边的命令从工程目录创建一个新的镜像:
使用一下命令来查看你的镜像的属性。注意你的镜像的大小(467 MB)。
以上这个例子中展示的镜像在现在占用了467 MB的空间。剩下的阶段将会显著地减小镜像的大小。但是首先要验证镜像是否能够按照预期工作。
输入以下命令来启动容器:
输入以下命令可以列出你的容器:
以上展示的容器正在运行,它正在监听的端口是 46191 。从运行在主机操作系统上的 web 浏览器转到 localhost:46191 应该呈现你的 web 页面:
阶段 1:清除缓存并将残余的内容从容器中删除
为了优化容器镜像的大小,第一步应该总是执行“清理”。这将保证安装和打包所残余的内容都被删掉。这个过程到底需要什么取决于你的容器。对于以上的例子,只需要编辑 Containerfile 让它包含以下几行。
构建修改后的 Containerfile 来显著地减小镜像(这个例子中是 237 MB)。
阶段 2:删除文档和不需要的依赖包
许多包在安装时会被建议拉下来,包含一些弱依赖和文档。这些在容器中通常是不需要的,可以删除。 dnf 命令有选项可以表明它不需要包含弱依赖或文档。
再次编辑 Containerfile ,并在 dnf install 行中添加删除文档和弱依赖的选项:
构建经过以上修改后的 Containerfile 可以得到一个更小的镜像(231 MB)。
阶段 3:使用更小的容器基镜像
前面的阶段结合起来,使得示例镜像的大小减少了一半。但是仍然还有一些途径来进一步减小镜像的大小。这个基镜像 registry.fedoraproject.org/fedora:33 是通用的。它提供了一组软件包,许多人希望这些软件包预先安装在他们的 Fedora Linux 容器中。但是,通用的 Fedora Linux 基镜像中提供的包通常必须要的更多。Fedora 项目也为那些希望只从基本包开始,然后只添加所需内容来实现较小总镜像大小的用户提供了一个 fedora-Minimal 镜像。
使用 podman image search 来查找 fedora-minimal 镜像,如下所示:
fedora-minimal 基镜像不包含 DNF,而是倾向于使用不需要 Python 的较小的 microDNF。
当 registry.fedoraproject.org/fedora:33 被 registry.fedoraproject.org/fedora-minimal:33 替换后,需要用 microdnf 命令来替换 dnf。
使用 fedora-minimal 重新构建后的镜像大小如下所示 (169 MB):
最开始的镜像大小是 467 MB。结合以上每个阶段所提到的方法,进行重新构建之后可以得到最终大小为 169 MB 的镜像。最终的 总 镜像大小比最开始的 基 镜像小了 182 MB!
从零开始构建容器
前边的内容使用一个容器文件和 Podman 来构建一个新的镜像。还有最后一个方法要展示——使用 Buildah 来从头构建一个容器。Podman 使用与 Buildah 相同的库来构建容器。但是 Buildah 被认为是一个纯构建工具。Podman 被设计来是为了代替 Docker 的。
使用 Buildah 从头构建的容器是空的——它里边什么都 没有 。所有的东西都需要安装或者从容器外复制。幸运地是,使用 Buildah 相当简单。下边是一个从头开始构建镜像的小的 Bash 脚本。除了运行这个脚本,你也可以在终端逐条地运行脚本中的命令,来更好的理解每一步都是做什么的。
或者,可以通过将上面的脚本传递给 Buildah 来构建镜像。注意不需要 root 权限。
最后的镜像只有 155 MB!而且 攻击面 也减少了。甚至在最后的镜像中都没有安装 DNF(或者 microDNF)。
结论
构建一个比较小的容器镜像有许多优点。减少所需要的带宽、磁盘占用以及攻击面,都会得到更好的镜像。只用很少的更改来减小镜像的大小很简单。许多更改都可以在不改变结果镜像的功能下完成。
只保存所需的二进制文件和配置文件来构建非常小的镜像也是可能的。
JAVA怎么创建一个容器
新建容器:Panel pan=new Panel();容器创建好后,要把它放在Frame里。 即Frame fr=new Frame();(pan);(true);我所说的是建立JFrame后会自动包含一个容器。
利用Busybox如何构建一个最小的Linux系统
同问。 。 。
add 与 load 控件数组与容器的问题
先用load加载控件数组,,然后用API函数setparent指定容器。 一、声明:Private Declare Function SetParent Lib user32 Alias SetParent (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long二、用法举例:SetParent a(2), 把控件数组a(2)放入容器Picture1中。
发表评论