overhead
与传统 runC 运行时不同,由于 Kata Containers 本身是一个轻量化的虚拟机,所以在资源开销方面不容忽视,这部分资源主要用于虚拟机的引导启动与 Kata 自身组件的运作。
在 K8s 1.18 版本之后提供了 PodOverhead 的特性,用于描述运行时所带来的额外资源开销。
如上所示,通过 overhead.podFixed 指定额外的 1C,2G 资源,这部分资源可以被 K8s 感知,从而影响到 Pod 调度、resourceQuota 以及 Pod 驱逐等场景。但是,overhead 中声明的额外资源开销仅作用于 K8s 层面,最终会注入到使用对应 runtimeClass 的 Pod 中,并不会对 Kata VM 的大小产生影响。
Pod QoS
overhead 的注入不会影响到 Pod 的 QoS。overhead 中申请的额外资源,会追加到 Pod 的 request 值,从而影响到控制面的调度等场景,如果 Pod 声明了limit,同样的也会追加到limit 中。需要注意的是:虽然 overhead 最终会影响到pod limit 和 request,但是不会影响到Pod 绑核条件,绑核仍然依据request和limit。
一个申请了 1C 1G 的容器
最终的资源消耗为
Kata VM
Kata 配置文件中默认的 VM 大小为 1C 2G
默认情况下,Kata VM 最小资源为1C 256M,当低于 256M时,会重置为2G。
Kata VM中额外的资源是通过hotplug的方式实现,资源目前特指 CPU 和 Memory 两种,Pod request 影响到调度层面的行为,不同于limit,request 并不会对 Kata VM 的大小产生影响,也就是说最终 VM 的资源大小为 limit + default,其中 limit 为 Pod 声明的 limit,不包含 overhead 在内,default 为Kata 配置文件中的基础 VM 大小。
以上述 guaranteed Pod 为例,可以看到最终的 VM 是一个 2C,3G 的规格大小
Cgroup
从Kubernetes 角度来讲,Cgroup 指的是Pod Cgroup,由Kubelet创建,限制的是Pod的资源;从Container 角度来讲,Cgroup指的是Container Cgroup,由对应的 runtime创建,限制的是container 的资源。
但是为了可以获取到更准确的容器资源,Kubelet 会根据 Container Cgroup去调整Pod Cgroup。在传统的 runtime中,两者没有太大的区别。而 Kata Containers引入VM的概念,所以针对这种情况有两种处理方式:
· 启用SandboxCgroupOnly,Kubelet 在调整 Pod Cgroup 的大小时,会将 sandbox 的开销统计进去
· 禁用SandboxCgroupOnly,sandbox 的开销和 Pod Cgroup 分开计算,独立存在
从host 视角来看,在Kata 没有开启 SandboxCgroupOnly 的时候,存在有两个容器(infra 和 workload)的Cgroup 策略文件,结构模式类似于runC,但是并没有找到有关限制进程信息的 task 文件。
从container 视角看,无论是哪种运行时,Cgroup均为 Pod工作负载的最大资源限量。
从 VM 视角看,无论是否开启 SandboxCgroupOnly,都可以看到有两个容器(infra 和 workload)的 Cgroup 策略文件,VM 中的Cgroup 都是针对工作负载做的限制,而这个视图更像是runC中看到的一切。
示例
Kata 配置中的基础 VM 大小为 5C 2G
runtimeClass 中声明了一个额外的 1C
声明了一个最大 2C 的业务容器
根据以上结论应存在:
Ø 1C 的额外资源会作用于 Kata Containers 的额外开销,而不是业务负载
Ø 2C 的容器资源为容器能够使用的最大使用上限
Ø overhead 的 1C + Pod 的 2C 一共的 3C为 VM 的最大使用量
Ø VM 中 CPU 的个数应为 7
查看 Pod 的资源限制
Pod 中运行高负载应用
在 host 上可以看到,进程占用了 2C,而并非上一步看到的3C
VM 中运行高负载应用
在 host 上可以看到,这次进程占用了 3C
也就是说,Pod limit 最终作用的对象就是业务容器的资源限制,而overhead作用的对象是附加在业务容器之上的,两者之和是最终 VM 的资源限制。
总结
Kubernetes在用Kata Containers作为底层runtime后,对于runtime 运行环境的额外开销不容忽视,但是K8s角度又无法感知到这部分资源,而overhead 的设计就弥补了这一缺陷,并且 overhead 对于资源的额外声明,是会统计在 Cgroup 中的,所以即使底层 Kata Containers 的配置即使很高,也可以通过 limit 实现资源限额,这是因为 Kata 对于资源并不是完全占用,不同的Kata VM之间会存在资源抢占现象。在此方面,Kata Containers 和传统容器的设计理念相同。