深入理解Kubernetes - 基于OOMKill的QoS的设计

Overview 阅读完本文,您当了解 Linux oom kill Kubernetes oom 算法 Kubernetes QoS 本文只是个人理解,如果有大佬觉得不是这样的可以留言一起讨论,参考源码版本为 1.18.20,与高版本相差不大 什么是OOM Kill 当你的Linux机器内存不足时,内核会调用Out of Memory (OOM) killer来释放一些内存。这经常在运行许多内存密集型进程的服务器上遇到。 OOM Killer是如何选择要杀死的进程的? Linux内核为每个运行的进程分配一个分数,称为 oom_score,==显示在内存紧张时终止该进程的可能性有多大==。该 Score 与进程使用的内存量成比例。 Score 是进程使用内存的百分比乘以10。因此,最大分数是 $100% \times 10 = 1000$。此外,如果一个进程以特权用户身份运行,那么与普通用户进程相比,它的 oom_score 会稍低。 在主发行版内核会将 /proc/sys/vm/overcommit_memory 的默认值设置为零,这意味着进程可以请求比系统中当前可用的内存更多的内存。这是基于以下启发式完成的:分配的内存不会立即使用,并且进程在其生命周期内也不会使用它们分配的所有内存。如果没有过度使用,系统将无法充分利用其内存,从而浪费一些内存。过量使用内存允许系统以更有效的方式使用内存,但存在 OOM 情况的风险。占用内存的程序会耗尽系统内存,使整个系统陷入瘫痪。当内存太低时,这可能会导致这样的情况:即使是单个页面也无法分配给用户进程,从而允许管理员终止适当的任务,或者内核执行重要操作,例如释放内存。在这种情况下,OOM Killer 就会介入,并将该进程识别为牺牲品,以保证系统其余部分的利益。 用户和系统管理员经常询问控制 OOM Killer 行为的方法。为了方便控制,引入了 /proc/<pid>/oom_adj 来防止系统中的重要进程被杀死,并定义进程被杀死的顺序。 oom_adj 的可能值范围为 -17 到 +15。Score 越高,相关进程就越有可能被 OOM-killer Kill。如果 oom_adj 设置为 -17,则 OOM Killer 不会 Kill 该进程。 oom_score 分数为 1 ~ 1000,值越低,程序被杀死的机会就越小。 oom_score 0 表示该进程未使用任何可用内存。 oom_score 1000 表示该进程正在使用 100% 的可用内存,大于1000,也取1000。 谁是糟糕的进程? 在内存不足的情况下选择要被终止的进程是基于其 oom_score 。糟糕进程 Score 被记录在 /proc/<pid>/oom_score 文件中。该值是基于系统损失的最小工作量、回收的大量内存、不终止任何消耗大量内存的无辜进程以及终止的进程数量最小化(如果可能限制在一个)等因素来确定的。糟糕程度得分是使用进程的原始内存大小、其 CPU 时间(utime + stime)、运行时间(uptime - 启动时间)以及其 oom_adj 值计算的。进程使用的内存越多,得分越高。进程在系统中存在的时间越长,得分越小。...

 ·  · 

kubernetes上jprofiler自动映射 - 架构设计与实现

项目设计 需求:外部分析器工具连接到运行在 kubernetes 集群上 Java pod 的 JVM,通过 jprofiler 暴露其接口,可以直接连接至这个 java pod,并且可以实现自动化映射,为了安全保证,映射将在不活跃时自动取消。 需要解决的问题 Jprofiler 如何在 kubernetes 集群中运行: 方法1:打包至业务Pod容器内 缺点:需要侵入业务Pod内,不方便 方法2:使用 Init Container 将 JProfiler 安装复制到 Init Container 和将在 Pod 中启动的其他容器之间共享的卷 方法3:使用 sidecar 方式 共享业务Pod与 sidecar 共享名称空间 缺点:涉及到容器共享进程空间,与 jprofiler-agent 机制问题,所以需要共享 /tmp 目录 JProfiler finds JVMs via the “Attach API” that is part of the JDK. Have a look at the $TMP/hsperfdata_$USER directory, which is created by the hot spot JVM. It should contain PID files for all running JVMs....

 ·  · 

client-go - Pod使用in-cluster方式访问集群

