生产环境容器落地最佳实践 - JFrog 内部 K8s 落地旅程



引言


Kubernetes 已经成为市场上事实上领先的编配工具,不仅对技术公司如此,对所有公司都是如此,因为它允许您快速且可预测地部署应用程序、动态地伸缩应用程序、无缝地推出新特性,同时有效地利用硬件资源。

 

本期我们将回顾采用 Kubernetes 作为容器编排工具的公司所面临的复杂性和挑战。我们希望我们提供的经验教训、最佳实践和技巧将帮助您在前往 K8s 旅途中起步并继续前进。

 

本期将介绍关于在 Kubernetes 生产环境的最佳实践,包括:

  • 为上 K8s 容器云准备好应用程序

  • 在 Kubernetes 中获得灵活性和通用性

  • 为所有应用程序使用单一、可信和可靠的源

  • 自动部署到 Kubernetes

  • 在 Kubernetes 中构建可靠且可伸缩的环境

  • 可见性和安全性:在 Kubernetes 中保护您的应用程序

  • 在 Kubernetes 中记录、监视和调试您的微服务

  • 将应用程序部署到 Kubernetes 的生产环境中



背景


JFrog 与 Kubernetes 的旅程始于我们寻找一个合适的容器编排解决方案,以便为内部目的创建一个功能齐全的环境。我们的开发人员需要测试我们非常复杂的环境,包括 JFrog Artifactory 和其他产品。与此同时,我们需要为程序和产品经理提供一个完整的功能环境,以便向我们的客户演示平台。

 

为了满足我们的需求,每个产品都需要一个独立的 CI/CD 开发环境,以便在测试各个分支之间的交互时独立地测试各个分支。

 

随着我们对 Kubernetes 越来越有信心,我们认识到将 JFrog 产品分发到 Kubernetes 的价值,能够跨不同的阶段、开发和生产环境运行应用程序。Kubernetes 还允许我们更好地利用我们的资源,因为我们不再需要为单独部署每个产品而启动单个 VM。下面我们将回顾落地过程中的主要挑战(6大挑战),同时分享我们的最佳实践、技巧,和在将您的容器应用程序一路带到生产环境中所获得的经验教训。



   

Kubernetes 介绍


Kubernetes 允许您创建容器化的应用程序,并将它们并行的部署,而不必担心各种服务和组件之间的兼容性。将应用程序容器化运行在 Kubernetes 中的好处是,您可以在一个充满活力的社区中开发产品,从而更容易创建可伸缩的微服务应用程序。这样做的缺点是,当整个团队都在处理各种组件时,情况会很快变得非常复杂。此外,容器化的应用程序可以包含多种组件类型,这取决于您使用的操作系统、语言和框架。

 

让我们从使用 Kubernetes 运行应用程序所需的三个基本组件开始:


  • 容器云集群

    Kubernetes 集群是您的容器化应用程序运行的编排基础设施。您需要决定是否要自己管理它,以及是否要使用云提供商托管它。此组件不在文档的此范围内讨论。


  • CI/CD 流水线

    CI/CD 流水线在 Kubernetes 中运行,并使流程自动化,从源代码和外部依赖包开始,一直到将应用程序部署到 Kubernetes 集群中。Kubernetes 流水线是“应用程序感知的”(面向应用),这意味着它们天生能够动态地提供一个完整的容器化应用程序堆栈(通常由多个 service、deployments, replica sets, secrets, configmap 等组成)。对应用程序上下文的每次更改,无论是代码、、镜像还是配置更改,都将触发流水线。


  • Kubernetes Registry

    您的生产集群应该使用一个单独的、受管理的和可信的真实源,该源存储和记录应用程序和其依赖组件。使用 Kubernetes Registry,您可以在一个 pod 中并行运行多个应用程序堆栈,而不产生冲突,也不需要关心每个应用程序的内部依赖关系。这将维护正在运行的集群、向上和向下扩容应用程序、开发新版本和调试应用程序具体问题分隔开来。



上 K8s 容器云前准备好你的应用程序


应用程序是服务/解决方案的核心。在 Kubernetes 中运行应用程序之前,需要计划和准备应用程序。


问卷清单:为 K8S 准备应用程序

下表显示了在准备 Kubernetes 应用程序之前必须询问的与应用程序相关的任务和问题。



有关将构建软件的基础知识,请参见软件12因素。https://12factor.net/



在 Kubernetes 中获得灵活性和通用性


