云原生|kubernetes|ResourceQuota 资源与准入控制器

前言:

ResourceQuota,直译资源配额

可为每个名称空间分别创建一个 ResourceQuota 对象,随后 ,用户在名 称空间中创建资源对象, ResourceQuota 准入控制器将跟踪使用情况以确保它不超过相应 ResourceQuota 对象中定义的系统资源限制。 用户创建或更新资源的操作违反配额约束将导 致请求失败, API Server 以 HTTP 状态代码“403 FORBIDDEN ”作为响应,并显示一条消 息以提示可能违反的约束。 不过,在名称空间上启用了 CPU 和内存等系统资源的配额后, 用户创建 Pod 对象时必须指定资源需求或资源限制,否则,会触发 ResourceQuota 准入控制 器拒绝执行相应的操作。

以上的定义比较模糊,大白话说明一下,第一,Resource指的的CPU,内存,pod副本数量这些,第二,该控制器是按照namespace来划分的,也就是说一个namespace定义一个ResourceQuota,该定义是通过资源清单文件来实现的,比如,有namespace A ,B,C, 那么,相对A 这个namespace,可以编写一个yaml文件,定义此namespace所能使用的资源额度,然后,在此namespace下的所有pod所使用的资源总和不可以超过yaml定义的资源配额。如果超出控制器定义的配额,新创建的pod将会失败,apiserver会报错。

下面,将以实际例子来讲述如何使用资源配额控制器。

一,

在namespace myrq 下创建resourcequota控制器,相关代码如下:

kubectl create ns myrq
cat quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: myrq
  namespace: myrq
spec:
  hard:
    pods: "2"

这个resourcequota仅仅定义了pod的副本,在namespace  myrq下的总配额是2

应用此yaml文件并查看resourcequota的详情:

kubectl apply -f quota.yaml
kubectl describe resourcequotas -n myrq myrq
root@k8s-master:~# kubectl describe resourcequotas -n myrq myrq
Name:       myrq
Namespace:  myrq
Resource    Used  Hard
--------    ----  ----
pods        0     2

此时的pods数量已使用是0,配额限制是2,此时查看myrq下的pod,可以发现确实是0个:

root@k8s-master:~# kubectl get po -n myrq 
No resources found in myrq namespace.

OK,现在使用配额,创建3个pod,看能不能成功:

kubectl create deployment nginx --image=nginx --replicas=3 -n myrq
root@k8s-master:~# kubectl describe deployments.apps -n myrq nginx 
Name:                   nginx
Namespace:              myrq
CreationTimestamp:      Sat, 21 Jan 2023 12:26:34 +0800
Labels:                 app=nginx
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=nginx
Replicas:               3 desired | 2 updated | 2 total | 0 available | 3 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=nginx
  Containers:
   nginx:
    Image:        nginx
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type             Status  Reason
  ----             ------  ------
  Available        False   MinimumReplicasUnavailable
  ReplicaFailure   True    FailedCreate
  Progressing      True    ReplicaSetUpdated
