06-设置 Kubernetes 资源限制

摘要:Kubernetes 作为当下最流行的的容器集群管理平台,需要统筹集群整体的资源使用情况,将合适的资源分配给pod容器使用,既要保证充分利用资源,提高资源利用率,又要保证重要容器在运行周期内能够分配到足够的资源稳定运行。 ### 配置容器资源限制 对于一个pod来说,资源最基础的2个的指标就是:CPU和内存。 Kubernetes提供了个采用requests和limits 两种类型参数

Kubernetes 作为当下最流行的的容器集群管理平台,需要统筹集群整体的资源使用情况,将合适的资源分配给pod容器使用,既要保证充分利用资源,提高资源利用率,又要保证重要容器在运行周期内能够分配到足够的资源稳定运行。

配置容器资源限制

对于一个pod来说,资源最基础的2个的指标就是:CPU和内存。
Kubernetes提供了个采用requests和limits 两种类型参数对资源进行预分配和使用限制。
limit 会限制pod的资源利用:

  • 当pod 内存超过limit时,会被oom。
  • 当cpu超过limit时,不会被kill,但是会限制不超过limit值。

测试内存限制

部署一个压测容器,压测时会分配250M内存,但实际pod的内存limit为100Mi

apiVersion: v1
kind: Pod
metadata:
  name: memory-demo
  namespace: example
spec:
  containers:
  - name: memory-demo-2-ctr
    image: polinux/stress
    resources:
      requests:
        memory: "50Mi"
      limits:
        memory: "100Mi"
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1"]

部署后查看pod状态,可以看到pod被OOM,

  kubectl -n example get po
NAME             READY     STATUS        RESTARTS   AGE
memory-demo      0/1       OOMKilled     1          11s

测试CPU限制

apiVersion: v1
kind: Pod
metadata:
  name: cpu-demo
  namespace: example
spec:
  containers:
  - name: cpu-demo-ctr
    image: vish/stress
    resources:
      limits:
        cpu: "1"
      requests:
        cpu: "0.5"
    args:
    - -cpus
    - "2"

查看容器信息,可以看到pod 虽然不会被kill掉,但是实际使用cpu被限制只有1000m。

 kubectl -n example top po cpu-demo
NAME       CPU(cores)   MEMORY(bytes)
cpu-demo   1000m        0Mi

容器服务质量(QoS)

Kubernetes 提供服务质量管理,根据容器的资源配置,将pod 分为Guaranteed, Burstable, BestEffort 3个级别。当资源紧张时根据分级决定调度和驱逐策略,这三个分级分别代表:

  • Guaranteed: pod中所有容器都设置了limit和request, 并且相等(设置limit后假如没有设置request会自动设置为limit值)
  • Burstable: pod中有容器未设置limit, 或者limit和request不相等。这种类型的pod在调度节点时, 可能出现节点超频的情况。
  • BestEffort: pod中没有任何容器设置request和limit。

计算qos代码:https://github.com/kubernetes/kubernetes/blob/master/pkg/apis/core/helper/qos/qos.go

不同QoS对容器影响

oom:

Kubernetes会根据QoS设置oom的评分调整参数oom_score_adj,oom_killer 根据 内存使用情况算出oom_score, 并且和oom_score_adj综合评价,进程的评分越高,当发生oom时越优先被kill。

QoS oom_score_adj
Guaranteed -998
BestEffort 1000
Burstable min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)

当节点内存不足时,QoS为Guaranteed 的pod 最后被kill。 而BestEffort 级别的pod优先被kill。 其次是Burstable,根据计算公式 oom_score_adj 值范围2到999,设置的request越大,oom_score_adj越低,oom时保护程度越高。

实践
节点信息:
# kubectl describe no cn-beijing.i-2zeavb11mttnqnnicwj9 | grep -A 3 Capacity
Capacity:
 cpu:     4
 memory:  8010196Ki
 pods:    110
apiVersion: v1
kind: Pod
metadata:
  name: memory-demo-qos-1
  namespace: example
spec:
  containers:
  - name: memory-demo-qos-1
    image: polinux/stress
    resources:
      requests:
        memory: "200Mi"
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "50M", "--vm-hang", "1"]

---
apiVersion: v1
kind: Pod
metadata:
  name: memory-demo-qos-2
  namespace: example
spec:
  containers:
  - name: memory-demo-qos-2
    image: polinux/stress
    resources:
      requests:
        memory: "400Mi"
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "50M", "--vm-hang", "1"]

---
apiVersion: v1
kind: Pod
metadata:
  name: memory-demo-qos-3
  namespace: example
