Kubernetes最佳实践 创建小容器



部署到Kubernetes的第一步是将应用程序放置在容器中。在本系列中,我们将研究如何创建一个小的安全容器的图像。
多亏了Docker,创建容器映像从未如此简单。指定基本映像,添加更改并创建容器。



尽管此技术非常适合入门,但默认情况下使用基本图像可能会导致对带有漏洞的大图像进行不安全的工作。

此外,Docker中的大多数映像都使用Debian或Ubuntu作为基础映像,尽管这提供了出色的兼容性和轻松的适应性(Docker文件仅需要两行代码),但是基础映像可以为容器增加数百兆字节的额外负载。例如,Go hello-world应用程序的一个简单的node.js文件大约需要700兆字节,而应用程序本身的大小只有几兆字节。



因此,所有这些额外的负担浪费了数字空间,并为安全系统中的漏洞和错误提供了出色的缓存。因此,让我们看一下减少容器映像大小的两种方法。

第一种是使用基本的小型图像;第二种是使用构建器模式。使用较小的基本映像可能是减小容器大小的最简单方法。最有可能的是,您使用的语言或堆栈提供的原始应用程序映像比默认映像小得多。让我们看一下我们的容器node.js。



默认情况下,在Docker中,基本节点:8个映像的大小为670 MB,而节点:8-alpine的大小仅为65 MB,即小10倍。使用较小的Alpine基本图片将大大减少容器的大小。 Alpine是一种小型轻量级的Linux发行版,在Docker用户中非常流行,因为它与许多应用程序兼容,同时保持了较小的容器尺寸。与标准Docker的“节点”映像不同,“节点:高山”删除了许多实用程序文件和程序,仅保留了足以运行您的应用程序的文件和程序。

要切换到较小的基本映像,只需更新Docker文件即可开始使用新的基本映像:



现在,与旧的onbuild映像不同,您需要将代码复制到容器中并安装所有依赖项。在新的Docker文件中,容器从以下节点开始:alpine image,然后为代码创建目录,使用NPM软件包管理器安装依赖项,最后启动server.js。



通过此更新,容器的大小减小了10倍。如果您的编程语言或堆栈没有缩减基本映像的能力,请使用Alpine Linux。它还将提供完全管理容器内容的功能。使用基本的小型图像是快速创建小型容器的好方法。但是您可以使用“构建器模式”实现更大的缩减。



在解释语言中,源代码首先传递给解释器,然后直接执行。在编译语言中,首先将源代码转换为编译后的代码。但是,编译通常使用运行代码并不需要的工具。这意味着您可以从最终容器中完全删除这些工具。您可以为此使用构建器模式。



该代码在第一个容器中创建并编译。然后,将已编译的代码打包在最终容器中,而无需编译该代码的编译器和工具。让我们跳过此过程。首先,我们将从onbuild映像转移到Alpine Linux。



在新的Docker文件中,容器以golang:alpine映像开头。然后,他为代码创建目录,将其复制到源代码,创建此源代码并启动应用程序。这个容器比onbuild容器小得多,但是它仍然包含我们实际上不需要的编译器和其他Go工具。因此,让我们仅提取已编译的程序并将其放入我们自己的容器中。



您可能会在此Docker文件中发现一些奇怪的东西:它包含两条FROM行。 4行的第一部分看起来与先前的Docker文件完全相同,只是它使用AS关键字来命名此步骤。在下一部分中,将使用新的FROM行来启动新图像,而不是golang:alpine图像,我们将使用Raw alpine作为基础图像。

Raw Alpine Linux没有安装任何SSL证书,这将导致大多数HTTPS API调用失败,因此让我们安装一些CA根证书。

现在最有趣的是:将编译后的代码从第一个容器复制到第二个容器,您只需使用第二部分第五行的COPY命令即可。它只会复制一个应用程序文件,不会影响Go实用工具。新的多阶段Docker文件将包含大小仅为12 MB的容器映像,而原始容器映像为700 MB,这是一个很大的不同!
因此,使用小的基本图像和构建器模式是无需大量工作即可创建更小的容器的好方法。
可能取决于应用程序堆栈,还有其他方法可以减小图像和容器的大小,但是小型容器确实具有可衡量的优势吗?让我们看一下小型容器非常有效的两个方面-性能和安全性。

要评估性能提升,请考虑创建容器,将其插入注册表(推)然后从那里进行检索(拉)的过程的持续时间。您会看到,较小的容器比较大的容器具有不可否认的优势。



