大家都喜欢Alpine镜子,因为它很轻,攻击面更小,但也许它们不再是最好的选择。现在是时候再次讨论distroless镜像了。在SumUp,我们经常使用Kubernetes和Docker镜像,因此我们一直在寻找基础镜像的最佳选择。Distroless图像并不是什么新鲜事,但出于某种原因,我觉得它们没有得到应有的采用。什么是distroless镜像?我不得不说这不是什么新鲜事,我是认真的。它已经存在多年,您可以在以下位置查看GoogleContainerTools/distroless:“distrolessdistroless”仅包含您的应用程序及其运行时依赖项。它们不包括包管理器、shell或您希望在标准Linux发行版中找到的任何其他程序。这足以理解你的容器除了你正在使用的东西之外什么都没有。我为什么要使用它们?现在每个人都有CI和CD管道,但有时构建、推送和拉取图像需要很长时间。无释放图像更轻,这意味着拉动和推动更快。Distroless镜像不一定会使您的构建步骤更快,但它们会缩短拉取和推送时间。Docker提供了一个最小层,当您将其用作图像的基础时不会创建额外的层。更少的层等于更快的下载和上传。更快的管道意味着对开发人员的反馈更快,花费的CI时间更少,这在您使用.NET等工具时非常重要。安全性也是一个重要问题,因为您应该尽可能减少攻击面。如果您不打算使用sudo或ping之类的工具,则不应在您的容器中设置这些工具。如果您的代码易受攻击,那么您就不太容易受到导致shell的RCE的影响,但RCE仍然会发生。-EricDuran应始终避免使用可帮助恶意行为者收集更多信息或执行权限升级的工具。你应该看看erickduran/docker-distroless-pocREADME。什么时候不该用distroless的场景说distroless什么时候好用,什么时候不该用?如果你想在容器内调试你的应用程序,你可以从安装的shell和一些其他工具中获益,但distroless没有这些工具。显而易见的答案是使用普通镜像进行开发,而将非发布版本用于生产。在开发中使用不同的图像会使开发人员远离真实的生产环境,这并不理想,但在CI管道中创建使用与生产环境相同的环境的测试步骤应该可以解决这个问题。小心这种权衡。举个例子怎么样?存储库GoogleContainerTools/distroless有一个关于如何为Golang工具制作distrolessdistroless镜像的示例。这是一个简单易行的例子,主要是因为Golang生成的二进制文件默认没有运行时依赖。相反,假设我们需要创建一个distroless映像来使用ping二进制文件,因为我们将在我们的一项服务中使用它来检查主机是否健康。这意味着我们需要找到所有运行时依赖项,但我会尽可能简单。我在Ubuntu中运行了ldd命令,它向我们展示了它的依赖关系,所以我开发了以下Dockerfile。另外请注意,并不是每个运行时依赖项都在ldd命令的输出中,我不得不使用其他方法来发现它们。然而,这并不是最明智的解决方案。上面的Docker文件创建了一个5.44MB的图像,我们可以通过使用Alpine而不是Ubuntu来改进它。如果您在Alpine环境中运行相同的ldd命令,您的依赖项也会更少、更轻。它运行良好,仅使用了1.43MB,比Alpine镜像和我们在第一阶段使用Ubuntu构建的镜像少了大约74%的空间。总结标题说你应该停止使用Alpine,但我想我是在告诉你,这只是在正确的情况下做出正确的选择的问题。此外,alpine和scratch将创建惊人的distroless。问题是,为您的应用程序设置distroless仍然是相当手动的,并不像您希望的那样有趣。由于它需要开发人员付出更多的努力,因此它经常被著名的Alpine镜像所取代。我认为这个想法是在生产中以及在进行手动和自动测试时使用distroless。您不想给开发人员施加更多压力来调试您的应用程序。我希望社区给予distroless应有的关注,它会带来更多的改进,比如尽可能自动化图像创建。
