问题描述
正在使用Ansible部署一组虚拟机上的微服务应用程序。每个微服务类型在虚拟机组中运行的副本数量不同。使用单个部署playbook进行部署,通过传递额外的变量来指定要安装的服务,并在清单中指定要运行的主机组。但是,有时需要在主机之间移动微服务以重新平衡负载。根据目前的Ansible设置,这个过程并不简洁。移动一个微服务实例意味着在清单组中添加一个新的主机条目,并从清单组中删除一个旧的主机条目。新的实例会被安装,但是不会对已删除的主机运行任何逻辑。需要运行另一个playbook来从已删除的主机卸载服务。用户正在寻找一种快速移动微服务的方法。他考虑使用一个包含所有主机的单个清单组,并使用列表变量来指定每个微服务运行的主机。当安装服务时,可以设置一个自定义的事实(fact)。安装任务可以检查该事实以及当前主机是否在列表中。卸载任务也可以检查该事实以及当前主机是否不在列表中。用户想知道这种组织逻辑的方式是否正确,或者是否有更好的方法。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
我已经创建了一个演示,其中使用一个角色在一组虚拟机上安装多个Spring Boot微服务。您可以命名一个子集的虚拟机,以指定每个服务应该放置在哪些主机上。playbook可以在所有主机上运行,计算每个服务应该在每个主机上运行,并将运行install.yaml或uninstall.yml任务。
以下是安装两个相同微服务的示例,它们具有不同的运行时参数:
roles:
- {
role: "ansible-role-springboot",
sb_app_name: "microservices-registration",
sb_app_group_id: "org.springframework.samples.service.service",
sb_app_artifact_id: "microservices-demo",
sb_app_version: "2.0.0.RELEASE",
sb_app_run_args: '"registration 8082"',
sb_app_healthcheck_urls: [
"http://localhost:8082/actuator/health"
],
sb_hosts: [
"my-test-vm"
]
}
- {
role: "ansible-role-springboot",
sb_app_name: "microservices-web",
sb_app_group_id: "org.springframework.samples.service.service",
sb_app_artifact_id: "microservices-demo",
sb_app_version: "2.0.1.RELEASE",
sb_app_run_args: '"web 8083"',
sb_app_healthcheck_urls: [
"http://localhost:8083/actuator/health"
],
sb_hosts: [
"my-test-vm"
]
}
这个角色基于orachide/ansible-role-springboot,看起来非常全面。新的部分是用粗体标出的,它是一个简单的应该运行微服务的主机列表。
通常,我们希望每次应用角色时使用不同的构件ID和版本。在上面的示例中,它运行一个官方的Spring Boot微服务mega jar,使用不同的RUN_AS参数运行不同的服务。这似乎有点奇怪,不是我推荐的做法,但是这个角色对这些细节是不可知的。
原始角色要求使用可执行的jar文件:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
该角色将创建一个符号链接到该可执行文件,并创建一个运行它的环境文件等等。
我所做的修改非常简单,因为原始角色根据sb_app_state安装或卸载逻辑:
- import_tasks: install.yml
when: sb_app_state == 'present'
- import_tasks: uninstall.yml
when: sb_app_state == 'absent'
所以只需要添加一些逻辑来检查当前主机名是否在sb_hosts列表中,然后根据需要更新sb_app_state的值。这可以通过一个简单的更改完成。
演示代码库使用test kitchen ansible和testinfra来对playbook进行单元测试。让它工作非常值得,可以自动化地对playbook逻辑进行验收测试。
方案2
使用编排器或Kubernetes / Docker swarm来管理容器的部署和迁移可能会更加方便和灵活。但是,如果您的组织还没有批准在生产环境中使用容器,那么使用Ansible来管理微服务的部署和迁移是一个不错的选择。