quota中文叫配额,是云计算中重要的概念之一,云计算提供什么,按需提供服务(各种资源),按需是云的精髓,要多少给多少,超限的响应也不能给。
在openstack中nova随处可见,trace openstack的源码,安全组,网络数量,tenant的cpu,内存,磁盘,等等都有quota的身影。
quota的变动是一个数据库事务,包含reservation/commit/rollback三个动作,缺一不可,reserve时若发现超限,则commit不进行,正常则commit,失败
就rollback,数据库写事务时的常规套路。需要特别提一句的是,reserve成功时候会返回reservation_id的list,commit根据这些id进行对应的配额变化。
trace过很多次openstack创建instance 的过程,再一次:
在_provision_instance中_check_num_instances_quota:
quotas = objects.Quotas(context)
quotas.reserve(instances=max_count, cores=req_cores, ram=req_ram)
调用nova/objects/quotas.py,这里objects中的quota封装了reserve和commit过程中serveration_id的list,省得传递它了。
在objects/quotas.py中的Quota 类中可以看到:
@base.remotable
def reserve(self, expire=None, project_id=None, user_id=None,
**deltas):
reservations = quota.QUOTAS.reserve(self._context, expire=expire,
project_id=project_id,
user_id=user_id,
**deltas)
self.reservations = reservations
self.project_id = project_id
self.user_id = user_id
self.obj_reset_changes()
这里quota.QUOTAS是QUOTAS = QuotaEngine()
一般来说,quota engine中对应的engine driver是DB,不用DB,难道用什么别的更合适?这里quota还要搞driver,想太多?
既然quota engine对应的是数据库,那就回到前面提到的sqlalchemy中去了,在nova/db/sqlalchemy/api.py中,我们可以找到
quota_reserve, reservation_commit,reservation_rollback等方法,背后对应了数据库的操作。
进入openstack的数据库中,查看表quotas, quota_usages, reservations几张表(还有别的表)就可以大致了解了。
比如quota表:
MariaDB [nova]> select * from quotas;
+----+---------------------+------------+------------+----------------------------------+-----------------------------+------------+---------+
| id | created_at | updated_at | deleted_at | project_id | resource | hard_limit | deleted |
+----+---------------------+------------+------------+----------------------------------+-----------------------------+------------+---------+
| 1 | 2015-04-28 07:55:58 | NULL | NULL | 91accf025304465fa1a4cfdcaa94d91d | metadata_items | 128 | 0 |
| 2 | 2015-04-28 07:55:58 | NULL | NULL | 91accf025304465fa1a4cfdcaa94d91d | injected_file_content_bytes | 10240 | 0 |
| 3 | 2015-04-28 07:55:58 | NULL | NULL | 91accf025304465fa1a4cfdcaa94d91d | ram | 51200 | 0 |
| 4 | 2015-04-28 07:55:58 | NULL | NULL | 91accf025304465fa1a4cfdcaa94d91d | instances | 10 | 0 |
| 5 | 2015-04-28 07:55:58 | NULL | NULL | 91accf025304465fa1a4cfdcaa94d91d | injected_files | 5 | 0 |
| 6 | 2015-04-28 07:55:58 | NULL | NULL | 91accf025304465fa1a4cfdcaa94d91d | cores | 20 | 0 |
| 7 | 2015-06-01 12:16:44 | NULL | NULL | 51b4379ea8734aaca96cb724a2d7200f | metadata_items | 128 | 0 |
| 8 | 2015-06-01 12:16:44 | NULL | NULL | 51b4379ea8734aaca96cb724a2d7200f | injected_file_content_bytes | 10240 | 0 |
| 9 | 2015-06-01 12:16:44 | NULL | NULL | 51b4379ea8734aaca96cb724a2d7200f | ram | 51200 | 0 |
| 10 | 2015-06-01 12:16:44 | NULL | NULL | 51b4379ea8734aaca96cb724a2d7200f | instances | 10 | 0 |
| 11 | 2015-06-01 12:16:44 | NULL | NULL | 51b4379ea8734aaca96cb724a2d7200f | injected_files | 5 | 0 |
| 12 | 2015-06-01 12:16:44 | NULL | NULL | 51b4379ea8734aaca96cb724a2d7200f | cores | 30 | 0 |
+----+---------------------+------------+------------+----------------------------------+-----------------------------+------------+---------+
quota_usages 表:
MariaDB [nova]> select * from quota_usages;
+---------------------+---------------------+------------+----+----------------------------------+-----------------+--------+----------+---------------+---------+----------------------------------+
| created_at | updated_at | deleted_at | id | project_id | resource | in_use | reserved | until_refresh | deleted | user_id |
+---------------------+---------------------+------------+----+----------------------------------+-----------------+--------+----------+---------------+---------+----------------------------------+
| 2015-04-28 08:05:18 | 2015-04-28 09:11:05 | NULL | 1 | 51b4379ea8734aaca96cb724a2d7200f | instances | 1 | 0 | NULL | 0 | 60ce7a8cab9c477895ef37440b1d9c57 |
| 2015-04-28 08:05:18 | 2015-04-28 09:11:05 | NULL | 2 | 51b4379ea8734aaca96cb724a2d7200f | ram | 512 | 0 | NULL | 0 | 60ce7a8cab9c477895ef37440b1d9c57 |
| 2015-04-28 08:05:18 | 2015-04-28 09:11:05 | NULL | 3 | 51b4379ea8734aaca96cb724a2d7200f | cores | 1 | 0 | NULL | 0 | 60ce7a8cab9c477895ef37440b1d9c57 |
| 2015-04-28 08:05:18 | 2015-04-28 08:05:18 | NULL | 4 | 51b4379ea8734aaca96cb724a2d7200f | security_groups | 1 | 0 | NULL | 0 | 60ce7a8cab9c477895ef37440b1d9c57 |
at last: 如果想在nova之外的地方使用quota,当然是novaclient,看nova client 源码,在novaclient/v1_1/shell.py中,有方法do_quota_update,参数有哪些
也可以看到,因此调用rest call或者nova client都可以达到目的。