在我们基于 Kubernetes 编写云原生 GoLang 代码时,通常在本地调试时,使用 kubeconfig 文件,以构建基于 clientSet 的客户端。而在将代码作为容器部署到集群时,则会使用集群 (in-cluster) 内的配置。 clientcmd 模块用于通过传递本地 kubeconfig 文件构建 clientSet。因此,在容器内使用相同模块构建 clientSet 将需要维护容器进程可访问的 kubeconfig 文件,并设置具有访问 Kubernetes 资源权限的 serviceaccount token。 下面是一个基于 kubeconfig 访问集群的代码模式 go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var ( k8sconfig *string //使用kubeconfig配置文件进行集群权限认证 restConfig *rest.Config err error ) if home := homedir.HomeDir(); home != "" { k8sconfig = flag.String("kubeconfig", fmt.Sprintf("./admin.conf"), "kubernetes auth config") } flag....

 ·  · 

K8S Admission Webhook官方扩展版 - ValidatingAdmissionPolicy

相关阅读:深入理解Kubernetes 4A - Admission Control源码解析 准入 (Admission) 是 Kubernetes 提供 4A 安全认证中的一个步骤,在以前版本中 (1,26-),官方提供了 webhook 功能,使用户可以自行的定义 Kubernetes 资源准入规则,但这些是有成本的,需要自行开发 webhook,下图是 Kubernetes准入控制流程。 图:Kubernetes API 请求的请求处理步骤图 Source:https://kubernetes.io/blog/2019/03/21/a-guide-to-kubernetes-admission-controllers/ 在 Kubernetes 1.26 时 引入了 ValidatingAdmissionPolicy alpha 版,这个功能等于将 Admission Webhook controller 作为了一个官方扩展版,通过资源进行自行扩展,通过这种方式带来下面优势: 减少了准入请求延迟,提高可靠性和可用性 能够在不影响可用性的情况下失败关闭 避免 webhooks 的操作负担 ValidatingAdmissionPolicy 说明 验证准入策略提供一种声明式的、进程内的替代方案来验证准入 Webhook。 验证准入策略使用通用表达语言 (Common Expression Language,CEL) 来声明策略的验证规则。 验证准入策略是高度可配置的,使配置策略的作者能够根据集群管理员的需要, 定义可以参数化并限定到资源的策略 下面是一个 ValidatingAdmissionPolicy 的示例,配置 Deployment 必须拥有的副本数的限制 yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 apiVersion: admissionregistration....

 ·  · 

Kubernetes集群中的IP伪装 - ip-masq-agent

“IP 伪装” 通常应用于云环境中,例如 GKE, AWS, CCE 等云厂商都有使用 “IP伪装” 技术,本文将围绕 “IP伪装” 技术本身,以及这项技术在 Kubernetes 集群中的实现应用 ip-masq-agent 的源码分析,以及 ”IP伪装“ 能为 Kubernetes 带来什么作用,这三个方向阐述。 什么是IP伪装? IP 伪装 (IP Masquerade) 是 Linux 中的一个网络功能,一对多 (1 to Many) 的网络地址转换 (NAT) 的功能 。 IP 伪装允许一组计算机通过 “伪装” 网关无形地访问互联网。对于互联网上的其他计算机,出站流量将看起来来自于 IP MASQ 服务器本身。互联网上任何希望发回数据包(作为答复)的主机必须将该数据包发送到网关 (IP MASQ 服务器本身)。记住,网关(IP MASQ 服务器本身)是互联网上唯一可见的主机。网关重写目标地址,用被伪装的机器的 IP 地址替换自己的地址,并将该数据包转发到本地网络进行传递。 除了增加的功能之外,IP Masquerade 为创建一个高度安全的网络环境提供了基础。通过良好构建的防火墙,突破经过良好配置的伪装系统和内部局域网的安全性应该会相当困难。 IP Masquerade 从 Linux 1.3.x 开始支持,目前基本所有 Linux 发行版都带有 IP 伪装的功能 什么情况下不需要IP伪装 已经连接到互联网的独立主机 为其他主机分配了多个公共地址 IP伪装在Kubernetes集群中的应用 IP 伪装通常应用在大规模 Kubernetes 集群中,主要用于解决 “地址冲突” 的问题,例如在 GCP 中,通常是一种 IP 可路由的网络模型,例如分配给 Pod service 的 ClusterIP 只能在 Kubernetes 集群内部可用,而分配 IP CIDR 又是一种不可控的情况,假设,我们为 k8s 分配的 IP CIDR 段如下表所示:...

 ·  ·