如何将“自愈”与基础设施即代码相结合

42次阅读
没有评论

问题描述

作为一个对运维领域的新手,我对于DevOps、SRE等领域的发展有一个大局观的问题。以下是一个具体的例子,涉及到网络负载均衡器。
从基础设施即代码(IaC)的角度来看,我理解应该将配置(例如不同虚拟服务器的池)保存在负载均衡器之外。对负载均衡器的更改应该首先在外部配置中进行,并通过流水线应用到实际应用程序中。
从“自愈”(self-healing)的角度来看,我们可能希望代码根据某些事件来更改网络负载均衡器的配置,以采取自动的补救措施。例如,如果某个传感器指示系统存在问题,我们可能希望将其从池中移除。
现在,解决这两个需求的明显方法是通过更改负载均衡器的外部配置来进行自动的补救措施。然而,一些基础设施即代码的原因和实现可能会导致这种方法存在问题。例如,假设负载均衡器的外部配置保存在Git存储库中的yaml文件中,并且对提交进行了控制(需要高级别人员进行审核)。在这种情况下,补救措施可能会被搁置在某个人的待办事项列表中。
显然,如果我们希望进行更频繁和更快速的自动响应,问题会变得更加严重。
我想知道人们对此的看法。主要问题是使用类似Git的工具来保存配置吗?将相同的控制措施应用于所有提交是一个错误吗?以这种方式处理负载均衡器设置是否错误(请注意,它具有一些运行时状态,这些状态没有被捕获,例如它对运行的健康检查的内部响应)?非常感谢任何想法。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

你没有指定具体的技术,但我可以从AWS的一种特定方法中获取灵感,然后将其扩展到其他用例。在AWS中,你有一个负载均衡器(ELB)和一个自动扩展组(ASG)。
负载均衡器有自己的健康检查,自动扩展组也可以有自己的健康检查。如果一个实例停止响应,它将从负载均衡器中移除。如果自动扩展组检测到一个不健康的实例,它将销毁该实例并重新创建一个新的实例,然后自动将其添加到负载均衡器中。自动扩展组知道它的最小实例数和最大实例数,并根据某些指标(例如CPU负载)维护实际实例的数量。
因此,只有当系统行为超出预期范围时,才需要更改配置。我们有一些自动扩展组,最小实例数为3,最大实例数为30。通常情况下,我们大约有4个实例,所以如果我们需要超过30个实例,那么可能是因为互联网已经崩溃了。
关于通过git进行配置更改 – 这可以与完整的CI/CD流水线一起正常工作,可能还包括一些蓝/绿部署。但是,除非你想避免所有可重用性并且总是复制基础设施定义的副本,否则可能应该考虑将参数存储在git之外的某个地方。你可以使用s3版本化的yaml/json文件、SSM参数(仍然是AWS的说法)或者一般的持久化版本化参数存储(NoSQL数据库也可以工作)。
正如评论中提到的 – 这里没有银弹,但停止在静态宇宙的框架中思考可能是有用的。如果你的目标是每天至少进行2次生产部署,你的“高级审核者”可能需要被更好的东西取代。

方案2

使用脚本或工具来管理容器的启动顺序可能会增加复杂性,并且需要确保容器A和容器B之间的依赖关系正确设置。
另一种方法是编写脚本或使用工具来控制容器的运行顺序。你可以使用docker run命令来手动控制容器的启动顺序,或者使用一些第三方工具来管理容器的依赖关系。

示例:

以下是一个简单的bash脚本示例,可以在容器A启动后启动容器B:

#!/bin/bash
# 启动容器A
docker run -d --name container_a your_image_a
# 等待容器A完全启动
while ! docker exec container_a echo "Container A is ready"; do
  sleep 1
done
# 启动容器B
docker run -d --name container_b your_image_b

在这个示例中,我们首先使用docker run命令启动容器A,并将其命名为container_a。然后,使用一个循环来等待容器A完全启动(这里是通过在容器内运行echo命令来测试)。一旦容器A就绪,我们再使用docker run命令启动容器B,并将其命名为container_b

正文完