在这一年中,我一直在与几个开发团队合作,他们开始在 K8S/OpenShift 上构建应用程序。 我的目标是为开发人员提供指导和最佳实践,以帮助他们成功地将应用程序部署到生产环境中。 如果您是在 K8S/OpenShift 之上构建应用程序的开发人员,那么您可能会对此博客感兴趣。
该博客包括两类最佳实践。 第一类列出了提高应用程序可靠性的实践,第二类包括了提高安全性的实践。 请注意,这两个类别之间有些重叠。 您会发现在某种程度上可以提高安全性的可靠性实践,反之亦然。
应用程序可靠性
以下 9 种最佳实践可提高应用程序可用性,正常运行时间,并总体上改善应用程序用户体验。
1. 将应用程序配置外部化
包含环境特定配置的容器镜像不能在环境(Dev,QA,Prod)中升级。 为了实现可靠的发布过程,应将在较低环境中测试过的相同镜像部署到生产中。(译者注: 一次构建, 到处运行)
将特定于环境的配置保留在容器镜像之外。 例如,使用 ConfigMaps 和 Secrets 存储应用程序配置。
2. 在 pod 定义中定义资源请求和资源限制
由于请求资源的配置不正确,应用程序可能会耗尽内存或导致 CPU 饥饿。 指定请求的内存和 CPU 资源可以使群集做出适当的调度决策,以确保应用程序具有请求的资源可用。
3. 始终在 POD 定义中定义 liveness 和 readiness 探针
运行状况检查探针使群集可以为您的应用程序提供基本的弹性。 它允许群集重新启动您的应用程序(liveness 探测失败),或者避免在未准备好服务请求的情况下将流量路由到您的应用程序(readiness 探测)。
4. 使用 pod disruption budgets 保护应用程序
在某些情况下,需要从集群节点中驱逐应用程序 pods。例如,在管理员可以执行节点维护之前,或者在集群 autoscaler 在降级时从集群中删除节点之前,需要进行驱逐。为了确保您的应用程序在需要驱逐 pods 时仍然可用,您必须定义各自的 PodDistruptionBudget 对象。
5. 确保应用程序 Pod 正常终止
终止时,应用程序容器应完成所有进行中的请求并正常终止现有连接。 这允许在终端用户不注意的情况下重新启动 pod,例如在部署应用程序的新版本时。
6. 每个容器运行一个进程
避免在单个容器中运行多个进程。 在单独的容器中运行 1 个进程可以更好地隔离进程,避免信号路由出现问题,并避免出现僵尸进程。
7. 实现应用程序监控和告警
应用程序监控和告警对于保持应用程序在生产中良好运行并满足业务目的至关重要。 使用 Prometheus&Grafana 等监控工具来监控您的应用程序.
8. 配置应用程序以将其日志写入 stdout / stderr (译者注: 其他 K8S 发行版按需采纳)
OpenShift 将收集这些日志 (指 stdout/stderr) 并将其发送到集中位置(ELK,Splunk)。 在分析生产问题时,应用程序日志是宝贵的资源。 基于应用程序日志内容的告警有助于确保应用程序按预期运行.
9. 考虑实施以下弹性措施:
- 断路器
- 超时
- 重试
- 速率限制
列出的弹性措施可以使您的应用程序在出现故障时表现更好。 它们可保护您的应用程序免于过载(速率限制,断路器),并在遇到连接问题(超时,重试)时提高性能。 考虑利用 Service Mesh 实现这些措施,而无需在应用程序中更改代码。
应用程序安全性
本节包括 5 个最佳实践,它们将提高应用程序的安全性。 我强烈建议您考虑在您的环境中实施所有这些实践。
10. 使用受信任的基础镜像
尽可能使用供应商提供的容器镜像。 供应商镜像已经过测试,强化和支持。 如果使用社区支持的图像,请仅使用您信任的社区提供的图像。 在公共注册表(例如 Docker Hub)中有未知来源的图像。 不要使用它们!
11. 使用最新版本的基础镜像
仅最新版本的容器镜像包含所有可用的安全修复程序。 设置 CI 管道以在构建应用程序镜像时始终提取最新版本的基础镜像。 另外,设置 CI 管道以在更新的基础镜像可用时重建应用程序。
12. 使用单独的构建镜像和运行时镜像
译者注:
即 docker 的多阶段构建功能
创建具有最小依赖性的单独的运行时镜像可减少攻击面并产生较小的运行时镜像。 构建镜像包含构建依赖关系,构建依赖关系对于构建应用程序是必需的,而对于运行应用程序则不是必需的
13. 尽可能遵守受限的安全上下文约束(restricted security context constraint)
译者注:
应该是 OpenShift 特有的安全加固功能。
标准 K8S 中可以考虑通过 OPA(OpenPolicyAgent)来实现。
修改您的容器镜像以允许在受限的 SCC(security context constraint 简写)下运行。
应用程序容易受到攻击,攻击者可以控制应用程序。 强制使用 OpenShift 受限制的 SCC 可提供最高级别的安全性,以防止在应用程序被破坏的情况下损害集群节点。
14. 使用 TLS 保护应用程序组件之间的通信
应用程序组件可能会传达应受到保护的敏感数据。 除非您认为基础 OpenShift 网络是安全的,否则您可能希望利用 TLS 保护应用程序组件之间的通信。 考虑利用 Service Mesh 对应用程序 TLS 进行管理。
总结
在此博文中,我们回顾了 14 种最佳实践,可以帮助您在 K8S/OpenShift 上构建更可靠,更安全的应用程序。 开发人员可以使用此列表导出自己的强制性实践列表,所有团队成员都必须遵循该列表.
该博客中列出的实践列表是一个良好的开端。 如果您想了解更多信息,可以在 OpenShift 文档的 创建镜像 部分中找到另一套很好的建议。