35.B站薪享宏福笔记——第十二章(5)资源限制

12 B站薪享宏福笔记——第十二章

                                    —— Kubernetes 中必备的工具组件

12.5 资源限制

            —— 需要多少配多少

12.5.1 资源限制

(1)概念

  Kubernetes 对资源的限制实际上是通过 Cgroup 来控制的(底层是 docker ,docker 的资源限制是通过 Cgroup 控制的),Cgroup 是容器的一组用来控制内核运行进程的相关属性的集合,针对内存、CPU 和 各种设备都有对应的 Cgroup

  默认情况下,Pod 运行没有 CPU 和 内存的限制。这意味着系统中任何 Pod 将能够运行该节点所有的运算资源,可以消耗足够多的 CPU 和内存,一般会针对某些应用的 Pod 资源进行资源限制,通过 resources 的 requests 和 limits 来实现

(2)特性

  调度器在调度时并不关注各类资源在当前时刻的实际使用量,而只关心节点上部署的所有 Pod 的资源申请量之和

  在容器内看到的始终是节点的内存,而不是容器本身的内存

  在容器内看到的始终是节点所有的 CPU 核心数,而不仅仅只是容器可用的 CPU 核心数

12.5.2 HPA

(1)镜像导入

# HPA 需要能够知道 cpu、内存 的使用量才可以根据cpu、内存进行限制(前面11.3 Prometheus 时 安装了 metrics.server,可以获取资源使用情况 )
[root@k8s-master01 12.5]# kubectl top node
NAME           CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
k8s-master01   321m         8%     2182Mi          61%       
k8s-node01     164m         8%     1448Mi          41%       
k8s-node02     182m         9%     1667Mi          47%
# 上传镜像
[root@k8s-master01 12.5]# rz

[root@k8s-master01 12.5]# ls
hpav1.tar
# 主节点导入,推送到node01、node02 节点,node01、node02节点再倒入镜像
[root@k8s-master01 12.5]# docker load -i hpav1.tar
........
[root@k8s-master01 12.5]# scp hpav1.tar n1:/root
root@n1's password: 
hpav1.tar                                                                                                                                                                                                  100%  482MB  14.2MB/s   00:33    
[root@k8s-master01 12.5]# scp hpav1.tar n2:/root
root@n2's password: 
hpav1.tar                                                                                                                                                                                                  100%  482MB 106.8MB/s   00:04    
[root@k8s-node01 ~]# docker load -i /root/hpav1.tar
........
[root@k8s-node02 ~]# docker load -i /root/hpav1.tar
........

(2)创建 hpa

[root@k8s-master01 12.5]# cat 1.resources.yaml 
apiVersion: apps/v1 
kind: Deployment  
metadata:  
 name: my-deployment  
spec:  
 replicas: 3  
 selector:  
   matchLabels:  
     app: myapp
 template:  
   metadata:  
     labels:  
       app: myapp  
   spec:  
     containers:  
     - name: my-container  
       image: wangyanglinux/hpa:v1
       resources:  
         requests:  
           cpu: 200m
