使用K8S管理多个环境(QA、登台、生产、开发等)的良好实践是什么?
例如,假设一个团队正在开发一个产品,该产品需要部署一些api和前端应用程序。通常,这至少需要2个环境:
阶段:在发布到客户端之前进行迭代/测试和验证
生产环境:这是客户端可以访问的环境。应该包含稳定且经过良好测试的特性。
因此,假设团队正在使用Kubernetes,那么托管这些环境的良好实践是什么呢?到目前为止,我们已经考虑了两种选择:
为每个环境使用K8s集群
只使用一个K8s集群,并将它们保存在不同的名称空间中。
(1)似乎是最安全的选择,因为它最大限度地减少了潜在的人为错误和机器故障的风险,这可能会使生产环境处于危险之中。然而,这带来了更多主机的成本,以及更多基础设施管理的成本。
(2)看起来它简化了基础设施和部署管理,因为只有一个集群,但它提出了一些问题,比如:
如何确保人为错误会影响生产环境?
如何确保登台环境中的高负载不会导致生产环境中的性能损失?
可能还有一些其他的担忧,所以我正在StackOverflow上接触K8s社区,以更好地了解人们是如何应对这类挑战的。
多集群注意事项
看看Vadim Eisenberg (IBM / Istio)的这篇博客文章:清单:使用多个Kubernetes集群的优缺点,以及如何在它们之间分配工作负载。
我想强调一些优点和缺点:
使用多个集群的原因
生产/开发/测试分离:特别适用于测试Kubernetes的新版本、服务网格或其他集群软件
遵从性:根据一些规定,一些应用程序必须运行在单独的集群/单独的vpn中
更好的安全性隔离
Cloud/on-prem:在内部服务之间分配负载
使用单个集群的原因
减少设置、维护和管理开销
提高利用率
降低成本
考虑到一个不太昂贵的环境,普通的维护,但仍然确保生产应用程序的安全隔离,我建议:
1个用于DEV和登台的集群(通过名称空间分隔,甚至可能使用网络策略隔离,就像在Calico中一样)
1个集群用于PROD
环境平价
保持开发、分期和生产尽可能相似是一个很好的实践:
支持服务之间的差异意味着微小的不兼容性
突然出现,导致代码在开发中工作并通过测试或
在生产中登台失败。这些类型的错误会产生摩擦
这削弱了持续部署的动力。
将强大的CI/CD工具与头盔相结合。您可以使用helm值的灵活性来设置默认配置,只需要覆盖不同环境的配置即可。
带有AutoDevops的GitLab CI/CD与Kubernetes进行了强大的集成,允许您管理多个已经具有helm支持的Kubernetes集群。
管理多个集群(kubectl交互)
当您使用多个Kubernetes集群时,很容易
搞砸上下文,在错误的集群中运行kubectl。除了
也就是说,Kubernetes有版本不匹配的限制
客户端(kubectl)和服务器(kubernetes master),因此运行命令
在正确的上下文中并不意味着运行正确的客户端版本。
要克服这个问题:
使用asdf管理多个kubectl版本
将KUBECONFIG env var设置为在多个KUBECONFIG文件之间进行更改
使用kube-ps1跟踪当前上下文/名称空间
使用kubectx和kubens在集群/命名空间之间快速切换
使用别名将它们组合在一起
我有一篇文章举例说明了如何实现这一点:在多个Kubernetes集群中使用不同的kubectl版本
我还推荐以下内容:
掌握KUBECONFIG文件由Ahmet Alp Balkan(谷歌工程师)
Zalando如何管理140多个Kubernetes集群
我认为有一个中间点。我正在使用eks和节点组。主服务器由aws管理、扩展和维护。然后你可以创建3种类型的节点组(只是一个例子):
1 - General Purpose ->标签:environment= General - Purpose
2 -暂存->标签:环境=暂存(如有必要,会被污染)
3 - Prod ->标签:环境=生产(如有必要,有污染)
您可以在pod上使用公差和节点选择器,以便将它们放置在应该放置的位置。
这允许您为生产的节点组使用更健壮或更强大的节点,例如,用于登台、uat、qa等的SPOT实例……它有几个很大的优点:
环境在物理上是分离的(在名称空间中也是虚拟的)
您可以通过共享主节点和两个环境共享的一些带有pod的节点,以及在staging/uat/…中使用现货或更便宜的实例来降低成本。
没有集群管理开销
您必须注意角色和策略以确保其安全。您可以使用例如eks+calico来实现网络策略。
更新:
我找到了一个在使用EKS时可能有用的文档。它提供了一些关于如何安全运行多租户集群的详细信息,其中一些详细信息可能有助于将生产pod和名称空间与登台中的名称空间隔离开来。
https://aws.github.io/aws-eks-best-practices/security/docs/multitenancy/
很明显,通过将生产集群与阶段集群分开,可以降低潜在错误影响生产服务的风险。然而,这是以更多的基础设施/配置管理为代价的,因为它至少需要:
生产集群至少有3个主节点,登台集群至少有一个主节点
2需要添加到CI/CD系统的Kubectl配置文件
我们也不要忘记,环境可能不止一种。例如,我曾经工作过的公司至少有3种环境:
QA:这是我们进行日常部署的地方,也是我们在向客户发布之前进行内部QA的地方)
客户端QA:这是我们在部署到生产环境之前部署的地方,这样客户端可以在发布到生产环境之前验证环境)
生产:部署生产服务的地方。
我认为临时/按需集群是有意义的,但只适用于某些用例(负载/性能测试或非常«大»集成/端到端测试),但对于更持久/粘性的环境,我认为在单个集群中运行它们可能会减少开销。
我想我想接触k8s社区,看看对于我所描述的这种场景使用了什么模式。
这里有一些想法:
Do not trust namespaces to protect the cluster from catastrophe. Having separate production and non-prod (dev,stage,test,etc) clusters is the minimum necessary requirement. Noisy neighbors have been known to bring down entire clusters.
Separate repositories for code and k8s deployments (Helm, Kustomize, etc.) will make best practices like trunk-based development and feature-flagging easier as the teams scale.
Using Environments as a Service (EaaS) will allow each PR to be tested in its own short-lived (ephemeral) environment. Each environment is a high-fidelity copy of production (including custom infrasture like database, buckets, dns, etc.), so devs can remotely code against a trustworthy environment (NOT minikube). This can help reduce configuration drift, improve release cycles, and improve the overall dev experience. (disclaimer: I work for an EaaS company).