在Tar​​antool墨盒上轻松部署应用程序(第2部分)


最近,我们讨论了如何部署用Tarantool Cartridge编写的应用程序。 但是操作不会在部署上结束,因此今天我们将更新应用程序,并了解如何管理拓扑,分片和授权以及更改角色的配置。


好奇请砍!


我们在哪里停下来


上一次我们配置以下拓扑:



示例存储库设法进行了一些更改,在那里出现了新文件, getting-started-app-2.0.0-0.rpmhosts.updated.2.yml 。 您不必拉出新版本,只需从链接下载软件包,并且hosts.updated.2.yml需要hosts.updated.2.yml ,以便在更改当前清单遇到困难时可以在那里查看。


如果您已经完成了本教程前面部分的所有步骤,那么在hosts.yml hosts.yml现在有一个包含两个storage副本的集群配置(在存储库中是hosts.updated.yml )。


提升我们的虚拟机:


 $ vagrant up 

安装新版本的Ansible-role Tarantool弹药筒(当然,为了更好,它进行了更改):


 $ ansible-galaxy install tarantool.cartridge,1.0.2 

因此,当前集群配置:


 --- all: vars: # common cluster variables cartridge_app_name: getting-started-app cartridge_package_path: ./getting-started-app-1.0.0-0.rpm # path to package cartridge_cluster_cookie: app-default-cookie # cluster cookie # common ssh options ansible_ssh_private_key_file: ~/.vagrant.d/insecure_private_key ansible_ssh_common_args: '-o IdentitiesOnly=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' # INSTANCES hosts: storage-1: config: advertise_uri: '172.19.0.2:3301' http_port: 8181 app-1: config: advertise_uri: '172.19.0.3:3301' http_port: 8182 storage-1-replica: config: advertise_uri: '172.19.0.3:3302' http_port: 8183 storage-2: config: advertise_uri: '172.19.0.3:3303' http_port: 8184 storage-2-replica: config: advertise_uri: '172.19.0.2:3302' http_port: 8185 children: # GROUP INSTANCES BY MACHINES host1: vars: # first machine connection options ansible_host: 172.19.0.2 ansible_user: vagrant hosts: # instances to be started on the first machine storage-1: storage-2-replica: host2: vars: # second machine connection options ansible_host: 172.19.0.3 ansible_user: vagrant hosts: # instances to be started on the second machine app-1: storage-1-replica: storage-2: # GROUP INSTANCES BY REPLICA SETS replicaset_app_1: vars: # replica set configuration replicaset_alias: app-1 failover_priority: - app-1 # leader roles: - 'api' hosts: # replica set instances app-1: replicaset_storage_1: vars: # replica set configuration replicaset_alias: storage-1 weight: 3 failover_priority: - storage-1 # leader - storage-1-replica roles: - 'storage' hosts: # replica set instances storage-1: storage-1-replica: replicaset_storage_2: vars: # replicaset configuration replicaset_alias: storage-2 weight: 2 failover_priority: - storage-2 - storage-2-replica roles: - 'storage' hosts: # replicaset instances storage-2: storage-2-replica: 

转到http://本地主机:8181 / admin / cluster /仪表板 ,并确保您的集群处于正确状态。


一切都与上次相同:我们将逐步更改此文件,并观察群集如何更改。 您可以随时在hosts.updated.2.yml查看最终版本


所以我们开始!


更新应用程序


首先,让我们更新我们的应用程序。 确保当前目录中有getting-started-app-2.0.0-0.rpm文件(如果没有,请从存储库下载 )。


指定软件包新版本的路径:


 --- all: vars: cartridge_app_name: getting-started-app cartridge_package_path: ./getting-started-app-2.0.0-0.rpm # <== cartridge_enable_tarantool_repo: false # <== 

我们指定了article_enable_tarantool_repo cartridge_enable_tarantool_repo: false以便该角色不会将存储库与我们上次安装的Tarantool软件包连接。 这将稍微加快部署过程,但完全没有必要。


启动带有cartridge-instances标签的剧本:


 $ ansible-playbook -i hosts.yml playbook.yml \ --tags cartridge-instances 

并且我们检查软件包是否已更新:


 $ vagrant ssh vm1 [vagrant@svm1 ~]$ sudo yum list installed | grep getting-started-app 

检查版本是否已变为2.0.0


 getting-started-app.x86_64 2.0.0-0 installed 

现在,您可以安全地试用该应用程序的新版本。