OldReplicaSets:    <none>
NewReplicaSet:     nginx-6799fc88d8 (2/3 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  16s   deployment-controller  Scaled up replica set nginx-6799fc88d8 to 3
root@k8s-master:~# kubectl get deployments.apps -n myrq 
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   2/3     2            2           2m42s

root@k8s-master:~# kubectl get po -n myrq 
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6799fc88d8-4rznt   1/1     Running   0          45s
nginx-6799fc88d8-bxf4w   1/1     Running   0          45s
root@k8s-master:~# kubectl describe resourcequotas -n myrq 
Name:       myrq
Namespace:  myrq
Resource    Used  Hard
--------    ----  ----
pods        2     2

OK,可以看到配额已经使用完了,但此deployment控制器是3个副本,因此只有两个pod创建成功,资源配额生效了。

在创建一个新的pod,能否成功呢?

kubectl create deployment nginx1 --image=nginx --replicas=1 -n myrq

可以看到,新的pod没有创建成功 

root@k8s-master:~# kubectl get deployments.apps -n myrq 
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
nginx    2/3     2            2           4m38s
nginx1   0/1     0            0           23s

提高配额:

从2提升到20

root@k8s-master:~# cat quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: myrq
  namespace: myrq
spec:
  hard:
    pods: "20"
root@k8s-master:~# kubectl apply -f quota.yaml 
resourcequota/myrq configured
root@k8s-master:~# kubectl describe resourcequotas -n myrq myrq 
Name:       myrq
Namespace:  myrq
Resource    Used  Hard
--------    ----  ----
pods        2     20

删除nginx1,重新部署,可以看到配额提高后,可以顺利部署了,三副本的nginx也自动恢复成了正常的状态:

root@k8s-master:~# kubectl delete deployments.apps -n myrq nginx1
deployment.apps "nginx1" deleted
root@k8s-master:~# kubectl create deployment nginx1 --image=nginx --replicas=1 -n myrq 
deployment.apps/nginx1 created
root@k8s-master:~# kubectl get deployments.apps -n myrq 
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
nginx    3/3     3            3           19m
nginx1   1/1     1            1           6m5s
root@k8s-master:~# kubectl describe resourcequotas -n myrq myrq 
Name:       myrq
Namespace:  myrq
Resource    Used  Hard
--------    ----  ----
pods        4     20

二,

OK,现在修改上面的配额定义yaml文件,修改成如下:

root@k8s-master:~# cat quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: myrq
  namespace: myrq
spec:
  hard:
    pods: "20"
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi
    count/deployments.apps: "3"
    count/deployments.extensions: "3"
    persistentvolumeclaims: "2"

新的yaml文件应用后,查看详情:

root@k8s-master:~# kubectl describe resourcequotas -n myrq 
Name:                         myrq
Namespace:                    myrq
Resource                      Used  Hard
--------                      ----  ----
count/deployments.apps        2     3
count/deployments.extensions  0     3
limits.cpu                    0     2
limits.memory                 0     2Gi
persistentvolumeclaims        0     2
pods                          4     20
requests.cpu                  0     1
requests.memory               0     1Gi

定义的deployment控制器配额是3个,前面已经创建了nginx和nginx1两个控制器,nginx是三副本,nginx1是一pod,因此是4pods,都是符合实际情况的

OK,在创建两个deployment控制器,看看能否成功:

nginx2的pod运行不正常,由于配额yaml文件重新apple了,指定了cpu和内存,因此,需要更改部署

root@k8s-master:~# kubectl create deployment nginx2 --image=nginx --replicas=1 -n myrq 
deployment.apps/nginx2 created
root@k8s-master:~# kubectl create deployment nginx3 --image=nginx --replicas=1 -n myrq 
error: failed to create deployment: deployments.apps "nginx3" is forbidden: exceeded quota: myrq, requested: count/deployments.apps=1, used: count/deployments.apps=3, limited: count/deployments.apps=3
root@k8s-master:~# kubectl get deployments.apps  -n myrq 
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
nginx    3/3     3            3           34m
nginx1   1/1     1            1           21m
nginx2   0/1     0            0           4m8s

在创建第四个deployment的时候,apiserver给我们返回了一个错误,提示创建失败,已经使用了三个,配额也是三个,因此失败。

OK,删除nginx2这个deployment控制器,重新创建,使用CPU和内存的配额:

root@k8s-master:~# cat quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: myrq
  namespace: myrq
spec:
  hard:
    pods: "20"
    requests.cpu: "20"
    requests.memory: 20Gi
    limits.cpu: "2"
    limits.memory: 2Gi
    count/deployments.apps: "3"
    count/deployments.extensions: "3"
    persistentvolumeclaims: "2"
root@k8s-master:~# cat dep-nginx.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx2
  name: nginx2
  namespace: myrq
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx2
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx2
    spec:
      containers:
      - image: nginx:1.18
        name: nginx2
        resources:
          requests:
            cpu: 500m
            memory: 500Mi
          limits:
            cpu: 1000m
            memory: 1Gi     

status: {}

应用以上文件后,发现nginx2只有两个副本:

root@k8s-master:~# kubectl get deployments.apps -n myrq 
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
nginx1   1/1     1            1           50m
nginx2   2/3     2            2           3m20s

查看配额,发现内存的配额用完了,三个副本,因此,limits使用了3G,但只有2G的配额,CPU也是只有两个配额,因此,少一个副本:

root@k8s-master:~# kubectl describe resourcequotas -n myrq
Name:                         myrq
Namespace:                    myrq
Resource                      Used    Hard
--------                      ----    ----
count/deployments.apps        2       3
count/deployments.extensions  0       3
limits.cpu                    2       2
limits.memory                 2Gi     2Gi
persistentvolumeclaims        0       2
pods                          3       20
requests.cpu                  1       20
requests.memory               1000Mi  20Gi

修改配额,增加CPU和内存的配额,CPU调整为20,内存调整为20G,重新apply两个文件:

root@k8s-master:~# cat quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: myrq
  namespace: myrq
spec:
  hard:
    pods: "20"
    requests.cpu: "20"
    requests.memory: 20Gi
    limits.cpu: "20"
    limits.memory: 20Gi
    count/deployments.apps: "3"
    count/deployments.extensions: "3"
    persistentvolumeclaims: "2"

查看nginx2,可以发现部署正确了:

root@k8s-master:~# kubectl get deployments.apps -n myrq 
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
nginx1   1/1     1            1           57m
nginx2   3/3     3            3           9s

查看配额:

一个pod用一个cpu嘛,所以三个副本3个cpu,内存同理

root@k8s-master:~# kubectl describe resourcequotas -n myrq
Name:                         myrq
Namespace:                    myrq
Resource                      Used    Hard
--------                      ----    ----
count/deployments.apps        2       3
count/deployments.extensions  0       3
limits.cpu                    3       20
limits.memory                 3Gi     20Gi
persistentvolumeclaims        0       2
pods                          4       20
requests.cpu                  1500m   20
requests.memory               1500Mi  20Gi

猜你喜欢

转载自blog.csdn.net/alwaysbefine/article/details/128745895