Docker将缓存层,因此后续构建将非常快。但是,在许多用于构建和测试容器的CI系统中,不会缓存层,因此可以节省大量时间。如您所见,根据机器的性能,构建大型容器的时间为34到54秒,而使用通过Builder模式减少的容器的时间为23到28秒。对于此类操作,生产率将提高40-50%。因此,只需考虑创建和测试代码的次数即可。

构建容器后,您需要将其映像(推送容器映像)插入容器注册表中,以便在集群中使用Kubernetes。我建议使用Google容器注册表。



使用Google Container Registry(GCR),您只需支付原始存储空间和网络费用,而无需支付额外的容器管理费。它是机密,安全且非常快速的。 GCR使用许多技巧来加快拉动操作。如您所见,根据计算机性能,使用go:onbuild插入Docker容器映像容器映像将花费15到48秒,而使用较小容器进行相同操作将花费14到16秒,对于效率较低的机器,操作速度的优势将提高3次。对于大型计算机,时间大致相同,因为GCR将全局缓存用于通用的图像数据库,也就是说,您根本不需要下载它们。在低功耗计算机中,CPU是一个瓶颈,因此,在这里使用小容器的优势更为明显。

如果您使用GCR,我强烈建议您将Google Container Builder(GCB)用作构建系统的一部分。



如您所见,使用它使您在减少Build + Push操作的持续时间上甚至比在生产机器上获得更好的结果-在这种情况下,将容器构建和发送到主机的过程几乎快了2倍。此外,每天您都可以免费获得120分钟的组装时间,这在大多数情况下可以满足创建容器的需求。

接下来是最重要的性能指标-检索或下载Pull容器的速度。而且,如果您不太在意推送操作所花费的时间,那么拉取过程的持续时间会严重影响系统的整体性能。假设您有一个由三个节点组成的集群,其中一个崩溃。如果使用管理系统(例如Google Kubernetes Engine),它将自动用新的替换空闲节点。但是,这个新节点将完全是空的,您必须将所有容器拖到该节点中才能正常工作。如果拉操作足够长,那么这段时间您的群集将以较低的性能工作。

在许多情况下,可能会发生这种情况:将新节点添加到群集,更新节点,甚至切换到新容器进行部署。因此,最小化拉拔时间成为关键因素。毫无疑问,小容器的下载速度要比大容器快。如果您在Kubernetes集群中使用多个容器,则节省时间可能非常重要。



看一下比较:使用小容器进行拉动操作所需的时间取决于机器的功率,而使用go:onbuild进行相同操作的时间要少4-9倍。使用小型容器的通用基本映像可以大大加快新Kubernetes节点可以部署和上线的时间和速度。

让我们看一下安全性问题。人们认为较小的容器比较大的容器更安全,因为它们的攻击面较小。真的吗? Google容器注册表最有用的功能之一就是能够自动扫描容器中的漏洞。几个月前,我同时创建了onbuild和多阶段容器,所以让我们看看那里是否存在任何漏洞。



结果是惊人的:在一个小容器中仅发现3个中等漏洞,而在一个大容器中仅发现16个严重漏洞和376个其他漏洞。如果查看一个大容器的内容,您会发现大多数安全问题与我们的应用程序无关,但与我们甚至不使用的程序有关。因此,当人们谈论大型攻击面时,它们的意思就是这样。



结论很明显:创建小型容器,因为它们可以为您的系统性能和安全性带来真正的好处。

Kubernetes最佳实践 具有名称空间的Kubernetes组织


一点广告:)


感谢您与我们在一起。你喜欢我们的文章吗?想看更多有趣的资料吗?通过下订单或向您的朋友推荐给开发人员的基于云的VPS,最低价格为4.99美元这是我们为您发明的入门级服务器 独特类似物:关于VPS(KVM)E5-2697 v3(6核)的全部真相10GB DDR4 480GB SSD 1Gbps从$ 19还是如何划分服务器?(RAID1和RAID10提供选件,最多24个内核和最大40GB DDR4)。

阿姆斯特丹的Equinix Tier IV数据中心的戴尔R730xd便宜2倍吗?在荷兰2台Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100电视戴尔R420-2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB-$ 99起!阅读有关如何构建基础设施大厦的信息。使用Dell R730xd E5-2650 v4服务器花费一欧元9000欧元的c类?

All Articles