开启分片


让我们打开分片,以便以后可以控制storage副本。 这非常简单。 将变量all.vars添加cartridge_bootstrap_vshard all.vars部分:


 --- all: vars: ... cartridge_cluster_cookie: app-default-cookie # cluster cookie cartridge_bootstrap_vshard: true # <== ... hosts: ... children: ... 

我们推出:


 $ ansible-playbook -i hosts.yml playbook.yml \ --tags cartridge-config 

请注意,我们指定了cartridge-config标记以仅运行集群配置中涉及的任务。


打开Web UI http://本地主机:8181 / admin / cluster /仪表板 ,看看我们的存储桶以2:3比例分布在存储副本集上(我们为副本集指定了这样的权重,还记得吗?):



打开自动故障转移


现在,我们将打开自动故障转移模式,以便稍后了解它是什么以及如何工作。


cartridge_failover标志添加到配置中:


 --- all: vars: ... cartridge_cluster_cookie: app-default-cookie # cluster cookie cartridge_bootstrap_vshard: true cartridge_failover: true # <== ... hosts: ... children: ... 

我们再次启动集群管理任务:


 $ ansible-playbook -i hosts.yml playbook.yml \ --tags cartridge-config 

成功完成剧本后,您可以转到Web UI并确保已Failover右上角的Failover开关。 要关闭自动故障转移模式,只需将article_failover的值更改为false ,然后再次运行该剧本。


现在该弄清楚这是一种什么样的制度,以及我们为什么要启用它。


我们处理故障转移


您可能注意到了我们为每个副本集指定的failover_priority变量。 让我们看看它是什么。


Tarantool弹药筒提供自动故障转移模式。 每个副本集都有一个领导者-将其记录到的实例。 如果领导者发生了什么事,其中的一句话将成为他的角色。 哪一个 让我们仔细看一下storage-2副本集:


 --- all: ... children: ... replicaset_storage_2: vars: ... failover_priority: - storage-2 - storage-2-replica 

我们首先在failover_priority指定的storage-2实例。 在Web UI中,它首先出现在副本集实例列表中,并标有绿色的皇冠。 这是领导者-在failover_priority指定的第一个实例:



现在,让我们看看如果副本集的头发生了什么情况会发生什么。 我们进入虚拟机并停止storage-2实例:


 $ vagrant ssh vm2 [vagrant@vm2 ~]$ sudo systemctl stop getting-started-app@storage-2 

返回Web UI:



storage-2实例处的表冠变为红色-这表示指定的领导者身体不健康。 但是, storage-2-replica有了绿色的冠冕-该实例接管了领导职责,直到storage-2恢复服务为止。 这是一个自动故障转移。


让我们恢复storage-2


 $ vagrant ssh vm2 [vagrant@vm2 ~]$ sudo systemctl start getting-started-app@storage-2 

一切都回到了平方:



让我们在故障转移优先级中更改实例的顺序。 我们将使storage-2-replica实例成为领导者,并通常从列表中删除storage-2


 --- all: vars: ... hosts: ... children: ... replicaset_storage_2: vars: # replicaset configuration ... failover_priority: - storage-2-replica # <== ... 

运行来自replicaset_storage_2组的实例的cartridge-replicasets


 $ ansible-playbook -i hosts.yml playbook.yml \ --limit replicaset_storage_2 \ --tags cartridge-replicasets 

我们转到http://本地主机:8181 / admin / cluster /仪表板,然后查看领导者是否已更改:



但是我们从配置中删除了storage-2实例,为什么它仍然在这里? 事实是,接收到新值failover_priority Cartridge会按以下方式组织实例:列表中的第一个实例成为领导者,其余指示的实例紧随其后。 failover_priority未提及的实例将按UUID排序并附加到末尾。


流放实例


但是,如果我们要从拓扑中排除实例怎么办? 一切都非常简单:您需要将expelled标志传递给expelled 。 让我们排除storage-2-replica实例。 他现在是领导者,因此Cartridge将不允许我们这样做。 但是我们不怕困难,仍然可以尝试:


 --- all: vars: ... hosts: storage-2-replica: config: advertise_uri: '172.19.0.2:3302' http_port: 8185 expelled: true # <== ... 

由于排除实例是拓扑更改,因此我们指定了cartridge-replicasets


 $ ansible-playbook -i hosts.yml playbook.yml \ --limit replicaset_storage_2 \ --tags cartridge-replicasets 