4.deployment 期望:副本数、选择器:匹配标签:标签、标签值、Pod 模版:元数据:标签、标签值、Pod 期望:容器组:容器名、基于镜像版本、资源限制:初始化:cpu 
[root@k8s-master01 12.5]# kubectl apply -f 1.resources.yaml 
deployment.apps/my-deployment created
[root@k8s-master01 12.5]# kubectl get deployment
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
my-deployment   3/3     3            3           6s
[root@k8s-master01 12.5]# kubectl get pod -o wide
NAME                             READY   STATUS    RESTARTS   AGE    IP              NODE         NOMINATED NODE   READINESS GATES
my-deployment-5cd68fd574-cq4bt   1/1     Running   0          2m7s   10.244.85.251   k8s-node01   <none>           <none>
my-deployment-5cd68fd574-cw2sj   1/1     Running   0          2m7s   10.244.58.221   k8s-node02   <none>           <none>
my-deployment-5cd68fd574-dkmc6   1/1     Running   0          2m7s   10.244.85.198   k8s-node01   <none>           <none>
# hpa 需要接管控制器,目前没有接管任何控制器
[root@k8s-master01 12.5]# kubectl get hpa
No resources found in default namespace.
# hpa 控制器需要依托别的控制器之上进行管理,管理 deployment、管理的deployment 名称、cpu 使用百分比是 50%(一旦超过50%进行扩容)、最小 保留 2个(防止流量激增,1个 Pod 被访问压死)、最大保留 10个(防止因被攻击,无限扩容)
[root@k8s-master01 12.5]# kubectl autoscale deployment my-deployment --cpu-percent=50 --min=2 --max=10
horizontalpodautoscaler.autoscaling/my-deployment autoscaled
# hpa 名、管理 deployment 名、目前使用/设置目标扩容值、最小保留、最大保留、副本数、管理时间(hpa的回收很谨慎!)
[root@k8s-master01 12.5]# kubectl get hpa
NAME            REFERENCE                  TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
my-deployment   Deployment/my-deployment   0%/50%    2         10        3          2m28s
# deployment 中定义的是 3 个,hpa 中定义最小值是 2 个,经过长时间没有流量访问,副本数下降,因为 hpa 是控制 deployment 的
[root@k8s
-master01 12.5]# kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE my-deployment Deployment/my-deployment 0%/50% 2 10 2 34m

(3)实验验证

[root@k8s-master01 12.5]# kubectl get pod --show-labels
NAME                             READY   STATUS    RESTARTS   AGE    LABELS
my-deployment-5cd68fd574-5hr4l   1/1     Running   0          17m    app=myapp,pod-template-hash=5cd68fd574
my-deployment-5cd68fd574-cw2sj   1/1     Running   0          145m   app=myapp,pod-template-hash=5cd68fd574
[root@k8s-master01 12.5]# kubectl create svc clusterip myapp --tcp=80:80
service/myapp created
[root@k8s-master01 12.5]# kubectl get svc 
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.0.0.1       <none>        443/TCP   34d
myapp        ClusterIP   10.5.168.161   <none>        80/TCP    17s
[root@k8s-master01 12.5]# curl 10.5.168.161
OK!
# 新开一个终端,启动 Pod 作为客户端访问经过 hpa 管理的服务端,通过无限循环对服务端进行压测
[root@k8s-master01 ~]# kubectl run -i --tty work1 --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # while true;do wget -q -O- http://myapp.default.svc.cluster.local;done
# 再开一个终端,同样无限循环压测
[root@k8s-master01 ~]# kubectl run -i --tty work2 --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # while true;do wget -q -O- http://myapp.default.svc.cluster.local;done
# 当使用率超过设定值 50% 会自动扩容,当 pod 达到最大值 10 个,即使再超过设定值,也不会再扩容
[root@k8s-master01 12.5]# kubectl get hpa
NAME            REFERENCE                  TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
my-deployment   Deployment/my-deployment   37%/50%   2         10        7          77m
[root@k8s-master01 12.5]# kubectl get hpa
NAME            REFERENCE                  TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
my-deployment   Deployment/my-deployment   71%/50%   2         10        7          79m
[root@k8s-master01 12.5]# kubectl get hpa
NAME            REFERENCE                  TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
my-deployment   Deployment/my-deployment   55%/50%   2         10        10         79m
[root@k8s-master01 12.5]# kubectl get pod --show-labels
NAME                             READY   STATUS    RESTARTS   AGE     LABELS
my-deployment-5cd68fd574-5hr4l   1/1     Running   0          33m     app=myapp,pod-template-hash=5cd68fd574
my-deployment-5cd68fd574-8qpvc   1/1     Running   0          3m38s   app=myapp,pod-template-hash=5cd68fd574
my-deployment-5cd68fd574-cw2sj   1/1     Running   0          161m    app=myapp,pod-template-hash=5cd68fd574
my-deployment-5cd68fd574-d4glb   1/1     Running   0          37s     app=myapp,pod-template-hash=5cd68fd574
my-deployment-5cd68fd574-fpxx9   1/1     Running   0          3m53s   app=myapp,pod-template-hash=5cd68fd574
my-deployment-5cd68fd574-kks52   1/1     Running   0          3m38s   app=myapp,pod-template-hash=5cd68fd574
my-deployment-5cd68fd574-ncbm6   1/1     Running   0          3m38s   app=myapp,pod-template-hash=5cd68fd574
my-deployment-5cd68fd574-sktxs   1/1     Running   0          37s     app=myapp,pod-template-hash=5cd68fd574
my-deployment-5cd68fd574-tkwdm   1/1     Running   0          37s     app=myapp,pod-template-hash=5cd68fd574
my-deployment-5cd68fd574-zmmgn   1/1     Running   0          3m53s   app=myapp,pod-template-hash=5cd68fd574
work1                            1/1     Running   0          5m57s   run=work1
work2                            1/1     Running   0          79s     run=work2
# 将无限循环 while 停止后,没有流量访问,cpu 减少,经过一段时间,hpa 控制减少到最小保留个数
[root@k8s-master01 12.5]# kubectl get hpa
NAME            REFERENCE                  TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
my-deployment   Deployment/my-deployment   0%/50%    2         10        2          94m
[root@k8s-master01 12.5]# kubectl get pod --show-labels
NAME                             READY   STATUS    RESTARTS      AGE    LABELS
my-deployment-5cd68fd574-cw2sj   1/1     Running   0             176m   app=myapp,pod-template-hash=5cd68fd574
my-deployment-5cd68fd574-fpxx9   1/1     Running   0             18m    app=myapp,pod-template-hash=5cd68fd574
# 消除实验影响
[root@k8s-master01 12.5]# kubectl delete hpa,deployment,pod --all
horizontalpodautoscaler.autoscaling "my-deployment" deleted
deployment.apps "my-deployment" deleted
pod "work1" deleted
pod "work2" deleted

