云原生|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


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
2月前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
137 2
|
6天前
|
弹性计算 运维 Kubernetes
使用ACK Edge统一管理多地域的ECS资源
本文介绍如何使用ACK Edge来管理分布在多个地域的ECS资源。
|
28天前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
134 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
2月前
|
Kubernetes Cloud Native 微服务
云原生入门与实践:Kubernetes的简易部署
云原生技术正改变着现代应用的开发和部署方式。本文将引导你了解云原生的基础概念,并重点介绍如何使用Kubernetes进行容器编排。我们将通过一个简易的示例来展示如何快速启动一个Kubernetes集群,并在其上运行一个简单的应用。无论你是云原生新手还是希望扩展现有知识,本文都将为你提供实用的信息和启发性的见解。
|
2月前
|
Kubernetes Cloud Native 开发者
云原生入门:Kubernetes的简易指南
【10月更文挑战第41天】本文将带你进入云原生的世界,特别是Kubernetes——一个强大的容器编排平台。我们将一起探索它的基本概念和操作,让你能够轻松管理和部署应用。无论你是新手还是有经验的开发者,这篇文章都能让你对Kubernetes有更深入的理解。
|
2月前
|
运维 Kubernetes Cloud Native
云原生技术入门:Kubernetes和Docker的协同工作
【10月更文挑战第43天】在云计算时代,云原生技术成为推动现代软件部署和运行的关键力量。本篇文章将带你了解云原生的基本概念,重点探讨Kubernetes和Docker如何协同工作以支持容器化应用的生命周期管理。通过实际代码示例,我们将展示如何在Kubernetes集群中部署和管理Docker容器,从而为初学者提供一条清晰的学习路径。
|
2月前
|
Kubernetes 负载均衡 Cloud Native
探索Kubernetes:云原生应用的基石
探索Kubernetes:云原生应用的基石
|
2月前
|
Kubernetes 监控 负载均衡
深入云原生:Kubernetes 集群部署与管理实践
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术以其弹性、可扩展性成为企业IT架构的首选。本文将引导你了解如何部署和管理一个Kubernetes集群,包括环境准备、安装步骤和日常维护技巧。我们将通过实际代码示例,探索云原生世界的秘密,并分享如何高效运用这一技术以适应快速变化的业务需求。
81 1
|
2月前
|
Kubernetes Cloud Native 云计算
云原生入门:Kubernetes 和容器化基础
在这篇文章中,我们将一起揭开云原生技术的神秘面纱。通过简单易懂的语言,我们将探索如何利用Kubernetes和容器化技术简化应用的部署和管理。无论你是初学者还是有一定经验的开发者,本文都将为你提供一条清晰的道路,帮助你理解和运用这些强大的工具。让我们从基础开始,逐步深入了解,最终能够自信地使用这些技术来优化我们的工作流程。
|
2月前
|
存储 Kubernetes 调度
【赵渝强老师】K8s中Deployment控制器与StatefulSet控制器的区别
K8s中的Deployment控制器用于管理无状态应用程序,关注Pod数量、更新方式等;而StatefulSets控制器则管理有状态应用程序,提供持久存储和唯一标识符,适用于需要稳定网络标识符和持久化存储的场景。两者的主要区别在于是否维护状态和顺序。