一、背景
当生产环境中因为内存分配不合理、或者使用不合理,导致容器OOM后需要提升内存限制
但是提升内存限制需要重启pod才能生效,对于多数生产环境中是不可接受的,需要考虑运行中动态修改的方案。
二、思路
k8s是通过cgroup设置pod资源限制的,cgroup是linux中一个独立组件,早于k8s就已经存在。
也就是说k8s和cgroup之间只是调用的关系,观察发现k8s只有在pod创建时才会设置cgroup,之后就不管了,所以可以通过后期手动设置cgroup来达到目的。
cgroup有v1和v2两个版本,我们目前用的是v1,接下来会基于v1版本展开。
cgroup比较友好的接口就是procfs,通过cat读取配置,通过io重定向写入配置,所以完全可以通过命令行来解决。
三、实现
1、在docker中找到容器的id:
1 2 3
| [root@master10 ~]# docker ps|grep redis 99bf05e5697d 53aa81e8adfa "redis-server --maxm…" 8 hours ago Up 8 hours k8s_redis_redis-8668c46ff7-2tp7t_redis_03381db2-cfcb-43ca-b5d5-a49b6f4a33f2_4 5c1e4e64e197 google_containers/pause:3.2 "/pause" 3 months ago Up 3 months k8s_POD_redis-8668c46ff7-2tp7t_redis_03381db2-cfcb-43ca-b5d5-a49b6f4a33f2_3
|
2、根据容器id找到cgroup路径信息
1 2 3
| [root@master10 ~]# docker inspect 99bf05e5697d |grep -E 'CgroupParent|Id' "Id": "99bf05e5697d52cf8755136e826b9a2087b3d5a971f40169b699a1f69d809202", "CgroupParent": "/kubepods/burstable/pod03381db2-cfcb-43ca-b5d5-a49b6f4a33f2",
|
这里解释一下:
k8s的Pod在docker中是由pause容器和工作容器组成的,所以为了管理这些容器,会有一个cgroup组的概念,即CgroupParent,所有容器会在在这个目录下创建以自身Id为名的子目录
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
| [root@master10 pod03381db2-cfcb-43ca-b5d5-a49b6f4a33f2]# cd /sys/fs/cgroup/cpu,cpuacct/kubepods/burstable/pod03381db2-cfcb-43ca-b5d5-a49b6f4a33f2/ [root@master10 pod03381db2-cfcb-43ca-b5d5-a49b6f4a33f2]# ls -la 总用量 0 drwxr-xr-x 4 root root 0 12月 31 19:18 . drwxr-xr-x 55 root root 0 12月 31 19:18 .. drwxr-xr-x 2 root root 0 12月 31 19:19 5c1e4e64e1972b049e11d20b831e27cdfb6409586e7459781ac279f56d0bf328 drwxr-xr-x 2 root root 0 4月 24 08:02 99bf05e5697d52cf8755136e826b9a2087b3d5a971f40169b699a1f69d809202 -rw-r -rw-r -r -rw-r -r -r -r -r -r -r -rw-r -rw-r -rw-r -rw-r -rw-r -r -rw-r -rw-r
|
3、拼凑cgroup路径
1 2 3 4 5 6 7 8 9
| cpu限制的路径: /sys/fs/cgroup/ + cpu,cpuacct/ + CgroupParent/ + Id
即:/sys/fs/cgroup/cpu,cpuacct/kubepods/burstable/pod03381db2-cfcb-43ca-b5d5-a49b6f4a33f2/99bf05e5697d52cf8755136e826b9a2087b3d5a971f40169b699a1f69d809202
内存限制的路径: /sys/fs/cgroup/ + memory/ + CgroupParent/ + Id
即:/sys/fs/cgroup/memory/kubepods/burstable/pod03381db2-cfcb-43ca-b5d5-a49b6f4a33f2/99bf05e5697d52cf8755136e826b9a2087b3d5a971f40169b699a1f69d809202
|
4、设置cpu限制
cpu限制的相关配置项为cpu.cfs_quota_us, 单位us,100Mi对应数值为100*1000
这里需要对cgroup组和自身容器同时进行设置,组=各容器之和,我们通常是单容器的,所以设置成一样值就行了,内存限制同理。
1 2 3 4
| cpu=$((100*1000)) cd /sys/fs/cgroup/cpu,cpuacct/kubepods/burstable/pod03381db2-cfcb-43ca-b5d5-a49b6f4a33f2/99bf05e5697d52cf8755136e826b9a2087b3d5a971f40169b699a1f69d809202 echo $((cpu+1)) > ../cpu.cfs_quota_us echo $cpu > cpu.cfs_quota_us
|
注:这里group的要求大于container,不然会提示无效参数
5、设置内存限制
内存限制的相关配置项为:
内存硬上限,一般是k8s limits中的值
- memory.memsw.limit_in_bytes
内存+sw之和的上限,一般跟limit_in_bytes一样,不过k8s会把group的设置为-1
1 2 3 4 5 6 7 8 9 10 11 12
| size=$((12*1024*1024*1024))
cd /sys/fs/cgroup/memory/kubepods/burstable/pod03381db2-cfcb-43ca-b5d5-a49b6f4a33f2/99bf05e5697d52cf8755136e826b9a2087b3d5a971f40169b699a1f69d809202
echo -1 > ../memory.memsw.limit_in_bytes echo $size > ../memory.limit_in_bytes echo -1 > ../memory.soft_limit_in_bytes
echo $size > memory.memsw.limit_in_bytes echo $size > memory.limit_in_bytes echo -1 > memory.soft_limit_in_bytes
|
注:这里需要注意顺序,不然可能会提示无效参数,具体顺序:
参考
https://www.cnblogs.com/sctb/p/17576082.html