Kubernetes(k8s)之容器资源限制

Posted Tuki_a

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kubernetes(k8s)之容器资源限制相关的知识,希望对你有一定的参考价值。

资源限制的实现

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

默认情况下,Pod运行没有CPU和内存的限额。这意味着系统中的任何Pod将能够像执行Pod所在节点机器一样,可以消耗足够多的CPU和内存。一般会针对某些应用的Pod资源进行资源限制,这个资源限制是通过resources的requests【要分配的资源】和limits【最大使用资源】来实现的。

资源的两种限制类型

Kubernetes采用request和limit两种限制类型来对资源进行分配。
1、request(资源需求):即运行Pod的节点必须满足运行Pod的最基本需求才能运行Pod。
2、limit(资源限额):即运行Pod期间,可能内存使用量会增加,那最多能使用多少内存,这就是资源限额。

资源类型单位

1、CPU
CPU 的单位是核心数,内存的单位是字节。
一个容器申请0.5个CPU,就相当于申请1个CPU的一半,你也可以加个后缀m,表示千分之一的概念。
比如说100m(100豪)的CPU等价于0.1个CPU

2、内存单位:
K、M、G、T、P、E   ##通常是以1000为换算标准的。
Ki、Mi、Gi、Ti、Pi、Ei   ##通常是以1024为换算标准的。

演示环境

server1:172.25.38.1	harbor仓库端
server2:172.25.38.2	k8s master端
server3:172.25.38.3	k8s node端
server4:172.25.38.4	k8s node端

Memory内存限制

在容器里使用镜像stress进行压力测试,指定资源数进行压力测试。先在仓库端拉取镜像并上传供k8s的master端使用。
#stress镜像其实就是封装了stress命令(模拟系统负载较高时的场景)


新创建一个目录,并创建一个用stress镜像的pod,内容如下:

apiVersion: v1
kind: Pod
metadata:
  name: memory-demo
spec:
  containers:
  - name: memory-demo
    image: stress
    args:				#提供了容器启动的参数
    - --vm
    - "1"				#模拟一个进程
    - --vm-bytes
    - 200M				#每个进程使用200M内存
    resources:
      requests:
        memory: 50Mi	#最少需要50Mi内存
      limits:
        memory: 100Mi	#最多100Mi

应用文件创建pod

可以看到状态变化如下,OMMKilled是超出内存限制的意思。
我们要求启动时开一个使用200M内存的进程,可我们又限制最多100M,那么自然会超出限制。如果一个容器超过其内存请求,那么当节点内存不足时,它的 Pod 可能被逐出。

crashloopbackoff意味着pod挂掉又重启又挂掉如此往复。
如果容器超过其内存限制,则会被终止。如果可重新启动,则与所有其他类型的运行时故障一样,kubelet 将重新启动它。

CPU限制

创建一个用stress镜像的pod做cpu压测

apiVersion: v1
kind: Pod
metadata:
  name: cpu-demo
spec:
  containers:
  - name: cpu-demo
    image: stress		#使用stress镜像
    resources:
      limits:
        cpu: "10"	#至多使用10个CPU
      requests:
        cpu: "5"	#最少用5个CPU
    args:			#提供了容器启动的参数
    - -c			#CPU
    - "2"			#指定容器启动时使用2个CPU

应用文件出现如下状态,待调度。这是因为我们设置容器至少需要5个CPU,但我们根本没有5个CPU(我只给了虚拟机一个CPU)即没有符合条件的node,自然无法成功调度pod

LimitRange

LimitRange 在 namespace 中施加的最小和最大内存限制只有在创建和更新 Pod 时才会被应用。改变 LimitRange 不会对之前创建的 Pod 造成影响。

为namespace设置资源限制

定义default这个namespaces下的资源限制,文件内容如下:

apiVersion: v1
kind: LimitRange	#资源类型
metadata:
  name: limitrange-memory
spec:
  limits:
  - default:			#当pod定义文件里没有指定资源数,在这个namespaces下最多使用0.5个cpu,512Mi内存
      cpu: 0.5
      memory: 512Mi
    defaultRequest:		#当pod定义文件里没有指定资源数,在这个namespaces下最少需要0.1个cpu,256Mi内存
      cpu: 0.1
      memory: 256Mi
    max:				#不管pod定义文件里有没有指定资源数,在这个namespaces下最多用1个cpu,1Gi内存
      cpu: 1
      memory: 1Gi
    min:				#不管pod定义文件里有没有指定资源数,在这个namespaces下最少需要0.1个cpu,100Mi内存
      cpu: 0.1
      memory: 100Mi
    type: Container

应用文件创建出了属于default这个namespaces的资源限制

可以查看详细描述

编写一个限制内存的创建pod的定义文件,内容如下:

apiVersion: v1
kind: Pod
metadata:
  name: memory-demo
spec:
  containers:
  - name: memory-demo
    image: nginx
    resources:
      requests:
        memory: 50Mi	#最少需要50Mi内存
      limits:
        memory: 100Mi	#最多100Mi

应用文件创建pod失败,是因为我们上面的limitrange的作用,最少要100Mi,而我们设定50Mi,所以出错了

将文件中如下图部分注释掉即不指定资源限制

重新应用

执行kubectl describe pod memory-demo可以看到因为LimitRange的缘故自动加上了资源限制

ResourceQuota

LimitRange是针对单个pod设置资源限制,ResourceQuota是针对所有pod设置的资源总额。
创建的ResourceQuota对象将在default名字空间中添加以下限制:
每个容器必须设置内存请求(memory request),内存限额(memory limit),cpu请求(cpu request)和cpu限额(cpu limit)。

为namespace设置资源配额

定义default这个namespaces下的资源配额,文件内容如下:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-cpu-demo
spec:
  hard:
    requests.cpu: "1"		#所有容器的CPU请求总额不得超过1 CPU
    requests.memory: 1Gi	#所有容器的内存请求总额不得超过1 GiB
    limits.cpu: "2"			#所有容器的CPU限额总额不得超过2 CPU
    limits.memory: 2Gi		#所有容器的内存限额总额不得超过2 GiB

修改一下上面用过的pod2.yaml文件

apiVersion: v1
kind: Pod
metadata:
  name: memory-demo
spec:
  containers:
  - name: memory-demo
    image: nginx
    resources:
      requests:
        cpu: 0.2
        memory: 100Mi
      limits:
        cpu: 1
        memory: 300Mi

应用创建pod,可以看到资源配额已经用了多少

再修改一下文件重新创建一个pod,并设置如下图资源请求

再看资源配额,可以看到累加起来的资源总额

修改资源配额定义文件,限制pod总数为4个

重新应用文件,资源配额更新成功

以上是关于Kubernetes(k8s)之容器资源限制的主要内容,如果未能解决你的问题,请参考以下文章

k8s容器资源限制,资源监控

Kubernetes 系列K8S 进阶 容器和 Pod 分配内存资源

Linux企业运维——Kubernetes(十五)容器资源限制

Linux企业运维——Kubernetes(十五)容器资源限制

企业运维实战--k8s学习笔记11.k8s容器资源限制

Kubernetes 内存管理及调度