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

简介: 云原生|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


相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
存储 Kubernetes 对象存储
部署DeepSeek但GPU不足,ACK One注册集群助力解决IDC GPU资源不足
借助阿里云ACK One注册集群,充分利用阿里云强大ACS GPU算力,实现DeepSeek推理模型高效部署。
|
Cloud Native Serverless 数据中心
阿里云ACK One:注册集群支持ACS算力——云原生时代的计算新引擎
ACK One注册集群已正式支持ACS(容器计算服务)算力,为企业的容器化工作负载提供更多选择和更强大的计算能力。
|
Cloud Native Serverless 数据中心
阿里云ACK One:注册集群支持ACS算力——云原生时代的计算新引擎
阿里云ACK One:注册集群支持ACS算力——云原生时代的计算新引擎
415 10
|
存储 Kubernetes 对象存储
部署DeepSeek但GPU不足,ACK One注册集群助力解决IDC GPU资源不足
部署DeepSeek但GPU不足,ACK One注册集群助力解决IDC GPU资源不足
400 3
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
690 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
弹性计算 运维 Kubernetes
使用ACK Edge统一管理多地域的ECS资源
本文介绍如何使用ACK Edge来管理分布在多个地域的ECS资源。
|
弹性计算 运维 Kubernetes
使用ACK Edge统一管理多地域的ECS资源
使用ACK Edge统一管理多地域的ECS资源
276 0
|
存储 Kubernetes 对象存储
部署 DeepSeek 但 GPU 不足,ACK One 注册集群助力解决 IDC GPU 资源不足
部署 DeepSeek 但 GPU 不足,ACK One 注册集群助力解决 IDC GPU 资源不足
|
Kubernetes Cloud Native 微服务
云原生入门与实践:Kubernetes的简易部署
云原生技术正改变着现代应用的开发和部署方式。本文将引导你了解云原生的基础概念,并重点介绍如何使用Kubernetes进行容器编排。我们将通过一个简易的示例来展示如何快速启动一个Kubernetes集群,并在其上运行一个简单的应用。无论你是云原生新手还是希望扩展现有知识,本文都将为你提供实用的信息和启发性的见解。
|
Kubernetes Cloud Native 云计算
云原生入门:Kubernetes 和容器化基础
在这篇文章中,我们将一起揭开云原生技术的神秘面纱。通过简单易懂的语言,我们将探索如何利用Kubernetes和容器化技术简化应用的部署和管理。无论你是初学者还是有一定经验的开发者,本文都将为你提供一条清晰的道路,帮助你理解和运用这些强大的工具。让我们从基础开始,逐步深入了解,最终能够自信地使用这些技术来优化我们的工作流程。

推荐镜像

更多