一 為啥需要為命名空間里面添加pod添加默認的requests和limits?
通過前面的學習我們已經知道,如果節點上面的pod沒有設置requests和limits,這些容器就會受那些設置了的控制,一旦出現節點內存資源超賣,這些未被設置的pod則會優先被kubernetes清除,所以對於每個pod而言,都應當給設定requests和limits值是個不錯的選擇。
1.1 介紹limitRange資源
limitRange不僅支持用戶給命名空間里面的pod每種資源配置最大最小值,甚至還會在沒有顯性的申明下,還會給容器添加系統的默認配值,更詳細的描述如圖所示
- 圖中很好的顯示了,當創建podA的時候,由於里面的requests和Limits值超過了LimitRange的預設置,所以無法成功的創建
- 而在創建pod B的時候由於沒有設置默認的requests和limits的值在,則准入插件會根據默認值為它添加這2項
- 如果命名空間里面沒有LimitRange的話,當pod申請的資源大於節點的資源的時候API服務器還是會接收這個請求,但是卻無法進行調度
- limitRange資源參數limit的作用對象始終是每個獨立的pod,容器或者是其他類型對象,始終不會是某個命名空間的limits總和,實際上總和是由ResourceQuota對象來指定
1.2 創建一個LimitRange對象
apiVersion: v1 kind: LimitRange metadata: name: example spec: limits: - type: Pod min: cpu: 50m memory: 5Mi max: cpu: 1 memory: 1Gi - type: Container defaultRequest: cpu: 100m memory: 10Mi default: cpu: 200m memory: 100Mi min: cpu: 50m memory: 5Mi max: cpu: 1 memory: 1Gi maxLimitRequestRatio: cpu: 4 memory: 10 - type: PersistentVolumeClaim min: storage: 1Gi max: storage: 10Gi
- LimitRange中以type為分類可以限制各種各種類型的資源,第一項限制了pod中容器requests和limits之和最大值和最小值區間
- 第二項設置了pod中每個容器在沒有配置的時候默認添加的requests和limits的值以及每個容器的內存以及cpu最小最大值,和最大值與最小值的比值限制等
- 並且可以限制pvc的最大值以及最小值
- 也可以單獨的將這些type進行拆分,之后pod在通過API的准入插件的時候,會將所有的這些type合並起來
- 如果在修改了LimitRange之后,之前集群已經創建的pod規則不會收到影響(這里有個疑問,如果pod在LimitRange資源創建之前就已經好了,后來由於某種原因需要重新調度,並且還是沿用之前pod的requests和limits,我覺得還是會受到影響)
二 限制命名空間的資源總量
2.1 kubernetes通過ResourceQuota資源對命名空間的資源總量進行控制
資源配額的作用是限制某個命名空間里面各種資源的最大使用量,已經創建的pod不會被限制,例如當在創建某個pod的時候,申請的pod的內存加上集群中已經存在的pod的內存總量超過ResourceQuota,那么API服務器將會決絕接收這個pod的申請,並且除了容器的cpu,內存等這些基礎資源,同時也可以限制其他的API類型資源,例如RC,RS等等一系列的資源使用量
2.2 為CPU和內存使用量創建ResourceQuota
apiVersion: v1 kind: ResourceQuota metadata: name: cpu-and-mem spec: hard: requests.cpu: 400m requests.memory: 200Mi limits.cpu: 600m limits.memory: 500Mi
- 這個ResourceQuota分別對命名空間里面的requests.cpu,requests.memory,limits.cpu,limits.memory的總量總出了限制
- 區別於LimitRange針對的對象是pod以及容器,ResourceQuota針對的對象是命名空間這些資源的總量
2.3 查看配額以及配額使用情況
[root@node01 Chapter14]# k describe quota Name: cpu-and-mem Namespace: default Resource Used Hard -------- ---- ---- limits.cpu 1 600m limits.memory 20Mi 500Mi requests.cpu 2 400m requests.memory 50Mi 200Mi
- 這些資源是之前就已經創建了的,后面創建的ResourceQuota無法對其起到限制作用
- 需要注意的一點是在創建的ResourceQuota的時候集群里面必須已經有LimitRange資源,否則在創建那些未設定requests和limits的pod的時候無法納入統計,或者導致ResourceQuota統計的資源不准確
2.4 為持久化存儲指定配額
apiVersion: v1 kind: ResourceQuota metadata: name: storage spec: hard: requests.storage: 500Gi ssd.storageclass.storage.k8s.io/requests.storage: 300Gi standard.storageclass.storage.k8s.io/requests.storage: 1Ti
- 系統允許在這個命名空間里面添加最大的存儲為500Gi
- 第二項是ssd的storage的配置最大為300Gi
- 第三項是低性能的磁盤的額度為1Ti
2.5 限制集群資源可創建對象
apiVersion: v1 kind: ResourceQuota metadata: name: quota-objects spec: hard: pods: 10 replicationcontrollers: 5 secrets: 10 configmaps: 10 persistentvolumeclaims: 4 services: 5 services.loadbalancers: 1 services.nodeports: 2 ssd.storageclass.storage.k8s.io/persistenevolumeclaims: 2
- 上面的代碼不言而喻,分別對命名空間里面的每種資源的數量數額進行限制
2.6 為特定的狀態的pod或者Qos等級的pod指定配額
先來解釋一下,可以選擇的狀態有哪幾種
-
- BestEffort 前面已經介紹過,即pod未被設置任何的requests和limits
- NotBestEffort,即所有的配置了requests和limits的pod
- Termination,這個不好理解,可以直接理解為pod的spec中配置了activeDeadlineSecond屬性的pod,而這個屬性意思就是當pod被標記為failed的時候pod還可以在節點上運行的時間
- NotTermination,這個意思是pod未加入這個activeDeadlineSecond屬性的pod
對於BestEffort和NotTermination的范圍,只需要pod在集群中的數量,而對於NotBestEffort以及Termination狀態的pod除了需要添加數量外,還需要添加requests以及limits,一個示范例子如下所示
apiVersion: v1 kind: ResourceQuota metadata: name: besteffort-notterminating-pods spec: scopes: - BestEffort - NotTerminating hard: pods: 40
三 監控集群中pod的資源使用量
注意:這里只對原理進行說明,不對實際的操作以及如何部署相關的應用進行展開
3.1 如何收集每個節點上面的pod的資源使用情況
kubelet自身包含一個cAdvisor的agent,它會收集整個節點上容器的消耗情況,之后將信息匯報給Heapster的組件