# 全局配额设计
## 概述
配额管理中重要的两个流程
- 设置配额
- 申请资源
为了在K8s集群内控制工作负载的资源使用量。往往需要先设置好配额,定义配额的资源量,且指定配额所限制的命名空间。当工作负载在被限制的命名空间使用资源时,再从设置好的配额中申请资源,以此达到对命名空间的资源消耗总量的管控。
## 设置配额
使用 UniverseResourceQuota 来设置全局配额,将限制整个 “宇宙” 多集群环境中 namespace 的资源使用量。
### 数据结构
```go
// UniverseResourceQuotaSpec defines the desired state of UniverseResourceQuota
type UniverseResourceQuotaSpec struct {
// Hard is the set of desired hard limits for each named resource
// +optional
Hard v1.ResourceList
// A collection of filters that must match each object tracked by a quota.
// If not specified, the quota matches all objects.
// +optional
Scopes []v1.ResourceQuotaScope `json:"scopes,omitempty"`
// ScopeSelector is also a collection of filters like Scopes that must match each object tracked by a quota
// but expressed using ScopeSelectorOperator in combination with possible values.
// +optional
ScopeSelector *v1.ScopeSelector `json:"scopeSelector,omitempty"`
// +optional
RegionSelector *metav1.LabelSelector `json:"regionSelector,omitempty"`
// +optional
ClusterSelector *metav1.LabelSelector `json:"clusterSelector,omitempty"`
// +optional
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,onitempty"`
}
// UniverseResourceQuotaStatus defines the observed state of UniverseResourceQuota
type UniverseResourceQuotaStatus struct {
// Hard is the set of enforced hard limits for each named resource
// +optional
Hard v1.ResourceList
// Used is the current observed total usage of the resource in the namespace
// +optional
Used v1.ResourceList
}
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// UniverseResourceQuota is the Schema for the universeresourcequotas API
type UniverseResourceQuota struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec UniverseResourceQuotaSpec `json:"spec,omitempty"`
Status UniverseResourceQuotaStatus `json:"status,omitempty"`
}
//+kubebuilder:object:root=true
// UniverseResourceQuotaList contains a list of UniverseResourceQuota
type UniverseResourceQuotaList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []UniverseResourceQuota `json:"items"`
}
```
### Spec
在 MizarGalaxy 多集群环节中,通过 Region,Scope(作用域),Cluster ,Namespace 条件来定义配额要限制的 namespace(或者将其限制的资源扩展为Application)
Region 即区域,指特定区域内的集群。Cluster 选择特定的集群。Namespace 指定特定的命名空间。Scope 用来限制特定状态的 Pod 的资源使用量。
UniverseResourceQuota 中的 scope 是限制“宇宙”多集群环境内特定 Regions 内或特定 Cluster 内的 namespaces 下特定状态的 pods quota。更多关于Scope的信息请参考 [Kubernetes Quota Scope](https://kubernetes.io/zh-cn/docs/concepts/policy/resource-quotas/#quota-scopes)。
- RegionSelector:
使用 RegionSelector 通过标签的方式来筛选,限制某个或多个 Region 中的的 namespace 的资源用量,如不设置,则默认是所有Region。
- Scope:
使用 Scope 的名称来筛选特定作用域的 namesapce 的资源用量,如不设置,则默认所有 Scope。
- ScopeSelector:
使用 ScopeSelector,限制带有某种 Scope 名称和相应值的 namesapce 的资源用量。
- ClusterSelector:
使用ClusterSelector 限制的资源用量。特定集群打上类似 `type:privite/public`,`team: bigdata/ai` 等标签用来标识集群的作用,再通过标签来筛选要限制的集群。
- NamespaceSelector:
使用 NamespaceSelector 限制特定标签的命名空间的资源用量。
### Status
统计配额的总资源用量,如果超出用量则不允许再申请资源。一旦 UniverseResourceQuota 被创建,controller 会开始监听整个 “宇宙” 中被限制的 namespace 的资源总用量。并汇总到 `.status.used` 字段中。
## 申请资源

### 申请
创建业务时在 pod,workload中设置 `.spec.resource` 字段以表示申请资源量和限制最大使用量(或者在Application中增加 resource 字段用来申请资源)
### 校验
使用 ValidateWebhook 来校验项目的资源申请。
当项目在申请预留资源时,Webhook 匹配到某个已经创建好的 UniverseResourceQuota,计算这个UniverseResouceQuota的资源余量。然后对比业务要申请的资源量。如果资源余量足够,则允许创建业务,如果资源余量不够,则驳回创建请求。
### 创建
校验通过后,调度到相应的集群中并创建工作负载,controller 监听到业务创建成功后,将该业务申请的资源量更新到对应 UniverseResourceQuota 的状态的 used 字段中。