命名空间的资源总量上限是怎么执行的?超了会在哪一步失败?为什么 Deployment 看起来创建成功了 Pod 却起不来?这篇用一个 ResourceQuota 把记账、拒绝点、与 LimitRange 的搭配、对象数量配额和 scope 范围都量了一遍。
ResourceQuota q(pods 3、requests.cpu 1、limits.cpu 2、requests.memory 1Gi、limits.memory 1Gi、count/configmaps 4)刚创建:count/configmaps=1/4, limits.cpu=0/2, limits.memory=0/1Gi, pods=0/3, requests.cpu=0/1, requests.memory=0/1Gi 创建 p1(requests cpu 400m / memory 200Mi,limits cpu 500m / memory 300Mi)之后:count/configmaps=1/4, limits.cpu=500m/2, limits.memory=300Mi/1Gi, pods=1/3, requests.cpu=400m/1, requests.memory=200Mi/1Gi 创建 p2(requests cpu 400m / memory 200Mi,limits cpu 500m / memory 300Mi)之后:count/configmaps=1/4, limits.cpu=1/2, limits.memory=600Mi/1Gi, pods=2/3, requests.cpu=800m/1, requests.memory=400Mi/1Gi
ResourceQuota 对每种资源分别记账。创建 p1(requests cpu 400m / memory 200Mi,limits cpu 500m / memory 300Mi)之后,status.used 里 pods=1/3、requests.cpu=400m/1、limits.cpu=500m/2;再创建 p2,requests.cpu 到 800m、limits.memory 到 600Mi。用量在创建那一刻就更新。count/configmaps 这种写法可以给任何命名空间级资源按个数计数。
第 3 个同样的 Pod(requests.cpu 会变成 1200m,超过 1):退出码 1;Error from server (Forbidden): error when creating "STDIN": pods "p3" is forbidden: exceeded quota: q, requested: requests.cpu=400m, used: requests.cpu=800m, limited: requests.cpu=1
换一个小的(100m / 50Mi,第 3 个 Pod):退出码 0;pod/s1 created;count/configmaps=1/4, limits.cpu=1100m/2, limits.memory=650Mi/1Gi, pods=3/3, requests.cpu=900m/1, requests.memory=450Mi/1Gi
再来一个小的(第 4 个 Pod,pods 已经 3/3):退出码 1;Error from server (Forbidden): error when creating "STDIN": pods "s2" is forbidden: exceeded quota: q, requested: pods=1, used: pods=3, limited: pods=3
用 Deployment 创建时,Deployment 本身是创建成功的,被拒绝的是它的 ReplicaSet 去创建 Pod 的那一步:
kubectl get deploy web:web 2/5 2 2 8s
ReplicaSet 的 FailedCreate 事件:Error creating: pods "web-7c4988568c-wqdnl" is forbidden: exceeded quota: q, requested: pods=1, used: pods=3, limited: pods=3
配额:count/configmaps=1/4, limits.cpu=300m/2, limits.memory=150Mi/1Gi, pods=3/3, requests.cpu=300m/1, requests.memory=150Mi/1Gi准入阶段、创建对象的那个请求被拒绝:第 3 个 400m 的 Pod 报 exceeded quota: q, requested: requests.cpu=400m, used: requests.cpu=800m, limited: requests.cpu=1,小 Pod 能放进去直到 pods=3/3,再多一个报 requested: pods=1, used: pods=3, limited: pods=3。用 Deployment 时,Deployment 本身创建成功,失败的是它的 ReplicaSet 去创建 Pod 那一步:kubectl get deploy 显示 2/5,原因要看 ReplicaSet 的 FailedCreate 事件。
什么都没写的 Pod:退出码 1;Error from server (Forbidden): error when creating "STDIN": pods "naked" is forbidden: failed quota: q: must specify limits.cpu for: c; limits.memory for: c; requests.cpu for: c; requests.memory for: c 同命名空间加了一个 LimitRange(补默认值)之后同一个 Pod:退出码 0;pod/naked created;count/configmaps=1/4, limits.cpu=300m/2, limits.memory=150Mi/1Gi, pods=2/3, requests.cpu=200m/1, requests.memory=100Mi/1Gi
配额里管着 requests / limits 的时候,没写这些字段的 Pod 直接被拒:failed quota: q: must specify limits.cpu for: c; limits.memory for: c; requests.cpu for: c; requests.memory for: c。同命名空间加一个 LimitRange 补默认值,同一个 Pod 就能创建,并且按补完的值记账。ResourceQuota 管总量,LimitRange 管单个对象和默认值,常常成对使用。
count/configmaps 上限 4:命名空间里原有 kube-root-ca.crt,c0~c4 里成功创建了 3 个;count/configmaps=4/4, limits.cpu=100m/2, limits.memory=50Mi/1Gi, pods=1/3, requests.cpu=100m/1, requests.memory=50Mi/1Gi
再建一个:error: failed to create configmap: configmaps "one-more" is forbidden: exceeded quota: q, requested: count/configmaps=1, used: count/configmaps=4, limited: count/configmaps=4
另一个命名空间里 scopes: [BestEffort]、pods: 1 的配额:第 1 个 BestEffort Pod 成功;第 2 个:退出码 1;Error from server (Forbidden): error when creating "STDIN": pods "be2" is forbidden: exceeded quota: be, requested: pods=1, used: pods=1, limited: pods=1
Burstable 的 Pod 不受这个配额管:退出码 0;pod/bu1 created
配额 be 的用量:{"pods":"1"}(只数了 BestEffort 的那一个)
删除 be1 之后 be 的用量:{"pods":"0"}count/configmaps: 4 在命名空间里已有 kube-root-ca.crt 加 3 个之后拒绝第 5 个。scopes: [BestEffort] 让配额只统计 BestEffort 的 Pod:第 1 个 BestEffort Pod 通过,第 2 个被拒,Burstable 的 Pod 不受影响,status.used 只是 {pods: 1};删掉 Pod 之后 used 立刻回到 0。