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

示例存储库设法进行了一些更改,在那里出现了新文件, getting-started-app-2.0.0-0.rpm
和hosts.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 /群集/仪表板上,一个惊喜等待着我们:

您可以使用新用户的username
和password
登录,也可以以admin
(默认用户)身份登录。 他的密码是集群cookie,我们在变量cartridge_cluster_cookie
指定了此值(这是app-default-cookie
,您不能窥视)。
成功登录后,打开“ Users
选项卡以确保一切顺利:

尝试添加新用户并更改其设置。 要删除用户,请为其指定一个deleted: true
标志。 Cartridge不会以任何方式使用email
和fullname
值,但是为了方便起见,您可以指定它们。
应用配置
让我们记住一切是如何开始的。
我们已经部署了一个小型应用程序,用于存储有关客户及其银行帐户的数据。 您还记得,该应用程序具有2个角色: api
和storage
。 storage
角色处理数据存储,并使用内置的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剧本的不同方法 ,并以最大的舒适度使用您的应用程序。
如果对您不起作用,或者您对如何改善我们的角色有任何想法,请随时发一张票 。 我们将始终为您解决问题提供帮助,我们将为您提供有趣的报价!