spec:
  containers:
  - name: memory-demo-qos-3
    image: polinux/stress
    resources:
      requests:
        memory: "200Mi"
        cpu: "2"
      limits:
        memory: "200Mi"
        cpu: "2"
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "50M", "--vm-hang", "1"]

单个节点可分配内存为8010196Ki, 大约7822.45Mi。
根据Burstable 的计算方式:


request 200Mi: (1000 - 1000*200/7822.45) 约为975

request 400Mi: (1000 - 1000*400/7822.45) 约为950

我们分别查看这3个pod的oom参数

// request 200Mi
  kubectl -n example exec  memory-demo-qos-1 cat /proc/1/oom_score_adj
975

// request 400Miß
  kubectl -n example exec  memory-demo-qos-2 cat /proc/1/oom_score_adj
949

// Guaranteed
  kubectl -n example exec  memory-demo-qos-3 cat /proc/1/oom_score_adj
-998

设置oom 规则代码:https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/qos/policy.go

pod 驱逐:

当节点的内存和cpu资源不足,开始驱逐节点上的pod时。QoS同样会影响驱逐的优先级。顺序如下:

  1. kubelet 优先驱逐 BestEffort的pod 和 实际占用资源大于requests的Burstable pod。
  • 接下来驱逐实际占用资源小于request的Burstable pod。
  • QoS为Guaranteed的pod最后驱逐, kubelet 会保证Guaranteed的pod 不会因为其他pod的资源消耗而被驱逐。
  • 当QoS相同时,kubelet 根据Priority计算驱逐的优先级

ResourceQuota

Kubernetes提供ResourceQuota对象,用于配置限制namespace内的每种类型的k8s对象数量和资源(cpu,内存)。

  • 一个namespace中可以创建一个或多个ResourceQuota
  • 如果namespace中配置了ResourceQuota, 部署时必须设置request和limit, 否则会拒绝创建请求。
  • 可以通过这是limitRange配置每个pod默认的requests和limits避免上述问题
  • 1.10以后支持扩展资源 详见:https://kubernetes.io/docs/tasks/configure-pod-container/extended-resource/
apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-cpu-demo
  namespace: example
spec:
  hard:
    requests.cpu: "3"
    requests.memory: 1Gi
    limits.cpu: "5"
    limits.memory: 2Gi
    pods: "5"

LimitRange

LimitRange 是用来设置 namespace 中 Pod 的默认的资源 request 和 limit 值,以及大小范围。

apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
  namespace: example
spec:
  limits:
  - default:  # default limit
      memory: 512Mi
      cpu: 2
    defaultRequest:  # default request
      memory: 256Mi
      cpu: 0.5
    max:  # max limit
      memory: 800Mi
      cpu: 3
    min:  # min request
      memory: 100Mi
      cpu: 0.3
    maxLimitRequestRatio:  # max value for limit / request
      memory: 2
      cpu: 2
    type: Container # limit type, support: Container / Pod / PersistentVolumeClaim

limitRange支持的参数如下:

  • default 代表默认的limit
  • defaultRequest 代表默认的request
  • max 代表limit的最大值
  • min 代表request的最小值
  • maxLimitRequestRatio 代表 limit / request的最大值。由于节点是根据pod request 调度资源,可以做到节点超卖,maxLimitRequestRatio 代表pod最大超卖比例。

总结

  • Kubernetes 提供request 和 limit 两种方式设置容器资源。
  • 为了提高资源利用率,k8s调度时根据pod 的request值计算调度策略,从而实现节点资源超卖。
  • k8s根据limit限制pod使用资源,当内存超过limit时会触发oom。 且限制pod的cpu 不允许超过limit。
  • 根据pod的 request和limit,k8s会为pod 计算服务质量,并分为Guaranteed, Burstable, BestEffort 这3级。当节点资源不足时,发生驱逐或者oom时, Guaranteed 级别的pod 优先保护, Burstable 节点次之(request越大,使用资源量越少 保护级别越高), BestEffort 最先被驱逐。
  • Kubernetes提供了RequestQuota和LimitRange 用于设置namespace 内pod 的资源范围 和 规模总量。 RequestQuota 用于设置各种类型对象的数量, cpu和内存的总量。 LimitRange 用于设置pod或者容器 request和limit 的默认值,最大最小值, 以及超卖比例(limit / request)。
  • 对于一些重要的线上应用,我们应该合理设置limit和request,limit和request 设置一致,资源不足时k8s会优先保证这些pod正常运行。
  • 为了提高资源利用率。 对一些非核心,并且资源不长期占用的应用,可以适当减少pod的request,这样pod在调度时可以被分配到资源不是十分充裕的节点,提高使用率。但是当节点的资源不足时,也会优先被驱逐或被oom kill。

参考文档

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容