目錄
- 目標(biāo)
- 一、啟動服務(wù)
- 二、創(chuàng)建命名空間
- 2.1、查看名字空間
- 2.2、創(chuàng)建名字空間
- 2.3、刪除名字空間
- 三、指定 CPU 請求和 CPU 限制
- 3.1、CPU 單位
- 3.2、設(shè)置超過節(jié)點能力的 CPU 請求
- 3.2.1、創(chuàng)建 Pod
- 3.2.2、Pod 的狀態(tài)
- 3.2.3、Pod 詳情
- 3.2.4、刪除 Pod
- 四、不限制CPU
- 總結(jié)
目標(biāo)
本篇文章我們將學(xué)習(xí),如何為容器設(shè)置 CPU request(請求) 和 CPU limit(限制)。 容器使用的 CPU 不能超過所配置的限制。 如果系統(tǒng)有空閑的 CPU 時間,則可以保證給容器分配其所請求數(shù)量的 CPU 資源。
一、啟動服務(wù)
在前面的章節(jié)中,有講解過 metrics-server 服務(wù),在這里,我們再次運行以下命令,啟動metrics-server :
minikube addons enable metrics-server
查看 metrics-server 資源API 是否可用,運行下面命令,則會輸出將包含一個對 metrics.k8s.io
的引用。
$ kubectl get apiservices NAME v1beta1.metrics.k8s.io
二、創(chuàng)建命名空間
在進(jìn)行資源分配之前,我們需要先創(chuàng)建一個命名空間,才能給這個空間分配資源。接下來我們先學(xué)習(xí)一下創(chuàng)建資源與集群的其余部分資源隔離。
在 Kubernetes 中,“名字空間(Namespace)”提供一種機(jī)制,將同一集群中的資源劃分為相互隔離的組。 同一名字空間內(nèi)的資源名稱要唯一,但跨名字空間時沒有這個要求。 名字空間作用域僅針對帶有名字空間的對象,例如 Deployment、Service 等, 這種作用域?qū)涸L問的對象不適用,例如 StorageClass、Node、PersistentVolume 等。
2.1、查看名字空間
初始狀態(tài)下,Kubernetes 具有三個名字空間:
- default 無名字空間對象的默認(rèn)名字空間
- kube-system 由 Kubernetes 系統(tǒng)創(chuàng)建的對象的名字空間
- kube-public 自動創(chuàng)建且被所有用戶可讀的名字空間(包括未經(jīng)身份認(rèn)證的)。此名字空間通常在某些資源在整個集群中可見且可公開讀取時被集群使用。此名字空間的公共方面只是一個約定,而不是一個必要條件。
我們可以通過使用 kubectl 的命令,來查看現(xiàn)有的命名空間:
$ kubectl get namespaces NAME STATUS AGE default Active 11d kube-system Active 11d kube-public Active 11d
如果想要查看某一個命名空間的詳情,也可以使用 kubectl describe namespaces
命令來查看:
$ kubectl describe namespaces <name> Name: default Labels: <none> Annotations: <none> Status: Active No resource quota. Resource Limits Type Resource Min Max Default ---- -------- --- --- --- Container cpu - - 100m
請注意,這些詳情同時顯示了資源配額(如果存在)以及資源限制區(qū)間。
資源配額跟蹤并聚合 Namespace 中資源的使用情況,并允許集群運營者定義 Namespace 可能消耗的 Hard 資源使用限制。
限制區(qū)間定義了單個實體在一個 Namespace 中可使用的最小/最大資源量約束。
名字空間可以處于下列兩個階段中的一個:
- Active 名字空間正在被使用中
- Terminating 名字空間正在被刪除,且不能被用于新對象。
2.2、創(chuàng)建名字空間
上面將的命名空間,都是當(dāng)前集群自帶的三個命名空間,那么我們能不能自己創(chuàng)建命名空間呢?答案是,肯定的,下面我們來學(xué)習(xí)兩種創(chuàng)建方式。
新建一個名為 my-namespace.yaml
的 YAML 文件,并寫入下列內(nèi)容:
apiVersion: v1 kind: Namespace metadata: name: <insert-namespace-name-here>
然后運行命令:
kubectl create -f ./my-namespace.yaml
或者,你可以使用下面的命令創(chuàng)建名字空間:
kubectl create namespace <insert-namespace-name-here>
2.3、刪除名字空間
可選字段 finalizers 允許觀察者們在名字空間被刪除時清除資源。 記住如果指定了一個不存在的終結(jié)器,名字空間仍會被創(chuàng)建, 但如果用戶試圖刪除它,它將陷入 Terminating 狀態(tài)。下面是刪除命名空間的命令:
$ kubectl delete namespaces <insert-some-namespace-name>
此命令會刪除當(dāng)前命名空間下面的所有內(nèi)容,刪除是異步的,所以有一段時間你會看到名字空間處于 Terminating 狀態(tài)。
三、指定 CPU 請求和 CPU 限制
要為容器指定 CPU 請求,請在容器資源清單中包含 resources: requests
字段。 要指定 CPU 限制,請包含 resources:limits
。
在本練習(xí)中,你將創(chuàng)建一個具有一個容器的 Pod。容器將會請求 0.5 個 CPU,而且最多限制使用 1 個 CPU。 pods/resource/cpu-request-limit.yaml
是 Pod 的配置文件:
apiVersion: v1 kind: Pod metadata: name: cpu-demo namespace: cpu-example spec: containers: - name: cpu-demo-ctr image: vish/stress resources: limits: cpu: "1" requests: cpu: "0.5" args: - -cpus - "2"
配置文件的 args 部分提供了容器啟動時的參數(shù)。 -cpus “2” 參數(shù)告訴容器嘗試使用 2 個 CPU。
1.創(chuàng)建 Pod:
$ kubectl apply -f https://k8s.io/examples/pods/resource/cpu-request-limit.yaml --namespace=cpu-example
2.驗證所創(chuàng)建的 Pod 處于 Running 狀態(tài)
$ kubectl get pod cpu-demo --namespace=cpu-example
3.查看顯示關(guān)于 Pod 的詳細(xì)信息:
$ kubectl get pod cpu-demo --output=yaml --namespace=cpu-example
輸出顯示 Pod 中的一個容器的 CPU 請求為 500 milli CPU,并且 CPU 限制為 1 個 CPU。
resources: limits: cpu: "1" requests: cpu: 500m
5.使用 kubectl top
命令來獲取該 Pod 的度量值數(shù)據(jù),我這里的輸出顯示 Pod 使用的是 974 milliCPU,即略低于 Pod 配置中指定的 1 個 CPU 的限制。
$ kubectl top pod cpu-demo --namespace=cpu-example NAME CPU(cores) MEMORY(bytes) cpu-demo 974m <something>
3.1、CPU 單位
CPU 資源以 CPU 單位度量。Kubernetes 中的一個 CPU 等同于:
- 1 個 AWS vCPU
- 1 個 GCP核心
- 1 個 Azure vCore
- 裸機(jī)上具有超線程能力的英特爾處理器上的 1 個超線程
小數(shù)值是可以使用的。一個請求 0.5 CPU 的容器保證會獲得請求 1 個 CPU 的容器的 CPU 的一半。 你可以使用后綴 m 表示毫。例如 100m CPU、100 milliCPU 和 0.1 CPU 都相同。 精度不能超過 1m。
CPU 請求只能使用絕對數(shù)量,而不是相對數(shù)量。0.1 在單核、雙核或 48 核計算機(jī)上的 CPU 數(shù)量值是一樣的。
刪除 Pod:
$ kubectl delete pod cpu-demo --namespace=cpu-example
3.2、設(shè)置超過節(jié)點能力的 CPU 請求
CPU 請求和限制與都與容器相關(guān),但是我們可以考慮一下 Pod 具有對應(yīng)的 CPU 請求和限制這樣的場景。 Pod 對 CPU 用量的請求等于 Pod 中所有容器的請求數(shù)量之和。 同樣,Pod 的 CPU 資源限制等于 Pod 中所有容器 CPU 資源限制數(shù)之和。
Pod 調(diào)度是基于資源請求值來進(jìn)行的。 僅在某節(jié)點具有足夠的 CPU 資源來滿足 Pod CPU 請求時,Pod 將會在對應(yīng)節(jié)點上運行:
接下來我們在目錄 pods/resource/cpu-request-limit-2.yaml
中創(chuàng)建一個 Pod,該 Pod 的 CPU 請求對于集群中任何節(jié)點的容量而言都會過大。 下面是 Pod 的配置文件,其中有一個容器。容器請求 100 個 CPU,這可能會超出集群中任何節(jié)點的容量。
apiVersion: v1 kind: Pod metadata: name: cpu-demo-2 namespace: cpu-example spec: containers: - name: cpu-demo-ctr-2 image: vish/stress resources: limits: cpu: "100" requests: cpu: "100" args: - -cpus - "2"
3.2.1、創(chuàng)建 Pod
執(zhí)行創(chuàng)建命令
$ kubectl apply -f https://k8s.io/examples/pods/resource/cpu-request-limit-2.yaml --namespace=cpu-example
3.2.2、Pod 的狀態(tài)
運行下列命令,查看該 Pod 的狀態(tài)
$ kubectl get pod cpu-demo-2 --namespace=cpu-example
輸出顯示 Pod 狀態(tài)為 Pending。也就是說,Pod 未被調(diào)度到任何節(jié)點上運行, 并且 Pod 將無限期地處于 Pending 狀態(tài):
NAME READY STATUS RESTARTS AGE cpu-demo-2 0/1 Pending 0 7m
3.2.3、Pod 詳情
可以輸入以下命令,查看有關(guān) Pod 的詳細(xì)信息,包含事件
$ kubectl describe pod cpu-demo-2 --namespace=cpu-example
輸出顯示由于節(jié)點上的 CPU 資源不足,無法調(diào)度容器:
Events: Reason Message ------ ------- FailedScheduling No nodes are available that match all of the following predicates:: Insufficient cpu (3).
3.2.4、刪除 Pod
當(dāng)然,我也可以使用命名刪除你的 Pod
$ kubectl delete pod cpu-demo-2 --namespace=cpu-example
四、不限制CPU
如果沒有為容器指定 CPU 限制,則會發(fā)生以下情況之一:
- 容器在可以使用的 CPU 資源上沒有上限。因而可以使用所在節(jié)點上所有的可用 CPU 資源。
- 容器在具有默認(rèn) CPU 限制的名字空間中運行,系統(tǒng)會自動為容器設(shè)置默認(rèn)限制。 集群管理員可以使用 LimitRange 指定 CPU 限制的默認(rèn)值。
如果為容器指定了 CPU 限制值但未為其設(shè)置 CPU 請求,Kubernetes 會自動為其 設(shè)置與 CPU 限制相同的 CPU 請求值。類似的,如果容器設(shè)置了內(nèi)存限制值但未設(shè)置 內(nèi)存請求值,Kubernetes 也會為其設(shè)置與內(nèi)存限制值相同的內(nèi)存請求。
總結(jié)
本篇文章通過配置集群中運行的容器的 CPU 請求和限制,你可以有效利用集群上可用的 CPU 資源。 通過將 Pod CPU 請求保持在較低水平,可以使 Pod 更有機(jī)會被調(diào)度。 通過使 CPU 限制大于 CPU 請求,你可以完成兩件事:
- Pod 可能會有突發(fā)性的活動,它可以利用碰巧可用的 CPU 資源。
- Pod 在突發(fā)負(fù)載期間可以使用的 CPU 資源數(shù)量仍被限制為合理的數(shù)量。