2023年Kubernetes最佳实践


作为容器编排平台,Kubernetes(K8s)具有诸多优势。例如,K8s 在自动化方面很重要。这包括工作负载发现、自我修复和容器化应用程序扩展。
然而,Kubernetes 并不总是在经过一些调整后就可以投入生产。
本指南分享了您应该立即实施的关键 Kubernetes 最佳实践,以提高您的 K8s 安全性、性能和成本。

1.跟上最稳定版本的步伐
一般规则是将您的 K8s 更新到最新的稳定版本。它很可能已经针对任何安全或性能问题进行了修补。几乎肯定还会有更多基于社区或供应商提供的支持。最后,K8s 最佳实践可以让您避免可能危及服务交付的安全、性能和成本异常。

2. 整理你的清单
也许您发现 YAML 很难使用。然后你可以使用 yamllint,它可以在一个文件中处理多个文档。
还有 Kubernetes 特定的 linters 可用:
您可以使用 kube-score 整理您的清单并遵循最佳实践。Kubeval 也会检查你的清单。但是,它只检查有效性。Kubernetes 1.13 中 kubectl 的 dry-run 选项允许 Kubernetes 检查但不应用您的清单。此功能允许您验证 K8s 的 YAML 文件。

3.版本控制配置文件是你的朋友
将所有配置文件(例如部署、服务和入口配置文件)存储在版本控制系统中。GitHub 是最流行的开源分布式版本控制平台,但其他平台还包括 GitLab、BitBucket 和 SourceForge。
在将您的代码推送到集群之前执行此操作使您能够跟踪源代码更改以及谁进行了更改。必要时,您可以快速回滚更改、重新创建或恢复集群,以确保稳定性和安全性。

4. Git 工作流是必经之路
GitOps,或基于 Git 的工作流,是一个优秀的模型,用于自动化所有任务,包括 CI/CD 管道,Git 作为唯一的真实来源。除了提高生产力之外,GitOps 框架还可以通过以下方式为您提供帮助:

  1. 加速部署
  2. 增强错误跟踪
  3. 自动化您的 CI/CD 工作流程。

最后,使用 GitOps 方法可以简化集群管理并加快应用程序开发。

5. 利用声明性 YAML 文件
编写声明性 YAML 文件,而不是使用 kubectl run 等命令式 kubectl 命令。然后,使用 kubectl apply 命令,您可以将它们添加到集群中。声明式方法允许您指定所需的状态,而 Kubernetes 将弄清楚如何到达那里。
您的所有对象以及您的代码都可以存储在 YAML 文件中并进行版本控制。如果出现问题,您可以通过恢复较早的 YAML 文件并重新应用它来轻松回滚部署。此外,此模型可确保您的团队可以看到集群的当前状态以及随时间对其所做的更改。

6. 明确你想要的资源请求和上限
在为请求或限制定义CPU和内存限制时,通常对CPU使用毫微克,对内存使用mebibytes或兆字节。如果资源请求超过了你指定的限制,容器将不会在pod中运行。

当资源稀缺时,生产集群可能在没有资源限制和请求的情况下失败。多余的资源会被集群中的pod消耗掉,增加你的Kubernetes成本。此外,如果pod消耗了太多的CPU或内存,而调度器无法添加新的pod,节点可能会崩溃。

7.将Pod与部署、ReplicaSets和作业结合起来
尽可能地避免使用裸露的pod。在节点发生故障时,裸露的pod不能被重新安排,因为它们没有与部署或复制集绑定。

部署可以实现两个目标。

  • 创建一个ReplicaSet以保持所需数量的pod。
  • 为pod定义一个替换策略,例如RollingUpdate。

除非你有一个严格的重启策略。从不使用的情况下,部署几乎总是比直接创建pod更有效率。

8.清楚地标记你的K8s资源
标签是键/值对,帮助你识别Kubernetes集群中特定资源的特征。标签还允许你用kubectl过滤和选择对象,使你能够根据特定的特征快速识别对象。