多语言编程和多种不同的工具和技术提供了多种可能性。您可以选择最适合您的业务需求的技术,但是每种技术可能有不同的接口、REST API和自己的包格式。支持这些工具的唯一方法是做到在制品从创建到部署的生命周期的管理中实现通用。

 

部署 Artifactory 作为您的 Kubernetes Registry


通过使用 Artifactory 作为“Kubernetes Registry”,您可以获得灵活性和通用性,作为可信的单一来源,它允许您深入了解代码到应用集群的过程,同时关联每个应用程序的每一层(layer)。Artifactory 在一个系统中支持超过25种不同的技术栈,具有一个元数据模型、一个升级流和强大的制品依赖关系。

 

Artifactory 允许您将容器化的微服务部署到 Kubernetes 集群,因为它作为一个通用存储库管理平台来满足您的所有 CI/CD 需求,而不管它们在您的组织中何处运行。登记应用程序包后,可以继续传播和执行构建、测试、升级,最后部署到 Kubernetes。为了方便地将 Artifactory (和其他JFrog产品)部署到 Kubernetes,请参考我们在helm hub 中的官方 JFrog Helm Charts(https://hub.helm.sh/charts/jfrog)。




自动化部署到Kubernetes


在 CI/CD 流水线的每个阶段中不需要人工干预的情况下可靠地大规模部署应用程序是的协调的主要原因。但是如何以一种可重复、可靠的方式将代码发布到集群中呢?如何确保只有正确版本的应用程序才能投入生产?

 

为此,我们建议将 Artifactory 部署为存储库管理平台,通过抹平开发和操作之间的差距在CI/CD 流水线中扮演重要角色。


将 Artifactory 部署为 Helm Charts 仓库


Artifactory 原生支持 Helm 存储库,使您能够完全控制 Kubernetes 的部署过程。它提供安全的、私有的、本地的 Helm 存储库,通过细粒度的访问控制在您的组织中共享 Helm Charts。使用远程存储库代理和缓存公共 Helm Charts 资源,并将本地和远程资源聚合到单个虚拟 Helm 存储库下,从而从单个 URL 访问所有 Helm Charts。



K8S 专家建议:

当使用 Artifactory 作为您的 Helm 存储库时,我们建议:

  • 分离您的稳定存储库和开发阶段存储库(基于成熟度)。

  • 在 Charts 中使用 SemVer version 2版本。

  • 定期重新计算索引。

 

在 CI/CD 流水线中部署应用程序的最佳实践 


在 CI/CD 流水线中部署应用程序时,我们建议:


  • 使用相同的 Helm Chart 进行本地、分段、测试和生产,同时每个环境使用不同的Value.yaml 文件。每个 yaml 都需要包含特定的环境配置值。例如:values-stg..yaml,,value-prod.yaml。

  • 在 VCS 源代码管理系统中管理应用自定义值。

  • 默认配置值 value.yaml 应该是针对开发人员或本地的,这样开发人员就可以轻松地在本地使用它。

  • 对依赖项使用外部 charts。使用社区已经完成的工作!

  • 出于安全目的:将您的×××从 Charts 中分离出来,并将它们作为外部 Charts 引用。



升级发布可靠和可伸缩的应用到Kubernetes 环境


在 Kubernetes 集群中并行运行多个应用程序需要建立对工件(Docker 镜像)的持续访问,同时支持零停机的高负载服务。

 

在 Kubernetes 部署 Artifactory 高可用


通过在 Kubernetes 集群中部署 Artifactory HA(高可用),在集群中,您将体验到零宕机服务,如果一个 pod 被回收或崩溃,或者节点意外停机,容器集群将自动调度恢复对应服务的 Pod。

 

在 Kubernetes 部署 Artifactory HA 的好处是:

 

  • 在不影响性能的情况下,支持更高的负载兵法。

  • 提供水平服务器可伸缩性,允许您在组织增长时轻松地增加容量以满足任何负载需求。

  • 支持在没有系统停机的情况下执行大多数维护任务。

  • 通过使用零停机时间替换应用程序的各个实例,可以在实例上安装更新版本,从而支持滚动升级。


在下例中,使用三个节点部署了一个 Artifactory HA 集群:一个主节点和两个成员节点。因为负载均衡只在成员节点上执行。这使得主节点可以自由地处理作业和任务,不会被入站流量中断。



Kubernetes 集群的存储和可伸缩性


Artifactory HA 允许您在 Kubernetes 中突破应用程序的限制,因为它支持大量存储替代方案。有关更多信息,请参见配置文件存储库。

(https://www.jfrog.com/confluence/display/RTF/Configuring+the+Filestore)



可见性和安全性:在 Kubernetes 中保护您的应用程序


像 Docker 和 Kubernetes 这样的云本地技术提供了更大的***面,为恶意数据挖掘、勒索软件和数据盗窃提供了更多潜在的入口点。在 Kubernetes 集群中运行的服务并不是完全独立的,它们可以访问集群中的其他区域。

 

正是出于这个原因,集群的可见性非常重要,尤其是从安全性的角度来看。您需要知道容器中运行的是什么,因为您的应用程序很少包含单个组件,而是包含外部依赖项,如 OS 包、OSS libs 和第三方流程。这就引出了一个不可避免的问题——它们安全吗?它们是否包含安全漏洞?他们是否遵守自由/开源软件许可?


获的 k8s 中容器的可见性


Artifactory 通过提供可审核性来深入了解整个 CI/CD 流程,因为它捕获了整个 CI/CD 流程中产生的大量有价值的元数据。您可以跟踪负责生成 Docker 镜像层的应用层的 CI 作业。它还可以通过允许比较两个构建来显示构建差异,从而很容易地跟踪 Docker 镜像基于哪个层生成的,到哪个构建产生的,从而跟踪到提交。

 

( K8 专家提示:

推荐阅读:每个人都必须遵循9个 Kubernetes 安全最佳实践。

(https://www.cncf.io/blog/2019/01/14/9-kubernetes-security-best-practices-everyone-must-follow/))


扫描和检测容器中的漏洞


JFrog Xray 与 Artifactory 协作,在应用程序生命周期的任何阶段执行二进制软件工件的通用分析。它对容器中的所有层执行递归扫描,并通过扫描和分析工件及其元数据(递归地遍历任何级别的依赖关系)来帮助识别所有层中的漏洞。可以在 Xray 中设置策略,根据 Xray 扫描发现的风险级别限制或阻止容器镜像部署到 Kubernetes。通过这种方式,可以阻止脆弱或不兼容的应用程序运行,或者限制它们在启动时可以做什么。

 

在 K8S 中保护您的开源项目


大多数应用程序严重依赖于包管理器和开源存储库,因此很容易受到来自这些源的恶意或不安全代码的***。作为我们支持和贡献开源社区计划的一部分,JFrog 开发了 KubeXray,这是一个开源项目,它将 Xray 的安全性扩展到 Kubernetes pod 中运行(或即将运行)的应用程序。使用 Xray 通过扫描容器映像生成的元数据,KubeXray 可以对已经部署的内容执行策略。

 

KubeXray 监控您所有的活动 Kubernetes Pod,以帮助您:

  • 捕获当前在所有 Kubernetes Pod 中运行的应用程序中最新的风险或漏洞。

  • 对正在运行的应用程序强制执行当前策略,即使您已经更改了这些策略。

  • 对未被 Xray 扫描且风险未知的正在运行的应用程序执行策略。

 

使用 Helm 2 防止未经授权的访问


Helm 2 包含一个名为“Tiller”的服务器端组件。Tiller 是一个集群内的服务器,它与 Helm客户端交互,并与 Kubernetes API 服务器交互。

 

Tiller  绝对是很酷的,但重要的是要知道有安全问题。这是因为 Helm 客户端负责管理 Charts,而服务器负责管理发布。这带来了很大的风险,因为 Tiller 使用 root 权限运行,有人可能会未经授权访问您的服务器。

 

Rimas Mocevicius 是 JFrog 公司的一名员工,也是 Helm 公司的联合创始人,他提出了一种创新的方法来解决这种情况,即在工作站上或  CI/CD 管道上运行 Helm 和 Tiller,而不将 Tiller 安装到 Kubernetes 集群中。您可以下载并安装无 Tiller 的 Helm v2 插件。

 

使用用 RBAC 管理 Kubernetes


必须将 RBAC(基于角色的访问控制)设置为 Kubernetes 的管理功能,因为它允许您定义哪个用户可以管理集群及其粒度。除了定义可以列出哪些用户和应用程序之外,还可以获取、创建或删除 pods 和其他 Kubernetes 对象。一个好的实践是通过在为应用程序创建的服务帐户中设置 “automountServiceAccountToken: false” 来禁用对 API 的访问。

 

如果没有指定服务帐户,它会自动将相同名称空间中的“默认”服务帐户分配给 pod。我们建议不要使用名称空间附带的默认值。始终为应用程序创建服务帐户,因为它允许您设置应用程序的限制,包括名称空间或集群范围的操作,并完全禁用对 Kubernetes API 的访问。



在 K8S 中记录日志、监视和调试应用程序


微服务的数量随着复杂性的增加而增加,问题是如何跟踪和监视它们,以及应该监视什么。当涉及到微服务时,您需要收集以下数据微服务:

  • 意外事件:例如,在数据库容器中执行的所有权更改

  • 微服务宕机。

  • 不正确的文件选择在生产造成混乱。

  • 不允许使用特定的基本 OS 版本。

 

在 Kubernetes 中应用程序记录日志的最佳实践


应用程序和系统日志对于排除 Kubernetes 集群活动的故障非常重要。

 

在 Kubernetes 中应用程序记录日志时,请遵循以下最佳实践:

  • 限制对日志的直接访问。

  • 在使用 Kubernetes 仪表板(不推荐用于生产环境)时,将仪表板设置为具有访问权限的只读。您可以允许其他成员执行故障排除,但不要完全访问仪表板,因为它可能会对 Kubernetes 集群造成损害。

  • 确保您的日志是实时可访问的,并且可以在稍后的阶段进行分析。

  • 使用 ELK/EFK 技术栈等日志收集工具(ElasticSearch、Logstash/Fluentd和Kibana)收集和索引来自系统和应用程序的所有日志。

  • 考虑将日志保存在单独的集群中,以便在稍后阶段使用日志。如果集群宕机,允许您访问日志

 

持续监控 K8S 中的微服务


持续监视系统和应用程序健康状况非常重要。

 

对于实时监视 Kubernetes 集群和其中运行的应用程序,有许多免费的和商业的解决方案。其中一个流行的解决方案是 Prometheus ,Grafana 的结合,提供实时监控,可以与报警工具相结合。



将应用程序部署到 K8S 生产环境中


在 K8S 顺利开始旅程的10个技巧


1. 对于初学者,我们建议从阅读 Kubernetes 的艰难方式开始!

(https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/README.md)


2. 从小事做起。从示例中学习,从一个小应用程序(nginx)开始,使用现有的演示,并尝试在 Docker 的 Skin Kubernetes 中部署应用程序。


3. 在进入 K8S 之前准备好你的应用程序。

(https://docs.google.com/document/d/1YS_jICIEPZLle7KcpEoLjuKCZ_TkgNzb9LajPU4AhsI/edit#heading=h.81oh8o1kpi75)

 

4. 为使应用程序在 k8s 中运行,设置一个最小的目标。


5. 使用托管的 k8S 来解放您的工作,例如:AKS、ESK 或 GKE,它们为您抽象了许多复杂性。


6. 每个 Pod 有一个主容器。


7. 我们建尝试 GKE 托管管理 Kubernetes。


8. 确定在 Kubernetes 集群内或集群外存储数据库的位置。这一点非常重要,因为您需要在集群崩溃时计划集群恢复。考虑以下:

  •  当 K8S 在 prem 上运行时: 在 Kubernetes 中将现有的数据库作为无状态应用程序使用。

  • 在云上运行 K8S 时:,选择一个如 PostgreSQL 或 MySQL 的 operator ,其知道如何在 Kubernetes 节点宕机时恢复的持久化数据库。

 

9. 部署到容器云时,请将对应集群分开,运行 CI/CD 流水线,以及从外部 CI/CD 流水线部署应用到 Kubernetes 集群。

 

10. 与社区合作



总结


正如本篇文章所描述的,我们展示了 Kubernetes 和 JFrog Artifactory 是如何让您可靠地、可预测地部署应用程序、动态地伸缩应用程序、无缝地推出新特性并有效地利用硬件资源的。

 

本篇文章旨在回顾希望采用 Kubernetes 作为容器编排工具的公司所面临的复杂性和挑战。我们希望我们分享的经验教训、最佳实践和技巧将帮助您在前往 K8s 的旅途中起步并继续前进。




文章作者:刘永强,JFrog 中国解决方案架构师,服务客户有中兴通讯,宜人贷,易保科技,顺丰等等,专注系统架构、软件 CI/CD 及 Devops 领域,曾在 HPE,亿玛等公司任高级工程师,负责过多个互联网平台和移动应用的研发和运维工作。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章