從 Request/Limit 走到 LimitRange#
前面兩章已經介紹了 Request 與 Limit,以及作為資源分組單位的 Namespace。把兩者結合起來,自然會出現一個新的需求:「能不能在 Namespace 層級替每個容器設一組合理的預設值,並且擋掉不合理的設定?」
預設情況下,Kubernetes 對容器內的資源使用是不設限的。如果 Pod 沒有自己宣告 Request 與 Limit,就有機會直接吃掉整個節點的資源。LimitRange 就是 Namespace 層級用來規範這件事的政策物件(Policy Object)。
LimitRange 能做什麼#
LimitRange 依附在某個 Namespace 之下,可以同時提供以下幾種能力:
- 對 Namespace 中的每個 Pod 或 Container 設定資源使用的上下限。
- 對每個 PersistentVolumeClaim 可申請的儲存空間設定上下限。
- 控制同一種資源的 Request 與 Limit 比值。
- 替沒有自行宣告資源的容器,注入預設的 Request 與 Limit。
動手實作#
建立 Namespace#
kubectl create ns demo-namespace把這個 Namespace 設為當前 context 的預設值:
kubectl config set-context --current --namespace=demo-namespace建立提供預設值的 LimitRange#
# limit-range.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: limit-range
spec:
limits:
- default:
cpu: 1000m
memory: 500Mi
defaultRequest:
cpu: 500m
memory: 200Mi
type: Container查看建立好的 LimitRange:
kubectl get limitrange limit-range --output=yaml擷取重點輸出:
limits:
- default:
cpu: "1"
memory: 500Mi
defaultRequest:
cpu: 500m
memory: 200Mi
type: ContainerLimitRange 建好之後,這個 Namespace 內接下來的容器有兩種情況:
- 容器沒有自己宣告 Request 與 Limit:Kubernetes 會用 LimitRange 中的
defaultRequest與default自動補上。 - 容器有宣告 Request 或 Limit:必須落在 LimitRange 的範圍內,否則會被擋下來。
換成清楚的條件:
- Pod 內任一容器若沒有宣告 Request/Limit,會被自動帶入 LimitRange 的預設值。
- 每個容器宣告的 Request 至少要
>= limits.defaultRequest。 - 每個容器宣告的 Limit 至少要
<= limits.default。
建立一個沒有宣告資源的 Pod#
# limit-range-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: limit-range-pod
spec:
containers:
- name: default-limit-range-pod
image: nginx部署:
kubectl apply -f ./limit-range-pod.yaml查看 Pod 的 spec,確認 LimitRange 真的有把預設值塞進來:
kubectl get pod limit-range-pod --output=yaml預期會看到:
containers:
- image: nginx
imagePullPolicy: Always
name: limit-range-pod
resources:
limits:
cpu: "1"
memory: 500Mi
requests:
cpu: 500m
memory: 200Mi嘗試建立超出範圍的 Pod#
當 Pod 宣告的 CPU Limit 超過 LimitRange 的最大值時,Kubernetes 會直接拒絕:
Error from server (Forbidden): error when creating "examples/admin/resource/limit-range-pod.yaml":
pods "limit-range-pod" is forbidden: maximum cpu usage per Container is 800m, but limit is 1500m.反過來,當宣告的 CPU Request 低於 LimitRange 規範的最小值時,也會被擋:
Error from server (Forbidden): error when creating "examples/admin/resource/limit-range-pod.yaml":
pods "limit-range-pod" is forbidden: minimum cpu usage per Container is 200m, but request is 100m.小結#
Namespace 把資源切成不同分組,LimitRange 在分組內提供了「預設值 + 上下限」的雙重保護。實務上常會再搭配 ResourceQuota,從 Namespace 整體可用資源、可建立物件數量等角度做進一步的把關,讓不同部門能在同一個叢集中安心共用資源。
原文出處#
- GitHub:https://github.com/MikeHsu0618/2022-ithelp/tree/main/Day23
- iThome:https://ithelp.ithome.com.tw/articles/10296817