即使你不认为你会马上使用它们,给你的对象贴上标签也是一个好主意。另外,尽可能多地使用描述性的标签来区分你的团队将要工作的资源。对象可以按所有者、版本、实例、组件、管理人、项目、团队、保密级别、合规性方面和其他标准进行标注。

9.运行有效性探针(在这个其他探针之后)
Liveness probes定期检查长期存在的pod的健康状况,防止Kubernetes将流量路由到不健康的pod。Kubernetes(kubelet默认策略)会重新启动无法通过健康检查的pod,确保你的应用程序的可用性。

探针向pod发送一个ping,看是否收到响应。没有响应表明你的应用程序没有在该pod上运行,导致探针启动一个新的pod并在那里运行应用程序。

还有一点。你必须先运行一个启动探针,这是第三种类型的探针,当一个pod的启动序列完成时,它会提醒K8s。如果一个pod的启动探针不完整,有效性和准备性探针就不会针对它。

10.命名空间简化了资源管理
命名空间协助你的团队将集群逻辑地划分为子集群。当你想在多个项目或团队之间同时共享一个Kubernetes集群时,这一点特别有用。命名空间允许开发、测试和生产团队在同一集群内进行协作,而不会覆盖或干扰对方的项目。

Kubernetes有三个命名空间:默认、kube-system和kube-public。一个集群可以支持多个命名空间,这些命名空间在逻辑上是独立的,但可以相互通信。

11.保持无状态
无状态的应用程序通常比有状态的应用程序更容易管理,尽管随着Kubernetes运营商的普及,这种情况正在改变。

无状态的后端使刚接触Kubernetes的团队不再需要维护限制扩展性的长期运行的连接。

无状态的应用程序也更容易按需迁移和扩展。

还有一件事。保持工作负载无状态允许你使用现货实例。

事情是这样的。使用现货实例的一个缺点是,AWS和Azure等供应商经常要求在短时间内归还廉价的计算资源,这可能会扰乱你的工作负载。你可以通过使你的应用程序无状态来规避这个问题。

12.建立你的网络策略
Kubernetes的网络策略规定了哪些流量是允许的,哪些是不允许的。这类似于在Kubernetes集群的吊舱之间设置防火墙。无论流量如何在环境中的吊舱之间移动,只有在网络策略允许的情况下才会被允许。

在创建网络策略之前,你必须定义授权连接,并指定该策略应适用于哪些豆荚。这将过滤掉任何不符合你标准的流量。

你可以在这个资源库中找到各种Kubernetes网络策略的例子和YAML文件样本。

13.设置基于角色的访问控制
RedHat在2022年对超过300名DevOps专业人士的调查中发现了以下情况。

  • 对于55%的受访者来说,安全问题延迟了应用程序的发布。
  • 在继续使用Kubernetes和容器方面,59%的人认为安全是一个主要障碍。
  • 31%的人说,安全漏洞导致了收入或客户损失。
  • 几乎所有的人(94%)在过去一年中至少有一次Kubernetes安全事件。

你可以使用RBAC来指定哪些用户可以访问哪些Kubernetes资源,例如他们可以访问哪些集群,谁可以进行修改,以及他们可以在多大程度上进行修改。

RBAC权限可以通过两种方式配置:

  • 如果你想为非命名空间的资源设置权限,请使用ClusterRole。
  • -按角色设置命名空间的Kubernetes资源

14.为你的Kubernetes环境安装防火墙
另一个重要的Kubernetes安全最佳实践。

在集群前面设置一个防火墙,以限制外部请求到达API服务器,此外还有网络策略来控制集群内的内部流量。这可以通过使用常规或端口防火墙规则来实现。

此外,确保IP地址被列入白名单,开放的端口被限制。

15.较小的镜像更理想
使你的镜像小而有层次。镜像越小,构建速度越快,所需的存储空间越小。通过有效地分层,一个镜像的大小可以大大减少。通过从头开始,你可以优化你的镜像。

怎么做?
如果你需要许多不同的组件,在一个Docker文件中使用多个FROM语句。该设置将根据FROM命令从部署的容器中提升每一层。
该功能会生成一些部分,每个部分指的是不同的基础镜像。产生的Docker容器更小,因为它不再包括以前的层,只有你需要的组件。