12.5.3 Pod QoS

(1)Qos 等级

  BestEffort(优先级最低) (当抢资源时,最后分配)

  Burstable        (当抢资源时,其次分配)

  Guaranteed(优先级最高)(当抢资源时,优先分配)

(2)BestEffort

  会分配给那些没有为任何容器设置 requests 和 limits 的 Pod

  最坏情况下,可能分配不到任何资源,同时,在需要为其它 Pod 释放资源时,这些容器会被第一批杀死

  因为没有设置资源限制,所以资源在足够使用时,这些容器可以使用任意多的资源量级

(3)Burstable

  Burstable QoS 等级基于 BestEffort 和 Guaranteed 之间,只要不归属于 BestEffort 和 Guaranteed 均归于此等级

(4)Guaranteed

  会分配给那些有 request 和 limits 资源且相等的 Pod

  如果容器资源 requests(软限制) 没有显示设置,默认与 limits(硬限制) 相同

(5)等级对比

注意:不同 Pod 间等级对比

image

BestEffort:Requests 和 Limits 都没有设置

Burstable:Requests 和 Limits 都设置了,但 Limits 比 Requests 设置的值更多

Guaranteed:Requests 和 Limits 都设置且设置的值相等

(6)单容器 Pod

CPU requests VS limits 内存 requests VS limits 容器的 QoS 等级
未设置 未设置 BestEffort
未设置 Requests < Limits Burstable
未设置 Requests = Limits Burstable
Requests < Limits 未设置 Burstable
Requests < Limits Requests < Limits Burstable
Requests < Limits Requests = Limits Burstable
Requests = Limits Requests = Limits Guaranteed

 

 

 

 

 

 

 

 

BestEffort:CPU 、内存的 Requests 和 Limits 都没有设置

Burstable:CPU 、内存的 Requests 和 Limits 至少有一个设置了,或 Limits 比 Requests 设置的值不相等

Guaranteed:CPU 、内存的 Requests 和 Limits 都设置且设置的值相等

(7)多容器 Pod

容器1 的 QoS 等级 容器2 的 QoS 等级 Pod 的 QoS 等级
BestEffort BestEffort BestEffort
BestEffort Burstable Burstable
BestEffort Guaranteed Burstable
Burstable Burstable Burstable
Burstable Guaranteed Burstable
Guaranteed Guaranteed Guaranteed

 

 

 

 

 

 

 

