事实证明,生成式AI在许多相对基础的用例中已发挥作用,但是当它需要在技术方面给予更多指导时,表现又如何呢?
在推出ChatGPT时,我们也和大家一样想将它给出的答案与常规网络搜索得到的答案进行比较。我们进行实验,询问技术问题并要求它回答具体内容。并非所有的回答都有效或正确,但我们仍非常认可其提供反馈以改进回答的能力。
然后,我们向ChatGPT更具体地询问有关使用 Kubernetes 的建议。它提供了一份在生产中使用Kubernetes的12项最佳实践清单,其中大部分都是正确且相关的。但当被要求将该列表扩展到50项最佳实践时,我们很快就发现,人类仍具有无可取代的价值。
我们如何使用 Kubernetes
JFrog在Kubernetes上运行其整体平台已有六年多的时间,使用的是主流云提供商(包括AWS、Azure和GCP)提供的托管Kubernetes服务。我们在全球30多个地区开展业务,每个地区都有多个Kubernetes集群。在中国,许多公司都在使用Kubernetes和其他AI赋能的解决方案来加强运营并保持市场竞争力。
在JFrog的案例中,Kubernetes主要用于运行工作负载和运行时任务,而非存储。JFrog采用云提供商提供的托管数据库和对象存储服务。Kubernetes基础设施由数千个节点组成,节点数量可根据自动扩展配置进行动态扩展或缩减。
JFrog生产环境包括数十万个Pod (Kubernetes中最小的部署单元)。确切数量会随着Pod的创建或终止而变化;目前,约30万个Pod在我们全球生产环境中运行,因此需要管理的工作负载量巨大。
我们经常发布新的应用程序版本、补丁和错误修复。我们实施一个内置系统来推出这些更新,包括在全面部署前进行适当的金丝雀(Canary)测试,以此保持连续的发布周期,并确保服务的稳定性。
大多数使用过该服务的人都知道,ChatGPT明确给出免责声明,表明其所基于的数据并不完全是最新的。鉴于此,并考虑到上述背景之下的需求,在OpenAI更新其数据和算法之前,关于Kubernetes在生产中的现代化应用,以下十点是ChatGPT无法告知的:
1. 节点划分是门艺术
节点划分涉及在较小的节点(可减少 “爆炸半径”)和较大的节点(可提高应用性能)之间找到平衡。关键在于根据工作负载要求(如CPU或内存优化)来使用不同的节点类型。调整容器资源,使其与节点的CPU与内存比率相匹配,可以优化资源利用率。
也就是说,考虑到每个应用程序或服务的资源消耗模式各不相同,找到每个节点上合适的Pod数量也是一项均衡工作。使用Pod拓扑分布约束或节点反亲和性等技术在节点间分散负载以优化资源使用,有助于适应工作负载强度的变化。对于使用基于Kubernetes的云服务的大型企业,负载均衡和负载分发至关重要。
2. 保护Control Plane的重要性
监控Kubernetes Control Plane至关重要,尤其是在托管Kubernetes服务中。虽然云提供商能提供可靠的控制和均衡,但仍需要了解其局限性。应做好监控和警报,以确保Control Plane以最佳状态运行。Control Plane运行缓慢会严重影响集群行为,包括调度、升级和扩展操作。即使是托管服务,也存在需要考虑的限制。
过度使用托管Control Plane可能会导致灾难性的崩溃。许多人都经历过这种情况,这也时刻提醒如果控制计划没有得到适当的监控和管理,它们就可能会不堪重负。
3. 如何维持应用程序正常运行时间
确定关键服务的优先级可优化应用程序的正常运行时间。Pod优先级和服务质量决定了需要始终运行的高优先级应用程序;了解优先级有助于优化稳定性和性能。
同时,Pod的反亲和性可防止同一服务的多个副本部署在同一节点上。这就避免单点故障,意味着如果一个节点出现问题,其他副本不会受到影响。
还应采用为任务关键型应用程序创建专用节点池的方法。例如,为 init Pod其他重要服务(如 Prometheus)创建单独的节点池,可显著提高服务的稳定性和最终用户体验。
4. 需要制定扩展计划
是否准备好处理双倍部署,以提供必要的容量增长,同时不带来任何负面影响?托管服务中的集群自动扩容功能可提供帮助,但了解集群规模限制也很重要。对我们来说,典型的集群规模约为100个节点;如果达到这一限制,我们就会启动另一个集群,而非勉强现有集群增长。
还应该考虑纵向和横向的应用扩容。关键是要找到适当的平衡点,在不过度消耗的情况下更好地利用资源。一般来说,横向扩容和复制工作负载更可取,但要注意其可能会影响数据库连接和存储。
5.要为失败做好计划
在应用基础架构的各个方面,为故障做规划已成为日常。需要开发能够应对应用程序故障、节点故障和集群故障等不同故障情况的方案。实施高可用性应用程序Pod及Pod反亲和性等策略有助于确保发生故障时的覆盖范围。
每个机构都需要针对集群故障制定详细的灾难恢复计划,并定期进行演练。当从故障中恢复时,受控和渐进的部署有助于避免资源不堪重负。
6. 确保交付流水线安全
软件供应链总是易受错误和恶意行为者的影响。因此需要控制流水线中的每一个步骤,避免在未仔细考虑外部工具和供应商可信度的情况下依赖它们。
为保持对外部资源的控制,需要采取一些措施,例如扫描来自远程资源库的二进制文件,并使用软件成分分析(SCA)解决方案以对其进行验证。团队还应在整体流水线中应用质量和安全关卡,以确保用户和流水线本身具有更高的可信度,从而保障交付软件具有更高的质量。
7. 同时确保运行时间的安全
使用准入控制器来执行规则(例如阻止黑名单版本的部署)有助于确保运行时间的安全。OPA Gatekeeper 等工具有助于执行策略,如只允许受控的容器注册表进行部署。
同时,建议使用基于角色的访问控制来确保对Kubernetes集群的访问安全,其他运行时间保护解决方案可以实时识别和处理风险。命名空间隔离和网络策略有助于阻止横向移动并保护命名空间内的工作负载。可以考虑在隔离节点上运行关键应用程序,以降低容器逃逸场景的风险。
8. 确保环境安全
确保环境安全意味着要假设网络始终会受到攻击。建议采用审计工具来检测群集和基础设施中的可疑活动,以及具有全面可见性和工作负载控制功能的运行时间保护。
同类最佳的工具固然很好,但在出现警报或可疑活动时,还需要一个强大的事件响应团队,并制定明确的操作手册。与灾难恢复类似,应定期进行演习和实践。此外,由于外部视角和客观研究能够提供有价值的见解,许多机构还会利用漏洞赏金,或由外部研究人员尝试入侵系统以发现漏洞。
9. 持续学习
随着系统和流程的发展演进,需要通过收集历史性能数据来评估并采取行动,从而大力开展持续学习。小规模的持续改进很常见;过去相关的内容可能现在已不再相关。
主动监控性能数据有助于发现某项服务中的内存或CPU泄漏,或第三方工具中的性能问题。通过积极评估数据的趋势和异常,能够提高对系统的理解和系统性能。相较于收到实时警报后再进行响应,这种主动监控和评估更具成效。
10.人工操作是最薄弱的环节
在可能的情况下,自动化能够最大限度地减少人工参与,这对于提升安全是一种很好的方法,因为在安全方面,人工操作是最薄弱的环节。建议通过探索一系列可用的自动化解决方案,找到最适合的个性化流程和定义。
GitOps作为在将变更从开发阶段引入生产阶段时的一种的常用方法,为管理配置变更提供众所周知的合约和界面。类似的方法是为不同类型的配置使用多个仓库,尽管开发、登台和生产环境之间应该彼此相似,但至关重要的是其必须明确分离。
展望未来
AI赋能的解决方案有助于降低运营的复杂性,并自动化执行与管理环境、部署和故障排除有关的任务,因此为未来带来希望。即便如此,人类的判断也是不可替代的,对此应始终予以考量。
如今,AI引擎依赖于公共知识,其中可能包含不准确、过时或不相关的信息,最终导致其给出错误的答案或建议。归根结底,运用常识并牢记AI的局限性至关重要。
【 本文作者董任远,JFrog大中华区总经理】