【问题标题】:Multiple environments (Staging, QA, production, etc) with Kubernetes使用 Kubernetes 的多个环境(暂存、QA、生产等)
【发布时间】:2017-08-29 23:37:51
【问题描述】:

什么被认为是使用 K8S 管理多个环境(QA、Staging、Production、Dev 等)的良好实践?

例如,假设一个团队正在开发一个需要部署一些 API 以及前端应用程序的产品。通常,这将需要至少 2 个环境:

  • 暂存:用于发布给客户端之前的迭代/测试和验证
  • 生产环境:这是客户可以访问的环境。应包含稳定且经过充分测试的功能。

那么,假设团队使用 Kubernetes,托管这些环境的最佳做法是什么?到目前为止,我们已经考虑了两种选择:

  1. 为每个环境使用一个 K8s 集群
  2. 仅使用一个 K8s 集群并将它们保存在不同的命名空间中。

(1) 似乎是最安全的选择,因为它将潜在的人为错误和机器故障的风险降至最低,这可能会使生产环境处于危险之中。然而,这伴随着更多主机的成本以及更多基础设施管理的成本。

(2) 看起来它简化了基础架构和部署管理,因为只有一个集群,但它提出了一些问题,例如:

  • 如何确保人为错误会影响生产环境?
  • 如何确保暂存环境中的高负载不会导致生产环境中的性能损失?

可能还有其他一些问题,因此我正在与 StackOverflow 上的 K8s 社区联系,以更好地了解人们如何应对这些挑战。

【问题讨论】:

  • 你是怎么做到的?请你让我们知道...我也在学习并尝试找出最好的方法。听起来像建立单独的集群可能是正确的方法......
  • 我们最终拥有了两个集群,一个用于暂存,另一个用于生产。从基础架构的角度来看,需要额外的管理,但在我们的例子中,隔离级别是值得的。
  • @YoanisGil 这里有答案可以标记为已接受吗?
  • @tdensmore 大多数答案都以自己的方式很好。问题是,没有一个答案,这取决于所讨论的用例。我认为 K8s 和它的社区自从我第一次提出这个问题(现在差不多 3 年)以来已经成熟了很多,并且似乎至少有一些可以应用的最小最佳实践,无论使用了多少集群以及用于什么目的(我在考虑命名空间、网络策略、节点选择器、seccomp 等)。

标签: kubernetes


【解决方案1】:

多集群注意事项

查看 Vadim Eisenberg (IBM / Istio) 的这篇博文:Checklist: pros and cons of using multiple Kubernetes clusters, and how to distribute workloads between them

我想强调一些优点/缺点:

拥有多个集群的原因

  • 生产/开发/测试分离:尤其适用于测试新版本的 Kubernetes、服务网格、其他集群软件
  • 合规性:根据某些规定,某些应用程序必须在单独的集群/单独的 VPN 中运行
  • 更好的安全隔离
  • 云/本地:在本地服务之间分配负载

拥有单个集群的原因

  • 减少设置、维护和管理开销
  • 提高利用率
  • 降低成本

考虑到一个不太昂贵的环境,平均维护,但仍确保生产应用程序的安全隔离,我建议:

  • 1 个用于 DEV 和 STAGING 的集群(由命名空间分隔,甚至可能是隔离的,使用网络策略,如 Calico
  • 1 个用于 PROD 的集群

环境平等

good practice 让开发、登台和生产尽可能相似:

支持服务之间的差异意味着微小的不兼容性 突然出现,导致代码在开发中工作并通过测试,或者 分期生产失败。这些类型的错误会产生摩擦 这会抑制持续部署。

将强大的 CI/CD 工具与 helm 结合使用。您可以使用helm values 的灵活性来设置默认配置,只需覆盖因环境而异的配置。

GitLab CI/CD with AutoDevops 与 Kubernetes 有强大的集成,让您可以管理多个 Kubernetes 集群,并提供 helm 支持。

Managing multiple clusters kubectl 交互)

当您使用多个 Kubernetes 集群时,很容易 弄乱上下文并在错误的集群中运行kubectl。超过 也就是说,Kubernetes 有 restrictions 用于 客户端(kubectl)和服务器(kubernetes master),所以运行命令 在正确的上下文中并不意味着运行正确的客户端版本。

要克服这个问题:

  • 使用asdf 管理多个kubectl 版本
  • Set the KUBECONFIG env var 在多个 kubeconfig 文件之间切换
  • 使用kube-ps1 跟踪您当前的上下文/命名空间
  • 使用kubectx and kubens 在集群/命名空间之间快速切换
  • 使用别名将它们组合在一起

我有一篇文章举例说明了如何做到这一点:Using different kubectl versions with multiple Kubernetes clusters

我还推荐以下阅读:

【讨论】:

  • 是否可以在不使用 Helm 的情况下处理多种配置? kubectl 没有办法编写配置文件(例如覆盖 dev/prod 之间的差异)?
【解决方案2】:

绝对使用单独的集群进行开发和创建 docker 映像,以便您的暂存/生产集群可以安全地锁定。是否为 staging + production 使用单独的集群取决于您根据风险/成本来决定 - 当然,将它们分开将有助于避免 staging 影响 production

我还强烈建议您使用 GitOps 在您的环境之间推广您的应用版本。

为了尽量减少人为错误,我还建议您尽可能多地考虑自动化 CI/CD 和推广。