运行剧本并查看错误:



如我们所见,Cartridge无法证明将当前副本集首标从拓扑中抛出是合理的。 这是非常合乎逻辑的,因为复制是异步的,所以排除领导者可能会导致数据丢失。 我们需要指定另一个领导者,并且仅在此之后排除该实例。 该角色将首先应用新的副本集配置,然后处理异常。 因此,我们更改failover_priority并再次运行该剧本:


 --- all: vars: ... hosts: ... children: ... replicaset_storage_2: vars: # replicaset configuration ... failover_priority: - storage-2 # <== ... 

 $ ansible-playbook -i hosts.yml playbook.yml \ --limit replicaset_storage_2 \ --tags cartridge-replicasets 

瞧, storage-2-replica实例已从拓扑中消失了!



请注意,实例流放确实是最终的且不可撤销。 从拓扑中删除实例后,我们的角色将停止systemd服务并删除该实例的所有文件。



如果您突然改变主意并确定storage-2副本集仍需要第二个实例,则将无法还原它。 弹药筒会记住已离开拓扑的所有实例的UUID,并且将不允许放逐者返回。 您可以使用相同的名称和配置来引发一个新实例,但是显然它将具有不同的UUID,因此Cartridge将允许它加入。


删除复制副本


我们已经发现,我们将不允许驱逐副本集的领导者。 但是,如果我们要永久删除storage-2复制副本,该怎么办? 当然,有一条出路。


为了不丢失数据,我们必须首先将所有存储桶都转移到storage-1 ,为此,我们将storage-2复制副本的权重设置为0


 --- all: vars: ... hosts: ... children: ... replicaset_storage_2: vars: # replicaset configuration replicaset_alias: storage-2 weight: 0 # <== ... ... 

启动拓扑管理:


 $ ansible-playbook -i hosts.yml playbook.yml \ --limit replicaset_storage_2 \ --tags cartridge-replicasets 

打开Web UI http:// localhost:8181 / admin / cluster / dashboard,并观察所有存储桶如何流入storage-1



我们将storage-2领导者设置为被驱逐标志,并告别此副本集:


 --- all: vars: ... hosts: ... storage-2: config: advertise_uri: '172.19.0.3:3303' http_port: 8184 expelled: true # <== ... 

 $ ansible-playbook -i hosts.yml playbook.yml \ --tags cartridge-replicasets 

请注意,这次我们没有指定limit选项,因为不应将我们启动了剧本的所有实例中的至少一个实例标记为expelled


因此,我们返回到原始拓扑:



登入


我建议不要管理副本集,而要考虑安全性。 现在,任何未经授权的用户都可以通过Web UI管理集群。 同意,看起来马马虎虎。


Cartridge提供了连接自己的授权模块(例如LDAP(或其中的任何模块))并使用它来管理用户及其对应用程序的访问的功能。 但是,我们将使用内置的授权模块,默认情况下,墨盒会使用该模块。 该模块允许您对用户执行基本操作(删除,添加,编辑),并实现密码验证功能。
请注意,我们的角色需要授权后端来实现所有这些功能。


因此,我们从理论转到实践。 首先,使授权成为必需,设置会话参数并添加新用户:


 --- all: vars: ... # authorization cartridge_auth: # <== enabled: true # enable authorization cookie_max_age: 1000 cookie_renew_age: 100 users: # cartridge users to set up - username: dokshina password: cartridge-rullez fullname: Elizaveta Dokshina email: dokshina@example.com # deleted: true # uncomment to delete user ... 

授权管理作为cartridge-config任务的一部分执行,我们指示以下标记:


 $ ansible-playbook -i hosts.yml playbook.yml \ --tags cartridge-config 

http://本地主机:8181 / admin /群集/仪表板上,一个惊喜等待着我们:



您可以使用新用户的usernamepassword登录,也可以以admin (默认用户)身份登录。 他的密码是集群cookie,我们在变量cartridge_cluster_cookie指定了此值(这是app-default-cookie ,您不能窥视)。


成功登录后,打开“ Users选项卡以确保一切顺利:



尝试添加新用户并更改其设置。 要删除用户,请为其指定一个deleted: true标志。 Cartridge不会以任何方式使用emailfullname值,但是为了方便起见,您可以指定它们。


应用配置


让我们记住一切是如何开始的。


