您还未登录! 登录 | 注册 | 帮助  

您的位置: 首页 > 软件开发专栏 > 云计算 > 正文

构建容器的七大优秀实践

发表于:2020-11-23 作者:佚名 来源:至顶网
虽然容器与Kubernetes正在快速普及,但首先我们需要明确一点——它们并不适合构建所有的应用程序类型。在“可以”与“应该”之间,大家需要建立起明确的区分。举例来说,构建专门在容器当中运行、并使用Kubernetes加以编排的应用程序(也被称为「云原生」开发)就与利用这些技术管理现有单体式应用程序是有着显著区别的。

事实上,对于刚刚迈入容器领域的团队来说,构建专门用于容器及Kubernetes的全新应用程序往往是比较理想的起点。Aqua Security公司战略副总裁Rani Osnat表示,“容器以及编排技术属于用于构建、部署及运行云原生应用程序的重要工具。我个人建议刚刚开始接触容器技术的朋友们使用新的、比较简单的应用程序作为测试用例。”

关于如何运用容器与Kubernetes开发应用,我们请教了Osnat以及其他多位云原生技术专家的观点,整理出以下六项最佳实践。

思考并建立现代架构

正如50年前盖房子的方法和风格,与现代建筑有着显著不同,构建软件也是如此,应当尽可能使用新的工具及方法。

SADA公司CTO Miles Ward说过,“如果您打算构建一款应用,请务必采用现代方式!”Ward还指出,微服务与十二要素方法论(12-factor) 应该成为现代应用程序开发中的核心原则。

Ward提到,尽管微服务与容器技术可以良好协同,但大多数开发场景其实并不硬性需要这种匹配。“微服务也经常与Kubernetes被视为一体,但这绝非必要。单体式开发同样适用,只要保证其既可以作为单体进行部署,又可以作为同一代码库之上的不同端点进行横向扩展即可。”Ward还强调,“十二要素方法论也是如此,它当然是个良好的起点,但却不是什么不可或缺的教条。”

Osnat建议道,“为了最大程度利用容器技术,可以把我们的应用程序设计为微服务架构,确保其中单一容器进行刷新时仍可正常运行。同时,还应该进行结构化设计,以便容器镜像只代表独立发布的单元,从而实现有效的CI/CD机制。”

“现代”开发往往通过多种方式进行定义。如果要为容器及Kubernetes构建应用程序,那么就要选择合适的打包与技术部署选型。下面来看另外两个示例:

  • 将容器镜像定义为可以独立扩展的逻辑单元: 将数据库、日志记录、监控、负载均衡以及用户会话组件实现为容器或者容器组。
  • 考虑使用云原生API:Kubernetes拥有强大的API扩展机制。把其与容器工具相集成,可以立即使用生态系统中的现有解决方案选项,例如命令行实用程序以及身份验证等。

从软件开发的角度来看,“现代”同样是件好事。Harness公司DevOps倡导者Ravi Lachhman表示,“对于大多数现代语言及框架来说,它们最佳的特性就是可以与容器顺畅对接。就在几年之前,像Java这样还很难体现容器边界。如今,随着容器以及Kubernetes等编排工具的流行,语言及框架已经迎来了新的发展范式。”

充分发挥CI/CD与自动化的力量

自动化是容器编排体系中的一大关键特征,也几乎成为构建容器内运行的各类应用程序的核心要素。如果没有自动化,现代应用的运营负担很可能难以承受。

Brillio公司首席架构师Chander Damodaran建议道,“以自动化方式构建应用程序与服务能够显著降低风险水平。随着服务与组件数量的激增,应用及服务运营很可能成为无解的难题。”

精心设计的CI/CD管道会尽可能将自动化引入开发及部署流程中的各个阶段,这也成为当前颇为流行的一股新风潮。我们也可以通过另一种方式理解自动化的价值:它能更轻松地消除错误,特别是早期开发过程中难以避免的种种错误。

Harness公司的Lachhman指出,“使用任何新平台都需要大量的反复试验,而Kubernetes本身并不足以抵消这些试验中的潜在错误。只有建立起稳健的持续交付管道,才能真正打造出可靠、可信的标准,例如测试、安全性与变更管理策略,借此保证应用程序高效运行。”

尽可能保持容器镜像轻量化

容器及Kubernetes开发应用程序时的另一个关键原则——尽可能保证镜像轻量化,借此满足性能、安全性以及其他相关要求。