这里是 a demo of how to automate CI/CD with multiple environments on Kubernetes using GitOps,用于在环境和预览环境之间的 Pull Requests 之间进行升级,尽管 Jenkins X 支持大多数 kubernetes 集群,但它在 GKE 上实时完成

【讨论】:

【解决方案3】:

这取决于您要在每个场景中测试什么。一般来说,我会尽量避免在生产集群上运行测试场景,以避免不必要的副作用(性能影响等)。

如果您打算使用 完全模仿生产系统的暂存系统进行测试,我建议您启动完整集群的精确副本并在完成测试后将其关闭并移动部署到生产。

如果您的目的是测试一个允许测试应用程序部署的暂存系统,我将永久运行一个较小的暂存集群并根据需要更新部署(还有缩减版的部署)用于持续测试。

为了控制不同的集群,我更喜欢有一个单独的 ci/cd 机器,它不是集群的一部分,但用于启动和关闭集群以及执行部署工作、启动测试等。这允许设置并在自动化测试场景中关闭集群。

【讨论】:

【解决方案4】:

很明显,通过将生产集群与暂存集群分开,可以降低潜在错误影响生产服务的风险。然而,这是以更多的基础设施/配置管理为代价的,因为它至少需要:

  • 至少 3 个主集群用于生产集群,至少一个主集群用于暂存集群
  • 要添加到 CI/CD 系统的 2 个 Kubectl 配置文件

我们也不要忘记,环境可能不止一种。例如,我曾在至少有 3 个环境的公司工作过:

  • QA:这是我们进行日常部署的地方,也是我们在发布给客户之前进行内部 QA 的地方)
  • 客户端 QA:这是我们在部署到生产之前进行部署的地方,以便客户端可以在发布到生产之前验证环境)
  • 生产:部署生产服务的地方。

我认为临时/按需集群是有意义的,但仅适用于某些用例(负载/性能测试或非常“大”的集成/端到端测试),但对于更持久/粘性更高的环境,我看到的开销是可以通过在单个集群中运行它们来减少。

我想我想联系 k8s 社区,看看在我所描述的这些场景中使用了哪些模式。

【讨论】:

  • 为什么你需要`至少一个master来做staging one`?你的意思是使用像k3s这样的微型kubernetes吗?我支持你
【解决方案5】:

除非合规性或其他要求另有规定,否则我倾向于为所有环境使用一个集群。使用这种方法,注意点是:

  • 确保您还使用标签对每个环境的节点进行分组。然后,您可以在资源上使用nodeSelector 以确保它们在特定节点上运行。这将减少(过度)资源消耗在环境之间溢出的可能性。

  • 将您的命名空间视为子网并默认禁止所有出/入流量。见https://kubernetes.io/docs/concepts/services-networking/network-policies/

  • 制定管理服务帐户的策略。 ClusterRoleBindings 意味着如果一个集群托管多个环境,则会有所不同。

  • 在使用 Helm 等工具时进行审查。一些图表公然安装具有集群范围权限的服务帐户,但服务帐户的权限应仅限于它们所在的环境。

【讨论】:

  • 如何规划​​集群升级失败?
【解决方案6】:

使用多个集群是常态,至少可以在生产和“非生产”之间强制分离。

本着这种精神,请注意GitLab 13.2 (July 2020) 现在包括:

Core 中的多个 Kubernetes 集群部署

使用 GitLab 部署多个 Kubernetes 集群和 GitLab 以前需要高级许可证。
我们的社区发声,我们倾听:部署到多个集群甚至对个人贡献者也很有用。
根据您的反馈,从 GitLab 13.2 开始,您可以在 Core 中部署到多个组和项目集群。

参见documentationissue

【讨论】:

    【解决方案7】:

    我认为运行单个集群是有意义的,因为它减少了开销和监控。但是,您必须确保设置网络策略和访问控制。

    网络政策 - 禁止 dev/qa 环境工作负载与 prod/staging 商店交互。

    访问控制 - 谁可以使用 ClusterRoles、Roles 等访问不同的环境资源。

    【讨论】:

      【解决方案8】:

      我认为有一个中间点。我正在使用 eks 和节点组。 master 由 aws 管理、扩展和维护。然后您可以创建 3 种节点组(仅作为示例):

      1 - 通用 -> 标签:环境=通用

      2 - Staging -> 标签:environment=staging(如有必要,污点)

      3 - Prod -> 标签:environment=production(如有必要,污点)

      您可以在 pod 上使用容忍度和节点选择器,以便将它们放置在应该在的位置。

      这允许您为生产的节点组使用更健壮或更强大的节点,例如,用于 staging、uat、qa 等的 SPOT 实例......并且有几个很大的好处:

      • 环境在物理上是分开的(实际上也是在命名空间中)
      • 您可以通过共享 master 和一些节点以及两个环境共享的 pod 以及在 staging/uat/...中使用现货或更便宜的实例来降低成本。
      • 没有集群管理开销

      您必须注意角色和政策以确保其安全。您可以使用 eks+calico 等实施网络策略。

      更新:

      我找到了一个在使用 EKS 时可能有用的文档。它有一些关于如何安全运行多租户集群的细节,其中一些细节可能有助于将生产 Pod 和命名空间与暂存的 Pod 和命名空间隔离开来。

      https://aws.github.io/aws-eks-best-practices/security/docs/multitenancy/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-14
        • 1970-01-01
        • 2017-12-17
        • 2017-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多