我们已经部署了一个小型应用程序,用于存储有关客户及其银行帐户的数据。 您还记得,该应用程序具有2个角色: apistoragestorage角色处理数据存储,并使用内置的vshard-storage角色实现分片。 第二个角色api实现了具有用于数据管理的API的HTTP服务器,并且在其内部连接了另一个控制分片的标准角色vshard-router


因此,我们向应用程序API发出了第一个请求。 添加新客户端:


 $ curl -X POST -H "Content-Type: application/json" \ -d '{"customer_id":1, "name":"Elizaveta", "accounts":[{"account_id": 1}]}' \ http://localhost:8182/storage/customers/create 

作为响应,我们得到如下信息:


 {"info":"Successfully created"} 

请注意,在URL中,我们指定了实例端口app-1 8082 ,因为它实现了此API。


现在,让我们更新新用户的余额:


 $ curl -X POST -H "Content-Type: application/json" \ -d "{\"account_id\": 1, \"amount\": \"1000\"}" \ http://localhost:8182/storage/customers/1/update_balance 

在响应中,我们看到更新后的余额:


 {"balance":"1000.00"} 

太好了,一切正常! 实现了API,Cartridge从事数据分片,我们已经为紧急情况设置了故障转移优先级,甚至启用了授权。 现在该配置应用程序了。


当前的群集配置存储在分布式配置文件中。 每个实例均保留该文件的副本,并且Cartridge确保其在集群所有节点之间的同步。 我们可以在此文件中指定应用程序角色的配置,Cartridge将负责在所有实例之间分配新配置。


让我们看一下该文件的当前内容。 转到“ Cofiguration files选项卡,然后单击“ Download按钮:



在下载的config.yml config.yml我们找到一个空表。 难怪,因为我们还没有指定任何参数:


 --- [] ... 

实际上,我们集群的配置文件并不为空,它存储了当前的拓扑,授权设置和分片设置。 但是Cartridge共享这些信息并不是那么容易,它仅供内部使用,因此存储在隐藏的系统部分中,我们无法对其进行编辑。


每个应用程序角色可以使用一个或多个配置部分。 下载新配置分为两个阶段:首先,所有角色都验证他们准备好接受新参数。 如果没有异议,则应用更改;如果有人反对,则发生回滚。


让我们回到我们的应用程序。 api角色使用“ max-balance部分,其中最大允许余额存储在一个客户帐户上。 让我们配置此部分,但是,当然,不是手动配置,而是使用我们的Ansible角色。


因此,现在应用程序配置(或者部分可用的配置)是一个空表。 将max-balance部分的值添加为100000 。 我们将变量cartridge_app_config写入清单文件中:


 --- all: vars: ... # cluster-wide config cartridge_app_config: # <== max-balance: # section name body: 1000000 # section body # deleted: true # uncomment to delete section max-balance ... 

我们指定了部分名称max-balance及其内容body 。 节的内容不仅可以是数字,还可以是表或行,具体取决于角色的编写方式和要使用的值的类型。


我们推出:


 $ ansible-playbook -i hosts.yml playbook.yml \ --tags cartridge-config 

我们检查最大允许余额是否确实发生了变化:


 $ curl -X POST -H "Content-Type: application/json" \ -d "{\"account_id\": 1, \"amount\": \"1000001\"}" \ http://localhost:8182/storage/customers/1/update_balance 

作为响应,我们收到一个错误,如我们所愿:


 {"info":"Error","error":"Maximum is 1000000"} 

您可以在“ Configuraion files选项卡上重新下载配置文件,以确保在那里出现新的部分:


 --- max-balance: 1000000 ... 

尝试将新部分添加到应用程序配置中,更改其内容或将其完全删除(为此,您需要在该部分中设置deleted: true标志)。


您可以在Tarantool Cartridge 文档中找到如何在角色中使用分布式配置。


当您完成vagrant halt时,请记住vagrant halt流动。


总结


上一次,我们学习了如何使用特殊的Ansible角色来部署分布式Tarantool Cartridge应用程序。 今天,我们更新了该应用程序,还掌握了该应用程序的拓扑管理,分片,授权和配置。


不要止步于此,学习编写Ansible剧本的不同方法 ,并以最大的舒适度使用您的应用程序。


如果对您不起作用,或者您对如何改善我们的角色有任何想法,请随时发一张 。 我们将始终为您解决问题提供帮助,我们将为您提供有趣的报价!

Source: https://habr.com/ru/post/zh-CN484192/


All Articles