Kubernetes支持多个环境(Staging、QA、生产等)

使用K8S管理多个环境(QA、登台、生产、开发等)的良好实践是什么?

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

  • 阶段:在发布到客户端之前进行迭代/测试和验证
  • 生产环境:这是客户端可以访问的环境。应该包含稳定且经过良好测试的特性。

因此,假设团队正在使用Kubernetes,那么托管这些环境的良好实践是什么呢?到目前为止,我们已经考虑了两种选择:

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

(1)似乎是最安全的选择,因为它最大限度地减少了潜在的人为错误和机器故障的风险,这可能会使生产环境处于危险之中。然而,这带来了更多主机的成本,以及更多基础设施管理的成本。

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

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

可能还有一些其他的担忧,所以我正在StackOverflow上接触K8s社区,以更好地了解人们是如何应对这类挑战的。

54594 次浏览

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

如果你打算用一个完全模仿生产系统的登台系统进行测试,我建议启动一个完整集群的精确副本,并在你完成测试并将部署转移到生产环境后关闭它。

如果你的目的是测试一个允许测试应用程序部署的登台系统,我会永久地运行一个较小的登台集群,并根据需要更新部署(也有一个缩小版的部署),以进行持续测试。

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

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

  • 生产集群至少有3个主节点,登台集群至少有一个主节点
  • 2需要添加到CI/CD系统的Kubectl配置文件

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

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

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

我想我想接触k8s社区,看看对于我所描述的这种场景使用了什么模式。

一定要使用单独的集群进行开发和创建docker映像,这样您的登台/生产集群就可以锁定安全性。是否为staging + production使用单独的集群取决于你根据风险/成本来决定——当然,保持它们独立将有助于避免staging影响production

我还强烈推荐使用GitOps在不同的环境中推广不同版本的应用程序。

为了尽量减少人为错误,我还建议你尽可能地将CI/CD和晋升自动化。

这里有演示了如何在Kubernetes上使用GitOps自动化多个环境的CI/CD用于在Pull Requests上的环境和预览环境之间的提升,这是在GKE上实时完成的,尽管Jenkins X支持大多数kubernetes集群

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

网络策略——禁止开发/qa环境工作负载与prod/staging存储交互。

访问控制——谁可以使用clusterrole、role等访问不同的环境资源。

除非遵从性或其他需求另有规定,否则我倾向于对所有环境使用单个集群。采用这种方法,注意事项如下:

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

  • 将名称空间视为子网,默认情况下禁止所有出口/入口流量。参见

    多集群注意事项

    看看Vadim Eisenberg (IBM / Istio)的这篇博客文章:清单:使用多个Kubernetes集群的优缺点,以及如何在它们之间分配工作负载

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

    使用多个集群的原因

    • 生产/开发/测试分离:特别适用于测试Kubernetes的新版本、服务网格或其他集群软件
    • 遵从性:根据一些规定,一些应用程序必须运行在单独的集群/单独的vpn中
    • 更好的安全性隔离
    • Cloud/on-prem:在内部服务之间分配负载

    使用单个集群的原因

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

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

    • 1个用于DEV和登台的集群(由名称空间分隔,甚至可以隔离,使用网络策略,如Calico)
    • 1个集群用于PROD

    环境平价

    它是一个良好的实践来保持开发、分期和生产尽可能相似:

    后台服务之间的差异意味着微小的不兼容性 突然出现,导致代码在开发中工作并通过测试或 在生产中登台失败。这些类型的错误会产生摩擦

    结合一个强大的CI/CD工具与helm。你可以使用执掌值的灵活性来设置默认配置,只是覆盖不同环境的配置。

    GitLab CI/CD与AutoDevops有一个强大的集成与Kubernetes,它允许你管理多个Kubernetes集群已经helm支持。

    管理多个集群 (kubectl交互)

    当您使用多个Kubernetes集群时,很容易 弄乱上下文并在错误的集群中运行kubectl。除了 也就是说,Kubernetes有限制的版本不匹配 客户端(kubectl)和服务器(kubernetes master),因此运行命令

    .在正确的上下文中并不意味着运行正确的客户端版本

    要克服这个问题:

    • 使用asdf来管理多个kubectl版本
    • 设置KUBECONFIG env var在多个kubeconfig文件之间进行更改
    • 使用kube-ps1来跟踪当前的上下文/命名空间
    • 使用__ABC0和kubens在集群/命名空间之间快速更改
    • 使用别名将它们组合在一起

    我有一篇文章举例说明了如何实现这一点:使用多个Kubernetes集群的不同kubectl版本

    我还推荐以下内容:

使用多个集群是一种规范,至少可以强制在生产和“非生产”之间进行强有力的分离。

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

Core中部署多个Kubernetes集群

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

https://about.gitlab.com/images/13_2/MultipleProjectClusters.png

参见文档问题

我认为有一个中间点。我正在使用eks和节点组。主服务器由aws管理、扩展和维护。然后你可以创建3种类型的节点组(只是一个例子):

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

2 -分期->标签:environment=staging(如有必要,可以添加污点)

3 - Prod ->标签:环境=生产(如有必要可进行污染)

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

这允许您为生产的节点组使用更健壮或更强大的节点,例如,用于登台、uat、qa等的SPOT实例……它有几个很大的优点:

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

您必须注意角色和策略以确保其安全。您可以使用例如eks+calico来实现网络策略。

更新:

我找到了一个在使用EKS时可能有用的文档。它提供了一些关于如何安全运行多租户集群的详细信息,其中一些详细信息可能有助于将生产pod和名称空间与登台中的名称空间隔离开来。

< a href = " https://aws.github。Io /aws-eks-best-practices/security/docs/multitenancy/" rel="nofollow noreferrer">https://aws.github.io/aws-eks-best-practices/security/docs/multitenancy/ .

这里有一些想法:

  1. 不要相信名称空间可以保护集群免受灾难。拥有独立的生产和非生产(开发,阶段,测试等)集群是最低的必要要求。吵闹的邻居是众所周知的。

  2. 代码和k8s部署的独立存储库(Helm, Kustomize等)将使像基于主干的开发和特征标记这样的最佳实践随着团队的扩展而变得更容易。

  3. 使用环境即服务(EaaS)将允许每个PR在其自己的短期(短暂)环境中进行测试。每个环境都是产品的高保真副本(包括自定义基础设施,如数据库、桶、dns等),因此开发人员可以在一个值得信赖的环境(而不是minikube)上远程编码。这可以帮助减少配置漂移,改进发布周期,并改善整体开发体验。(免责声明:我在一家EaaS公司工作)。