THoughtWorks公司CTO办公室首席技术专家Ken Mugrage表示,“只保留您绝对需要的东西。镜像中往往包含主体应用程序所不需要的其他程序包。”因此,要移除应用程序当中不必要的所有其他软件包——包括shell实用程序。这不仅能够缩小镜像体积,同时也能减少其攻击面。

CloudBolt公司产品营销负责人Nilesh Deo也赞同了这个观点,“开发人员需要重新考虑自己的应用开发方法。例如创建较小的容器与基础镜像等。镜像越小,加载速度越快,应用程序的运行速度也就越快。”

不要盲目信任镜像

在软件开发当中,我们经常会重用某些现有组件,避免“重复造轮子”。对于容器开发更是如此,不过从安全角度而言,也不能盲目相信镜像,特别应该对其中可能存在的安全缺陷保持警惕。

Mugrage表示,“很多人直接从repo中选择镜像,却没有注意到其中安装有某些应用栈。这些镜像往往质量不高,甚至存在不容忽视的安全问题。我们使用的任何镜像,甚至是自有repo的镜像,都应在部署管道内的每一次运行前接受扫描,检查其漏洞与合规性。”

起步阶段就要计划可观察性、遥测与监控机制

故障,是容器与微服务的一部分,当然,这里更多强调的是故障管理,而非彻底避免故障。Kubernetes的自我修复功能无疑是该其核心吸引力之一,但也要求用户拥有适当的可见性。在这一领域,可观察性、遥测与监控机制就成了最关键的能力。

Sentry.io公司软件工程师Andrei Zbikowski指出,“Kubernetes具有内置弹性机制,符合全面监控方面的最佳实践要求。其自我修复功能可以在某些参数不满足健康要求时,重新启动存在故障的容器、或者终止并替换其他的容器。这项功能虽然可以让应用程序长期保持正常运行,但也掩盖了一些其他的问题。”

Zbikowski补充道,缺乏对代码的可见性,可能导致应用程序随时抛出错误,但管理者却因为运行指标的一切正常而误以为万事大吉,“监控应用程序以及容器/后端系统非常重要。全面的监控方法必须有能力提高问题的广泛可见性,以便在重大影响发生之前,识别并纠正问题。”

Mugrage指出, “在起步阶段,大家就应该考虑到可观察性与监控需求。对分布式应用程序进行故障排查往往极为困难,这方面需求必须被包含在应用程序设计当中。后续添加的监管解决方案,往往效果不佳。”

红帽公司技术专业布道师Gordon Haff表示,“使用多种云原生技术工具方案,可以在应用程序当中建立起复杂的监控、跟踪、服务网格以及仪表板。例如Prometheus、Jaeger、Kiali以及Istio等等都在此列,不过,工具种类繁多,这也让技术选型成为一项挑战。”

考虑从无状态应用程序起步

一般而言,运行无状态应用程序,往往比运行有状态应用程序(例如数据库)要容易得多。随着Kubernetes运营商的增加,情况开始有所不同。不过,对于刚刚上手Kubernetes的团队来说,运行无状态应用程序可能是更好的选择。

Plotly公司联合创始人Chris Parmer指出,“如果只能挑选一条最佳实践的话,我建议从无状态应用程序入手,通过无状态后端,开发团队可以确保没有需要长期运行的连接,或者可变状态,从而极大降低扩展的难度。开发人员还能够在零停机时间的前提下,轻松部署应用程序,确保最终用户的请求可以并行被传递至不同的容器处。”

Parmer指出,可扩展性是在Kubernetes上运行容器的主要优势,而使用无状态应用程序更有利于发挥这项优势。

“无状态应用程序意味着开发团队能够更轻松地迁移及扩展容器以满足组织的业务需求,包括随意添加或删除容器。通过使用基于无状态后端的Web应用程序框架,我们可以从Kubernetes集群当中获取最大收益。”Parmer说。

构建容器化不容易

时至今日,Kubernetes中仍然没有哪种抽象可以让其底层系统变得真正易于理解——或者说,目前的方案只能使其更易于使用。红帽OpenShift首席技术营销经理Chris Short指出,“这当然不容易,否则每个人都能打造出Kubernetes了。我们在进行容器编排的同时,还消除集群状态及底层基础设施的「存在感」,甚至消除了管理方面的需求。Etcd是一个巨大的Kubernetes依赖项,很多厂商都在想办法将其隐藏起来。Kubernetes涉及网络、安全性以及其他一系列复杂内容。只有做好失败的准备,您的团队才能真正迈出探索Kubernetse的脚步,为迎接真正的「现代」架构摆正心态。”