通过 单容器 Pod 知道 QoS 等级,低、中、优,低 x 低 = 低,优 x 优 =优,其余相乘都是中

(8)案例等级 释放资源顺序

注意:当以下 4 个 Pod 在同一服务器内,需要释放资源时,释放顺序

image

Pod1:定义了 Requests、Limit ,且两者相等,QoS 为 Guaranteed

Pod2:定义了 Requests、Limit ,但两者不相等,QoS 为 Burstable ,实际使用量 90%

Pod3:没有定义 Requests、Limit ,QoS 为 BestEffort

Pod4:定义了 Requests、Limit ,但两者不相等,QoS 为 Burstable ,实际使用量 70%

资源释放由等级低到高,先释放 BestEffort,再 Burstable ,最后 Guaranteed,当 Burstable 等级相同时,因为是服务器资源不够需要释放,实际使用量越多被认为资源消耗越严重,比相同 QoS 等级释放的更早

释放资源的顺序:Pod3 > Pod2 > Pod4 > Pod1

12.5.4 LimitRange(作用在 Pod)

(1)概念

  通过创建一个 LimitRange 资源来避免必须配置每个容器的资源限制,LimitRange 资源不仅允许用户(为每个命名空间)指定能给容器配置的每种资源的最小和最大限额,还支持在没有显示指定资源 request 时为容器设置默认值

(2)实验验证

[root@k8s-master01 12.5]# cat 2.limit_range.yaml 
apiVersion: v1
kind: LimitRange
metadata:
 name: example-limit-range
spec:
 limits:
 - type: Pod
   max:
     cpu: "1"
     memory: 1Gi
   min:
     cpu: "200m"
     memory: 100Mi
 - type: Container
   max:
     cpu: "500m"
     memory: 512Mi
   min:
     cpu: "100m"
     memory: 64Mi
   defaultRequest:
     cpu: "200m"
     memory: 128Mi
   default:
     cpu: "300m"
     memory: 200Mi
   maxLimitRequestRatio:
     cpu: "2"
     memory: "4"
1.接口组版本:核心组 v1 版
2.类别:limitRange 类别
3.元数据:limitRange 名称
4.期望:最大限制:类型:Pod:最大值:cpu、内存、最小值:cpu、内存(定义 Pod 时,cpu、内存所在区间)
               类型:容器:最大值:cpu、内存、最小值:cpu、内存(定义 容器 时,cpu、内存所在区间)、 容器默认初始值:cpu、内存(在容器下,当cpu 、内存未定义时采用默认值)、默认最大值:cpu、内存、最大值与初始值的比值:cpu 比值、内存比值
                         
[root@k8s-master01 12.5]# kubectl apply -f 2.limit_range.yaml 
limitrange/example-limit-range created
[root@k8s-master01 12.5]# kubectl get limitranges
NAME CREATED AT
example-limit-range 2025-08-26T03:48:37Z
# 验证当 pod 中未定义资源使用情况时,会因为 limitRange 定义后默认添加,limit 和 requests 中 cpu 和 内存 被定义默认值
[root@k8s-master01 12.5]# cat 3.pod.yaml 
apiVersion: v1
kind: Pod
metadata:
 name: resource-limited-default-pod
spec:
 containers:
 - name: my-container
   image: myapp:v1.0

[root@k8s-master01 12.5]# kubectl apply -f 3.pod.yaml 
pod/resource-limited-default-pod created
[root@k8s-master01 12.5]# kubectl get pod -o wide
NAME                           READY   STATUS    RESTARTS   AGE   IP              NODE         NOMINATED NODE   READINESS GATES
resource-limited-default-pod   1/1     Running   0          7s    10.244.85.205   k8s-node01   <none>           <none>
[root@k8s-master01 12.5]# kubectl get pod resource-limited-default-pod -o yaml
..........
spec:
  containers:
  - image: myapp:v1.0
    imagePullPolicy: IfNotPresent
    name: my-container
    resources:
      limits:
        cpu: 300m
        memory: 200Mi
      requests:
        cpu: 200m
        memory: 128Mi
