部署容器时要考虑的6个关键因素
容器非常强大,它具有广泛的功能,并且可以轻松地提供应用程序或服务。具有讽刺意味的是,虽然容器的目标是为了简化和提高效率而减少移动部件,但是在幕后有许多复杂的考虑因素,为了从部署中获益,必须考虑这些因素。(注意:这篇关于部署容器时要考虑的六个因素的文章也可以免费下载。)
我与Scott McCarty进行了交谈,他是红帽公司集装箱产品的首席经理,我们进一步讨论了这个话题。
麦卡蒂在《企业空间》一书中也提到了这一点,重要的是要考虑以下六个方面的因素(当然不限于此)
开发人员通常不会从性能角度考虑潜在的问题,但是仅仅因为您可以使用web浏览器访问应用程序并不意味着它将处理大量并发事务。在它真正投入使用之前,您不会知道它处理得有多好。您的应用程序可能“在我的机器上工作”,但在生产环境中,它会以每秒150万次的速度执行事务吗?
Kubernetes可以扩大规模,但这样做也会消耗大量资源。容器可以帮助解决体系结构问题,并确保所有必要的依赖项都存在,但它不会在推出后自动应用性能。
底层语言运行时、web服务器和openssl等库的质量都会影响性能。确保您的Linux发行版有一组积极主动的性能工程师测试回归,更重要的是,调优整个堆栈的性能。
在Linux世界中,不同的程序在一个内核上运行。大多数程序使用syscall层,这是一个与内核交互的API。当您坚持使用Linux中的syscall层时,向前兼容性工作得相当好。
Linux的创始人Linus Torvalds有一条严格的规则,即内核不应该破坏向后兼容性。容器总是向前兼容的,因为syscall层小心翼翼地不破坏这个功能。
但是,如果在旧的内核上运行一个新的容器映像,会发生什么情况呢?或者,当你小心翼翼地走出syscall层,进入ioctl、/dev、/proc等api时,会发生什么?
兼容性存在时间和空间上的限制。良好的设计和测试可以在这方面提供帮助。容器映像和主机的Linux发行版需要深入考虑这些问题,否则用户将陷入崩溃状态。在内核层、编译器层(gcc)和库层(glibc)以及syscall接口之外的api中都是如此。
另一个问题是,如果只使用与C库相关联的syscall函数,可能就不会有问题。然而,更有可能的情况是,你的应用程序会拖进一些辅助软件,而不是像故障诊断或监控元素这样的应用程序的一部分,这些部分使用了其他内核api,如ioctl /proc或/dev,这可能会导致问题。
如果您升级容器主机,它可能不再运行容器。在虚拟机世界中,您通常不必担心(但是,即使使用虚拟化,也要注意一些架构或芯片组可能会导致问题),但是在物理服务器世界中,一些架构或芯片组可能会导致问题。
参见:系统更新政策模板下载(Tech Pro Research)
硬件和软件的生态系统是可支持的,可以映射到底层的Linux发行版。如果你需要手臂支撑,它必须有。考虑一下可支持性——这适用于硬件的容器主机和软件的容器映像。
在选择容器映像和容器主机时,这是一个经常被遗忘的“购买标准”。但是请记住,Linux发行版的软件生态系统(硬件和软件)是容器主机(硬件)和容器映像(软件)可用的生态系统。如果您的Linux发行版支持特定的硬件或云提供商,那么您的容器主机将能够正常运行。在涉及Linux内核的其他事情的生态系统中,已经出现了奇怪的bug。
如果您的应用程序是为特定的Linux发行版设计和构建的,那么将这些应用程序放到基于Linux发行版的容器映像中会容易得多。
参见:混合云:一个备忘单(TechRepublic)
与性能类似,安全性也不是“它可以在我的笔记本上工作”就能解决的问题。一旦容器映像投入生产,它将把您的应用程序及其所有依赖项暴露给internet的所有危险。这包括拒绝服务攻击、数据泄露、木马图像和黑客攻击。在为您的容器环境选择容器映像和容器主机时,需要考虑所有这些因素。
也许您没有从Red Hat容器目录下载容器图像,而是选择从中国的某个可疑站点下载。这是一个非常糟糕的主意。如果你不从一个已知的好容器开始,有人会在里面注入恶意代码,而你是不会知道的。
容器界可以从XCode的Ghost hack中吸取教训——有人在应用程序中插入了一个特洛伊木马,然后把它上传到苹果商店。之前也有一个类似的事件,涉及Docker Hub——500万到1000万的人下载了一个坏容器。
从安全的角度来看,了解组件的质量是至关重要的;永远使用你信任的资源。确定你为什么信任他们——是代码质量,补丁,等等?请记住,一个容器可能在你下载它的那一天就已经很好了,但是三年后呢?
参见:数据中心自动化研究报告2018:尽管数据增长,自动化的采用仍然缓慢(Tech Pro research)
容器会进行很多构建,每次重新构建容器时都要重新编译应用程序(与C和GoLang程序一样)是常见的趋势。您可以静态地编译到二进制文件中,并使用它来运行构建scratch容器——编译二进制文件中需要的所有东西,然后发布。
这使得图像尽可能的小,但这并不方便。现在开发人员负责映像中的一切。一年后,如果某个库中的某个东西破坏了向后兼容性,而容器失败了,谁来修复它?不管是谁,都必须具备开发人员的技能——不能只是运行“yum update”的操作。你可能需要重新编译应用程序。
另一种方法是构建一个基本映像,其中包含一些包,比如使用openssl动态编译的web服务器,可以通过“yum update”来修复性能问题,从而获得新的包。这比更改代码要容易得多,但最终会得到一个更大的映像。
一旦你添加了软件,它的大小就不重要了,它现在是400或500 Mb。
正在开发的容器化应用程序主要有两种类型。那些构建在Linux基础映像上的,以及那些从头开始构建的。
在这两种应用程序样式中,用户通常对容器映像的大小很敏感,因为它影响将容器映像拉到容器主机所需的时间。在从头构建和部署静态编译的二进制文件(在Golang中很常见)时,选择一个小的基本映像或从头构建非常重要。
在构建供企业使用的整个软件生态系统时,更重要的是考虑整个供应链的规模(所有RPM包及其依赖项),因为基础层通常可以共享和缓存。减少攻击面就是通过减少库的副本和语言运行时来减少整个环境中的内存占用。谷歌云平台:内幕指南(TechRepublic下载)
支持主要有两种形式:生命周期和白手套支持。
生命周期是控制时间量的东西,容器映像中的任何给定包(rpm或deb)都可以使用哪些补丁。
白手套支持允许您提交票据,获得热修复程序,并支持上游更改。
两者都非常重要,这取决于您将支持您的容器应用程序的时间(提示:比您想象的要长)。
生命周期支持上下文非常重要,因为您的应用程序的运行时间比您想象的要长。可能是三到五年,或者更长。有很多应用程序/系统的实例,它们已经运行了五年了。您必须考虑运行yum更新所需的基本映像支持时间。然后,您必须返回到第一个模型来进行代码更改、实现不同版本的库并将其交还给开发人员,这样做的成本可能很高。
问问自己:我的容器映像有更新吗?如果什么东西坏了,我可以打电话叫人来修吗?如果我有一个独特的问题,我可以驱动补丁吗?能够归档票据并驱动操作是与仅仅运行“yum update”不同级别的支持。