管理员可以使用 Kubernetes 资源配额工具来确保在不同用户之间公平共享资源。由 ResourceQuota
对象定义的资源配额,可提供限制条件来限制单个命名空间中的聚合资源消耗。
层次结构控制器扩展了每个命名空间的资源配额的概念,支持分层命名空间。HierarchicalResourceQuota
对象限制一个子树中所有命名空间的总资源消耗量,使管理员能够跨多个相关命名空间限制资源消耗。
启用分层资源配额时,层次结构控制器会安装两个验证准许 webhook,一个真正强制实施资源消耗限制,另一个用来验证分层资源配额。
启用分层资源配额
分层资源配额由层次结构控制器提供。如需启用分层资源配额,请按以下步骤操作:
使用 Config Sync 1.6.2 或更高版本安装层次结构控制器。
在 Config Management Operator 的配置文件中,将
spec.hierarchyController
对象中enableHierarchicalResourceQuota
的值设置为true
:# config-management.yaml apiVersion: configmanagement.gke.io/v1 kind: ConfigManagement metadata: name: config-management spec: hierarchyController: enabled: true # Set to true to enable hierarchical resource quotas: enableHierarchicalResourceQuota: true # ...other fields...
应用配置:
kubectl apply -f config-management.yaml
大约一分钟后,层次结构控制器和分层资源配额就可以在您的集群上使用。
如需验证是否已启用分层资源配额,请按以下步骤操作:
在任何命名空间中创建
HierarchicalResourceQuota
对象,如下所示:cat > example-hrq.yaml <<EOF apiVersion: hierarchycontroller.configmanagement.gke.io/v1alpha1 kind: HierarchicalResourceQuota metadata: name: example-hrq spec: hard: configmaps: "1" EOF kubectl apply -f example-hrq.yaml -n default
确认已在命名空间中使用相同
spec.hard
(1 个configmap
)创建名为gke-hc-hrq
的新ResourceQuota
对象,例如:kubectl describe resourcequota gke-hc-hrq -n default
输出:
Name: gke-hc-hrq Namespace: default Resource Used Hard -------- ---- ---- configmaps 0 1
清理:
kubectl delete hrq -n default example-hrq
确保移除自动创建的对象:
kubectl get resourcequota gke-hc-hrq -n default
输出:
Error from server (NotFound): resourcequotas "gke-hc-hrq" not found
使用分层资源配额
设置配额
设置 HierarchicalResourceQuota
与设置常规 ResourceQuota
相同,但具有不同的 apiVersion
和 kind
;因此,您可以像在 ResourceQuota
中一样在 spec.hard
字段中设置资源限制。
假设有一个名为 team-a
的团队拥有一个名为 service-a
的服务,并且有一个名为 team-b
的子团队,三者均由分层命名空间表示,如下所示:
kubectl hns tree team-a
输出:
team-a
├── service-a
└── team-b
如果要限制 team-a
中的 configmaps
数量,但不限制任何后代中的数量,您可以按照常规方式创建常规 ResourceQuota
,如下所示:
cat > team-a-rq.yaml <<EOF
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-a-rq
namespace: team-a
spec:
hard:
configmaps: "1"
EOF
kubectl apply -f team-a-rq.yaml
相比之下,如需限制 team-a
及其后代中的 configmaps
总数,请替换上一示例中的 apiVersion
和 kind
:
cat > team-a-hrq.yaml <<EOF
# Modify the following two lines:
apiVersion: hierarchycontroller.configmanagement.gke.io/v1alpha1
kind: HierarchicalResourceQuota
# Everything below this line remains the same
metadata:
name: team-a-hrq
namespace: team-a
spec:
hard:
configmaps: "1"
EOF
kubectl apply -f team-a-hrq.yaml
在这三种命名空间中尝试创建 configmap
都会成功。例如,我们可能会选择在其中一个子命名空间中创建 configmap
:
kubectl create configmap config-1 --from-literal key=value -n team-b
输出:
confimap/config-1 created
但如果再尝试在任何一个命名空间中创建新 configmap 都将失败,包括在同级或父级命名空间中:
kubectl create configmap config-2 --from-literal key=value -n service-a
kubectl create configmap config-2 --from-literal key=value -n team-a
二者的输出:
Error from server (Forbidden): admission webhook "resourcesquotasstatus.hierarchycontroller.configmanagement.gke.io" denied the request: exceeded hierarchical quota in namespace "team-a": "team-a-hrq", requested: configmaps=1, used: configmaps=1, limited: configmaps=1
检查配额
如需查看 HierarchicalResourceQuota
的当前限制和使用情况,请使用 kubectl describe
命令查看常规资源配额:
kubectl describe hrq team-a-hrq -n team-a
输出:
# ...other fields...
Spec:
Hard:
Configmaps: 1
Status:
Hard:
Configmaps: 1
Used:
Configmaps: 1
更新命名空间层次结构
命名空间始终受其祖先中的任何 HierarchicalResourceQuota
的限制。修改命名空间层次结构会触发任何配额的用量的重新计算。
从具有分层配额的子树中移除命名空间
当命名空间从其祖先中具有分层配额的子树中移出时,它将不再受这些配额的限制,并且其资源将从配额的使用量中删除。
例如,如果从前面的子树中移除 team-b
,则 team-b
中的 configmap
消耗将没有任何限制。分层配额用量重置为 0
,这意味着 team-a
和 service-a
现在总共可多消耗一个 configmap
。
将命名空间添加到具有分层配额的子树
将命名空间添加到具有分层配额的子树后,该命名空间将受到分层配额的限制,其资源用量将被添加到配额的用量。
例如,如果将另一个命名空间添加到上一个子树,则新添加的命名空间中将不允许再消耗 configmap
。同样,新添加的命名空间中的任何现有 configmap
用量都会添加到分层配额的使用量中。
即使新命名空间的用量超过了分层配额中的限制,分层配额也不会阻止您将新的命名空间移动到子树中。但是,如果超出限制,将禁止使用更多资源,直到用量低于限制或上限增加为止。这与施加的限制低于命名空间中的现有用量时 Kubernetes ResourceQuota
的行为类似。
一般规则
在极端情况下,分层资源配额的行为与 Kubernetes 资源配额类似。例如:
- 如果多个分层资源配额应用于同一个命名空间,则遵循最严格的资源限制。
- 如果您创建的限制低于已消耗的资源量,则不会删除现有资源,但是任何将来的资源消耗都将被禁止,直到使用率降至该限制以下或直至上限增加为止。
问题排查
消耗资源时出现 InternalError
当您消耗资源时(例如,创建 configmap
),您的请求可能会在 10 秒内停止响应,并且您会看到以下错误消息:
Error from server (InternalError): Internal error occurred: resource quota evaluates timeout
除非 gke-hc-controller-manager
pod 处于错误状态,否则不应出现此错误消息。
要解决此问题,拥有权限的管理员可以通过在 hnc-system
命名空间中直接使用 gke-hc-controller-manager-
前缀来删除 pod。pod 会自动重启。在 pod 准备就绪之前,请注意以下事项:
- 任何资源消耗均不受分层配额的限制。
- 创建/更新
HierarchicalResourceQuota
失败。 - 如果启用了分层可观测性,无需应用标签即可创建 Pod。
如果上述操作无法解决此问题,请向我们报告情况以便进行分析,最好是您可以使用下列命令来获取日志:
kubectl logs -n hnc-system deployment/gke-hc-controller-manager -c manager
后续步骤
- 观察分层工作负载。
- 如需详细了解您可能需要使用 HNC 完成的常见任务,请参阅 HNC 用户指南:操作方法。