..........
# 超出默认限制会创建失败,cpu 的 最大值与初始值的比值 比设定的 2 大,比值为 2.5
[root@k8s-master01 12.5]# cat 4.out_limit.yaml apiVersion: v1 kind: Pod metadata: name: resource-limited-pod spec: containers: - name: my-container image: myapp:v1.0 resources: requests: cpu: "200m" memory: "128Mi" limits: cpu: "500m" memory: "256Mi" [root@k8s-master01 12.5]# kubectl apply -f 4.out_limit.yaml Error from server (Forbidden): error when creating "4.out_limit.yaml": pods "resource-limited-pod" is forbidden: cpu max limit to request ratio per Container is 2, but provided ratio is 2.500000
# 消除实验影响
[root@k8s-master01 12.5]# kubectl delete limitranges example-limit-range
limitrange "example-limit-range" deleted
[root@k8s-master01 12.5]# kubectl delete pod --all
pod "resource-limited-default-pod" deleted

12.5.5 ResourceQuota(作用在 namespace)

注意:当特定资源配置了配额,在 pod 中必须为这些资源指定 request 和 limits ,否则 apiServer 不会接受创建 Pod 的请求,即使删除限制,也需要重新创建才能成功

(1)概念

  LimitRange 只应用于单独的 Pod,而集群需要一种手段可以限制命名空间中的可用资源总量,这个就是 ResourceQuota

  ResourceQuota 限制了一个命名空间中 pod 和 PVC 存储最多可以使用的资源总量,同时也可以限制用户允许在该命名空间中创建 pod、PVC 以及其它 API 对象的数量

(2)实验

[root@k8s-master01 12.5]# cat 5.resource_quota.yaml 
apiVersion: v1
kind: ResourceQuota
metadata:
 name: test-resources-rq
 namespace: test
spec:
 hard:
   requests.cpu: "20"
   requests.memory: 100Gi
   limits.cpu: "40"
   limits.memory: 200Gi
   pods: "1"
   configmaps: "10"
   persistentvolumeclaims: "4"
   replicationcontrollers: "20"
   secrets: "10"
   services: "10"
   services.loadbalancers: "2"
1.接口组版本:核心组 v1 版
2.类别:ResourceQuota 类别
3.元数据:ResourceQuota 名称、所在名称空间(限制的名称空间)
4.期望:固定资源:cpu初始值、内存初始值、cpu最大值、内存最大值、pod总量、configmap 总量、pvc 总量、RC 控制器总量、secrets 总量、svc 总量、svc 的 loadbalancers 总量
# 可以看到各类资源在名称空间下 创建的个数/可创建总个数
[root@k8s-master01 12.5]# kubectl apply -f 5.resource_quota.yaml 
resourcequota/test-resources-rq created
[root@k8s-master01 12.5]# kubectl get resourcequotas -n test
NAME                AGE    REQUEST                                                                                                                                                                                            LIMIT
test-resources-rq   112s   configmaps: 1/10, persistentvolumeclaims: 0/4, pods: 0/1, replicationcontrollers: 0/20, requests.cpu: 0/20, requests.memory: 0/100Gi, secrets: 0/10, services: 0/10, services.loadbalancers: 0/2   limits.cpu: 0/40, limits.memory: 0/200Gi
# 没有定义 deployment 可创建个数,虽然显示创建了,但是没有成功
# 注意,如果在限制之前创建,不会因限制删除原资源,但是将无法增加
[root@k8s-master01 12.5]# kubectl create deployment myapp --image=myapp:v1.0 --replicas=3 -n test
deployment.apps/myapp created
[root@k8s-master01 12.5]# kubectl get deployment -n test
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
myapp   0/3     0            0           70s
[root@k8s-master01 12.5]# kubectl get pod -n test
No resources found in test namespace.
# 消除实验影响
[root@k8s-master01 12.5]# kubectl delete resourcequotas,deployment --all -n test
resourcequota "test-resources-rq" deleted
deployment.apps "myapp" deleted

———————————————————————————————————————————————————————————————————————————

                                                                                                                         无敌小马爱学习

posted on 2025-08-06 15:12  马俊南  阅读(52)  评论(0)    收藏  举报