在Kubernetes中,命名空間是一種隔離不同應用程序資源的方式。除了CPU和存儲資源之外,內存也是容器運行所需的重要資源之一。為了確保應用程序的穩(wěn)定運行,我們可以為每個命名空間配置最小和最大內存約束。本教程介紹如何設置在名字空間中運行的容器所使用的內存的最小值和最大值。
可以在 LimitRange 對象中指定最小和最大內存值。如果 Pod 不滿足 LimitRange 施加的約束, 則無法在名字空間中創(chuàng)建它。
一、準備開始
必須擁有一個 Kubernetes 的集群,同時必須配置 kubectl 命令行工具與集群通信。 建議在至少有兩個不作為控制平面主機的節(jié)點的集群上運行本教程。 如果還沒有集群,可以通過 Minikube 構建一個自己的集群,或者可以使用下面的 Kubernetes 練習環(huán)境之一:
- Killercoda
- 玩轉 Kubernetes
在集群里必須要有創(chuàng)建命名空間的權限。集群中的每個節(jié)點都必須至少有 1 GiB 的內存可供 Pod 使用。
二、創(chuàng)建命名空間
創(chuàng)建一個命名空間,以便在此練習中創(chuàng)建的資源與集群的其余資源隔離。
kubectl create namespace constraints-mem-example
三、創(chuàng)建LimitRange和Pod
下面是 LimitRange 的示例清單:
apiVersion: v1 kind: LimitRange metadata: name: mem-min-max-demo-lr spec: limits: - max: memory: 1Gi min: memory: 500Mi type: Container
創(chuàng)建 LimitRange:
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints.yaml --namespace=constraints-mem-example
查看 LimitRange 的詳情:
kubectl get limitrange mem-min-max-demo-lr --namespace=constraints-mem-example --output=yaml
輸出顯示預期的最小和最大內存約束。 但請注意,即使沒有在 LimitRange 的配置文件中指定默認值,默認值也會自動生成。
limits: - default: memory: 1Gi defaultRequest: memory: 1Gi max: memory: 1Gi min: memory: 500Mi type: Container
現(xiàn)在,每當在 constraints-mem-example 命名空間中創(chuàng)建 Pod 時,Kubernetes 就會執(zhí)行下面的步驟:
- 如果 Pod 中的任何容器未聲明自己的內存請求和限制,控制面將為該容器設置默認的內存請求和限制。
確保該 Pod 中的每個容器的內存請求至少 500 MiB; - 確保該 Pod 中每個容器內存請求不大于 1 GiB;
- 以下為包含一個容器的 Pod 清單。該容器聲明了 600 MiB 的內存請求和 800 MiB 的內存限制, 這些滿足了 LimitRange 施加的最小和最大內存約束。
apiVersion: v1 kind: Pod metadata: name: constraints-mem-demo spec: containers: - name: constraints-mem-demo-ctr image: nginx resources: limits: memory: "800Mi" requests: memory: "600Mi"
創(chuàng)建 Pod:
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod.yaml --namespace=constraints-mem-example
確認 Pod 正在運行,并且其容器處于健康狀態(tài):
kubectl get pod constraints-mem-demo --namespace=constraints-mem-example
查看 Pod 詳情:
kubectl get pod constraints-mem-demo --output=yaml --namespace=constraints-mem-example
輸出結果顯示該 Pod 的容器的內存請求為 600 MiB,內存限制為 800 MiB。 這些滿足這個命名空間中 LimitRange 設定的限制范圍。
resources: limits: memory: 800Mi requests: memory: 600Mi
刪除創(chuàng)建的 Pod:
kubectl delete pod constraints-mem-demo --namespace=constraints-mem-example
四、超過最大限制的Pod
以下為包含一個容器的 Pod 的清單。這個容器聲明了 800 MiB 的內存請求和 1.5 GiB 的內存限制。
apiVersion: v1 kind: Pod metadata: name: constraints-mem-demo-2 spec: containers: - name: constraints-mem-demo-2-ctr image: nginx resources: limits: memory: "1.5Gi" requests: memory: "800Mi"
嘗試創(chuàng)建 Pod:
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod-2.yaml --namespace=constraints-mem-example
輸出結果顯示 Pod 沒有創(chuàng)建成功,因為它定義了一個容器的內存請求超過了允許的值。
Error from server (Forbidden): error when creating "examples/admin/resource/memory-constraints-pod-2.yaml": pods "constraints-mem-demo-2" is forbidden: maximum memory usage per Container is 1Gi, but limit is 1536Mi.
五、不滿足最小請求的Pod
以下為只有一個容器的 Pod 的清單。這個容器聲明了 100 MiB 的內存請求和 800 MiB 的內存限制。
apiVersion: v1 kind: Pod metadata: name: constraints-mem-demo-3 spec: containers: - name: constraints-mem-demo-3-ctr image: nginx resources: limits: memory: "800Mi" requests: memory: "100Mi"
嘗試創(chuàng)建 Pod:
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod-3.yaml --namespace=constraints-mem-example
輸出結果顯示 Pod 沒有創(chuàng)建成功,因為它定義了一個容器的內存請求小于強制要求的最小值:
Error from server (Forbidden): error when creating "examples/admin/resource/memory-constraints-pod-3.yaml": pods "constraints-mem-demo-3" is forbidden: minimum memory usage per Container is 500Mi, but request is 100Mi.
六、沒有聲明請求/限制的Pod
創(chuàng)建一個沒有聲明內存請求和限制的 Pod。以下為只有一個容器的 Pod 清單。該容器沒有聲明內存請求,也沒有聲明內存限制。
apiVersion: v1 kind: Pod metadata: name: constraints-mem-demo-4 spec: containers: - name: constraints-mem-demo-4-ctr image: nginx
創(chuàng)建 Pod:
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod-4.yaml --namespace=constraints-mem-example
查看 Pod 詳情:
kubectl get pod constraints-mem-demo-4 --namespace=constraints-mem-example --output=yaml
輸出結果顯示 Pod 的唯一容器內存請求為 1 GiB,內存限制為 1 GiB。容器怎樣獲得那些數(shù)值呢?
resources: limits: memory: 1Gi requests: memory: 1Gi
因為 Pod 沒有為容器聲明任何內存請求和限制,集群會從 LimitRange 獲取默認的內存請求和限制。 應用于容器。
這意味著 Pod 的定義會顯示這些值??梢酝ㄟ^ kubectl describe 查看:
# 查看輸出結果中的 "Requests:" 的值 kubectl describe pod constraints-mem-demo-4 --namespace=constraints-mem-example
此時, Pod 可能已經運行起來也可能沒有運行起來。 回想一下我們本次任務的先決條件是每個節(jié)點都至少有 1 GiB 的內存。 如果每個節(jié)點都只有 1 GiB 的內存,那將沒有一個節(jié)點擁有足夠的可分配內存來滿足 1 GiB 的內存請求。
刪除 Pod:
kubectl delete pod constraints-mem-demo-4 --namespace=constraints-mem-example
七、強制執(zhí)行最小/最大限制
LimitRange 為命名空間設定的最小和最大內存限制只有在 Pod 創(chuàng)建和更新時才會強制執(zhí)行。 如果更新 LimitRange,它不會影響此前創(chuàng)建的 Pod。
八、設置內存最小/最大限制動因
作為集群管理員,可能想規(guī)定 Pod 可以使用的內存總量限制。例如:
1、集群的每個節(jié)點有 2 GiB 內存。不想接受任何請求超過 2 GiB 的 Pod,因為集群中沒有節(jié)點可以滿足。
2、集群由生產部門和開發(fā)部門共享。希望允許產品部門的負載最多耗用 8 GiB 內存, 但是開發(fā)部門的負載最多可使用 512 MiB。 這時,可以為產品部門和開發(fā)部門分別創(chuàng)建名字空間,并為各個名字空間設置內存約束。
九、清理
刪除命名空間:
kubectl delete namespace constraints-mem-example