準(zhǔn)入控制
一、什么是K8S之準(zhǔn)入控制
就是在創(chuàng)建資源經(jīng)過(guò)身份驗(yàn)證之后,kube-apiserver在數(shù)據(jù)寫(xiě)入etcd之前做一次攔截,然后對(duì)資源進(jìn)行更改、判斷正確性等操作。
-
LimitRange,ResourceQuota
目的:能控制特定命名空間中的資源使用量,最終實(shí)現(xiàn)集群的公平使用和成本的控制
-
LimitRange:為Pod添加默認(rèn)的計(jì)算資源需求和計(jì)算資源限制;以及存儲(chǔ)資源需求和存儲(chǔ)資源限制;
支持分別在容器和Pod級(jí)別進(jìn)行限制;
比如:指定名稱(chēng)空間下每個(gè)Pod CPU、內(nèi)存的最低最高額度 -
ResourceQuota:限制資源數(shù)量,限制計(jì)算資源總量,存儲(chǔ)資源總量;
比如:指定名稱(chēng)空間下,只允許創(chuàng)建Pod、svc的數(shù)量, 所有Pod CPU、內(nèi)存的最低最高額度
-
需要實(shí)現(xiàn)的功能如下:
限制運(yùn)行狀態(tài)的Pod的計(jì)算資源用量
限制持久存儲(chǔ)卷的數(shù)量以控制對(duì)存儲(chǔ)的訪(fǎng)問(wèn)
限制負(fù)載均衡器的數(shù)量以控制成本
防止濫用網(wǎng)絡(luò)端口
提供默認(rèn)的計(jì)算資源Requests以便于系統(tǒng)做出更優(yōu)化的調(diào)度
-
一個(gè) LimitRange(限制范圍) 對(duì)象提供的限制能夠做到:
在一個(gè)命名空間中實(shí)施對(duì)每個(gè) Pod 或 Container 最小和最大的資源使用量的限制。
在一個(gè)命名空間中實(shí)施對(duì)每個(gè) PersistentVolumeClaim 能申請(qǐng)的最小和最大的存儲(chǔ)空間大小的限制。
在一個(gè)命名空間中實(shí)施對(duì)一種資源的申請(qǐng)值和限制值的比值的控制。
設(shè)置一個(gè)命名空間中對(duì)計(jì)算資源的默認(rèn)申請(qǐng)/限制值,并且自動(dòng)的在運(yùn)行時(shí)注入到多個(gè) Container 中。
二、啟用 LimitRang
對(duì) LimitRange 的支持自 Kubernetes 1.10 版本默認(rèn)啟用。
LimitRange 支持在很多 Kubernetes 發(fā)行版本中也是默認(rèn)啟用的。
LimitRange 的名稱(chēng)必須是合法的 DNS 子域名。
三、限制范圍總覽
管理員在一個(gè)命名空間內(nèi)創(chuàng)建一個(gè) LimitRange 對(duì)象。
用戶(hù)在命名空間內(nèi)創(chuàng)建 Pod ,Container 和 PersistentVolumeClaim 等資源。
LimitRanger 準(zhǔn)入控制器對(duì)所有沒(méi)有設(shè)置計(jì)算資源需求的 Pod 和 Container 設(shè)置默認(rèn)值與限制值, 并跟蹤其使用量以保證沒(méi)有超出命名空間中存在的任意 LimitRange 對(duì)象中的最小、最大資源使用量以及使用量比值。
若創(chuàng)建或更新資源(Pod、 Container、PersistentVolumeClaim)違反了 LimitRange 的約束, 向 API 服務(wù)器的請(qǐng)求會(huì)失敗,并返回 HTTP 狀態(tài)碼 403 FORBIDDEN 與描述哪一項(xiàng)約束被違反的消息。
若命名空間中的 LimitRange 啟用了對(duì) cpu 和 memory 的限制, 用戶(hù)必須指定這些值的需求使用量與限制使用量。否則,系統(tǒng)將會(huì)拒絕創(chuàng)建 Pod。
LimitRange 的驗(yàn)證僅在 Pod 準(zhǔn)入階段進(jìn)行,不對(duì)正在運(yùn)行的 Pod 進(jìn)行驗(yàn)證
示例1: 創(chuàng)建LimitRange準(zhǔn)入控制策略
- 對(duì)Pod、容器、PVC等資源進(jìn)行限制
[root@k8s-master authfiles]# cat limitrange-demo.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: core-resource-limits
namespace: dev #名字空間級(jí)別資源 對(duì)整個(gè)名額空間生效
spec:
limits:
- type: Pod #對(duì)Pod限制
max:
cpu: "4" #CPU最大不能超過(guò)4核
memory: "4Gi" #內(nèi)存不能超過(guò)4G
min:
cpu: "500m" #CPU最小不能小于500m
memory: "16Mi" #內(nèi)存不能小于16M
- type: Container #對(duì)容器作限制
max:
cpu: "4"
memory: "1Gi"
min:
cpu: "100m"
memory: "4Mi"
default: #上閾值 #如果容器中沒(méi)有做requests或limits作限制,則附加的默認(rèn)值
cpu: "2"
memory: "512Mi"
defaultRequest: #下閾值
cpu: "500m"
memory: "64Mi"
maxLimitRequestRatio: #最大限制請(qǐng)求比率 上閾值/下閾值 也可以用倍數(shù)做限制
cpu: "4"
- type: PersistentVolumeClaim #對(duì)PV做限制
max:
storage: "10Gi"
min:
storage: "1Gi"
default:
storage: "5Gi"
defaultRequest:
storage: "1Gi"
maxLimitRequestRatio: #沒(méi)有下閾值 也可以用倍數(shù)做限制
storage: "5"
- 創(chuàng)建LimitRange策略
[root@k8s-master authfiles]# kubectl apply -f limitrange-demo.yaml
limitrange/core-resource-limits created
[root@k8s-master authfiles]# kubectl get limitrange -n dev
NAME CREATED AT
core-resource-limits 2021-08-25T02:29:04Z
[root@k8s-master authfiles]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
deployment-demo-fb544c5d8-4jvgh 1/1 Running 0 16h
deployment-demo-fb544c5d8-7fq8f 1/1 Running 0 16h
deployment-demo-fb544c5d8-hdsz4 1/1 Running 0 16h
deployment-demo-fb544c5d8-qq7mp 1/1 Running 0 16h
[root@k8s-master authfiles]# kubectl describe limitrange core-resource-limits -n dev
Name: core-resource-limits
Namespace: dev
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Pod cpu 500m 4 - - -
Pod memory 16Mi 4Gi - - -
Container memory 4Mi 1Gi 64Mi 512Mi -
Container cpu 100m 4 500m 2 4
PersistentVolumeClaim storage 1Gi 10Gi 1Gi 5Gi 5
- 驗(yàn)證測(cè)試策略是否生效
[root@k8s-master authfiles]# kubectl run testpod-$RANDOM --image="ikubernetes/demoapp:v1.0" -n dev
pod/testpod created
[root@k8s-master authfiles]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
testpod-1017 1/1 Running 0 93s
[root@k8s-master authfiles]# kubectl get pods testpod -n dev -o yaml
...
spec:
containers:
- image: kubernetes/demoapp:v1.0
imagePullPolicy: IfNotPresent
name: testpod
resources: #默認(rèn)值
limits:
cpu: "2" #最高2核
memory: 512Mi
requests:
cpu: 500m #最低500m
memory: 64Mi
- 創(chuàng)建小于內(nèi)存限制的Pod 創(chuàng)建失敗
[root@k8s-master authfiles]# kubectl run testpod-$RANDOM --image="ikubernetes/demoapp:v1.0" -n dev --limits='cpu=2,memory=1Gi' --requests='cpu=1,memory=8Mi'
Error from server (Forbidden): pods "testpod-10340" is forbidden: minimum memory usage per Pod is 16Mi, but request is 8388608
ResourceQuota
- ResourceQuota資源可限制名稱(chēng)空間中處于非終止?fàn)顟B(tài)的所有Pod對(duì)象的計(jì)算資源需求及計(jì)算資源限制總量。
- cpu或requests.cpu: CPU資源相關(guān)請(qǐng)求的總量限額;
- memory或requests.memory: 內(nèi)存資源相關(guān)請(qǐng)求的總量限額;
- limits.cpu: CPU資源相關(guān)限制的總量限額;
- limits.memory:內(nèi)存資源相關(guān)限制的總量限額;
- Rescurcebuota資源還支持為本地名稱(chēng)空間中的PVC存儲(chǔ)資源的需求總量和限制總量提供限額,它能夠分別從名稱(chēng)空間中的全部PVC、隸屬于特定存儲(chǔ)類(lèi)的PVC以及基于本地臨時(shí)存儲(chǔ)的PVC三個(gè)類(lèi)別分別進(jìn)行定義。
- requests.storage:所有PVC存儲(chǔ)需求的總量限額;空間限制;
- persistentvolumeclaims:可以創(chuàng)建的PVC總數(shù)限額;數(shù)量限制;
- <storage-class-name>.storageclass.storage.k8s.io/requests.storage:特定的存儲(chǔ)類(lèi)上可使用的所有PVC存儲(chǔ)需求的總量限額;
- <storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims:特定的存儲(chǔ)類(lèi)上可使用的PVC總數(shù)限額;
- requests.ephemeral-storage:所有Pod可以使用的本地臨時(shí)存儲(chǔ)資源的requets總量;
- limits.ephemeral-storage:所有Pod可用的本地臨時(shí)存儲(chǔ)資源的limits總量。
示例2:創(chuàng)建ResourceQuota準(zhǔn)入控制策略
[root@k8s-master authfiles]# cat resourcequota-demo.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: resourcequota-demo
namespace: dev
spec:
hard :
pods: "5" #Pod總量
count/services: "5" #svc總量
count/configmaps: "5"
count/secrets: "5"
count/cronjobs.batch: "2"
requests.cpu: "2" #cpu下閾值總量
requests.memory: "4Gi"
limits.cpu: "4" #cpu上閾值總量
limits.memory: "8Gi"
count/deployments.apps: "2"
count/statefulsets.apps: "2"
persistentvolumeclaims: "6"
requests.storage: "20Gi"
longhorn.storageclass.storage.k8s.io/requests.storage: "20Gi"
longhorn.storageclass.storage.k8s.io/persistentvolumeclaims: "6"
[root@k8s-master authfiles]# kubectl apply -f resourcequota-demo.yaml
resourcequota/resourcequota-demo created
[root@k8s-master authfiles]# kubectl get ResourceQuota -n dev
NAME AGE REQUEST LIMIT
resourcequota-demo 33s count/configmaps: 0/5, count/cronjobs.batch: 0/2, count/deployments.apps: 0/2, count/secrets: 3/5, count/services: 0/5, count/statefulsets.apps: 0/2, longhorn.storageclass.storage.k8s.io/persistentvolumeclaims: 0/6, longhorn.storageclass.storage.k8s.io/requests.storage: 0/20Gi, persistentvolumeclaims: 0/6, pods: 1/5, requests.cpu: 500m/2, requests.memory: 64Mi/4Gi, requests.storage: 0/20Gi limits.cpu: 2/4, limits.memory: 512Mi/8Gi
- 驗(yàn)證測(cè)試策略是否生效
[root@k8s-master authfiles]# kubectl describe resourcequota resourcequota-demo -n dev
Name: resourcequota-demo
Namespace: dev
Resource Used Hard
-------- ---- ----
count/configmaps 0 5
count/cronjobs.batch 0 2
count/deployments.apps 0 2
count/secrets 3 5
count/services 0 5
count/statefulsets.apps 0 2
limits.cpu 2 4
limits.memory 512Mi 8Gi
longhorn.storageclass.storage.k8s.io/persistentvolumeclaims 0 6
longhorn.storageclass.storage.k8s.io/requests.storage 0 20Gi
persistentvolumeclaims 0 6
pods 1 5
requests.cpu 500m 2
requests.memory 64Mi 4Gi
requests.storage 0 20Gi
[root@k8s-master authfiles]# kubectl run testpod-$RANDOM --image="ikubernetes/demoapp:v1.0" -n dev
pod/testpod-10678 created
[root@k8s-master authfiles]# kubectl describe resourcequota resourcequota-demo -n dev
Name: resourcequota-demo
Namespace: dev
Resource Used Hard
-------- ---- ----
count/configmaps 0 5
count/cronjobs.batch 0 2
count/deployments.apps 0 2
count/secrets 3 5
count/services 0 5
count/statefulsets.apps 0 2
limits.cpu 4 4 #配額已使用完 無(wú)法在創(chuàng)建Pod
limits.memory 1Gi 8Gi
longhorn.storageclass.storage.k8s.io/persistentvolumeclaims 0 6
longhorn.storageclass.storage.k8s.io/requests.storage 0 20Gi
persistentvolumeclaims 0 6
pods 2 5
requests.cpu 1 2
requests.memory 128Mi 4Gi
requests.storage 0 20Gi
[root@k8s-master authfiles]# kubectl run testpod-$RANDOM --image="ikubernetes/demoapp:v1.0" -n dev
Error from server (Forbidden): pods "testpod-30200" is forbidden: exceeded quota: resourcequota-demo, requested: limits.cpu=2, used: limits.cpu=4, limited: limits.cpu=4