k8s进阶:Resource

K8S进阶知识

本系列笔记记录一些本人在学习k8s后,额外补充到的一些知识,或者是重新梳理.对我个人来说,就是进阶,比较碎片化,记录为主.

Resource

request和limit

  1. 当使用docker作为运行时,通过yaml指定request和limit,并apply后,可以通过以下命令查看一些传给docker的实际资源参数:
1
docker inspect <container-id>
  • CpuShares:

    yaml中request.cpu(100m=0.1核)*1024=CpuShares(102.4)

    docker中一个相对权重,作用是当docker发生资源竞争时候,决定分配给容器资源的比例.

    比如某节点起了两个容器,分别cpu配置为1和2,那两个容器的CpuShares就是1024和2048,当节点发生资源竞争,docker就会按CpuShares的比例(1:2)将cpu资源分配给两个容器.

  • Memory: 内存,B单位

  • CpuPeriod和CpuQuota:

    CpuPeriod是docker默认值(100000),单位是纳秒;CpuQuota就是limit.cpu,单位微核(200m=0.2核*100000=20000)

    CpuPeriod: 100000

    CpuQuota: 20000

    表示容器在100毫秒最多分配给它cpu0.2核

  1. 模拟增加cpu和内存使用

    内存使用脚本:

    1
    2
    3
    4
    5
    6
    #!/bin/bash
    str = "<任选一段比较长的字符串>"
    while [ TRUE ]
    do
    str = "${str}${str}"
    done

    字符串不停翻倍,内存使用不停扩大,当该进程使用的内存不停扩大到limit,docker会直接将其杀掉,但不会重启容器(该脚本并不是容器的主进程/启动进程).

    cpu使用命令:

    1
    dd if=/dev/zero of=/dev/null &

    不停创建新进程,cpu使用率不停增加,但cpu使用最大只能用到limit,且进程不会被杀掉.因为cpu可压缩.

LimitRange

K8S提供的另一种资源限制手段,本身也是K8S的一种资源,作用在namespace下的pod和container生效.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
apiVersion: v1
kind: LimitRange
metadata:
name: test-limits
namespace: test
spec:
limits:
- max:
cpu: 4000m
memory: 2Gi
min:
cpu: 100m
memory: 100Mi
# request和limit比值最大不能超过多少
maxLimitRequestRatio:
# limit.cpu最大比request.cpu大3倍
cpu: 3
# limit.mem最大比request.mem大2倍
memory: 2
# Pod的资源限制
type: Pod
####################Container比Pod多了默认值,因为Pod是一个逻辑概念,里面可以跑多个容器,所以无法配置默认值#####################
# limit的默认值
- default:
cpu: 300m
memory: 200Mi
# request的默认值
defaultRequest:
cpu: 200m
memory: 100Mi
max:
cpu: 2000m
memory: 1Gi
min:
cpu: 100m
memory: 100Mi
maxLimitRequestRatio:
cpu: 5
memory: 4
type: Container

ResourceQuota

针对namespace做资源限制,限制该namespace的request和limit最多使用多少资源以及pod数量

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: ResourceQuota
metadata:
name: resource-quota
namespace: test
spec:
hard:
pods: 4
request.cpu: 2000m
requests.memory: 4Gi
limits.cpu: 4000m
limits.memory: 8Gi

也可以限制namespace下各种资源的数量

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
namespace: test
spec:
hard:
configmaps: 10
persistentvolumeclaims: 4
replicationcontrollers: 20
secrets: 10
service: 10

查看:

1
kubectl <get|describe> quota -n test

Pod驱逐-Eviction

request == limit: 可靠

不设置: 不可靠

limit>request: 基本可靠

kublet持续监控节点资源情况,当符合对应驱逐策略时,便开始驱逐pod

常见驱逐策略配置

1
2
3
4
5
6
# 节点可用内存少于1.5G,开始驱逐,结合第二个参数与一起使用
--eviction-soft=memory.available<1.5Gi
# soft意味着不是马上驱逐,而是优雅kill(grace),此参数配置与上一条一起使用,但节点内存持续1m30s都少于1.5G时,才开始驱逐
--eviction-soft-grace-period=memory.available=1m30s
# hard就是硬驱逐,当条件满足,便立即执行驱逐,或关系
--eviction-hard=memory.available<100Mi,nodefs.available<1Gi,nodefs.inodesFree<5%

kubelet的驱逐处理:

磁盘紧缺时候:

  1. 删除死掉的pod/容器
  2. 删除没用的镜像
  3. 按优先级/资源占用情况驱逐pod(同级别中优先驱逐占用资源最多的)

内存紧缺时:

  1. 驱逐不可靠的pod(优先驱逐占用内存最大的)
  2. 驱逐基本可靠的pod
    1. 实际使用内存>request内存的pod中找超过最多的优先驱逐
    2. 如果没有则优先驱逐占用内存最大的
  3. 驱逐可靠的pod(过程与基本可靠一致)

k8s进阶:Resource
http://example.com/2022/07/11/k8s-advanced-resource/
作者
Peter Pan
发布于
2022年7月11日
许可协议