Kubernetes集群使用sysctl

2023-12-20 49

Kubernetes 1.23 版本开始,kubelet 支持使用 / 或 . 作为 sysctl 参数的分隔符。 从 Kubernetes 1.25 版本开始,支持为 Pod 设置 sysctl 时使用设置名字带有斜线的 sysctl。 例如,可以使用点或者斜线作为分隔符表示相同的 sysctl 参数,以点作为分隔符表示为: kernel.shm_rmid_forced, 或者以斜线作为分隔符表示为:kernel/shm_rmid_forced。

一、准备开始

sysctl 是一个 Linux 特有的命令行工具,用于配置各种内核参数, 它在非 Linux 操作系统上无法使用。

必须拥有一个 Kubernetes 的集群,同时必须配置 kubectl 命令行工具与集群通信。 建议在至少有两个不作为控制平面主机的节点的集群上运行本教程。 如果还没有集群,可以通过 Minikube 构建一个自己的集群,或者可以使用下面的 Kubernetes 练习环境之一:

  • Killercoda
  • 玩转 Kubernetes

对一些步骤,需要能够重新配置在集群里运行的 kubelet 命令行的选项。

二、获取Sysctl参数列表

在 Linux 中,管理员可以通过 sysctl 接口修改内核运行时的参数。在 /proc/sys/ 虚拟文件系统下存放许多内核参数。这些参数涉及了多个内核子系统,如:

1、内核子系统(通常前缀为: kernel.);

2、网络子系统(通常前缀为: net.);

3、虚拟内存子系统(通常前缀为: vm.);

4、MDADM 子系统(通常前缀为: dev.)。

若要获取完整的参数列表,请执行以下命令:

sudo sysctl -a

三、安全/非安全Sysctl参数

Kubernetes 将 sysctl 参数分为 安全 和 非安全的。 安全 的 sysctl 参数除了需要设置恰当的命名空间外,在同一节点上的不同 Pod 之间也必须是 相互隔离的。这意味着 Pod 上设置 安全的 sysctl 参数时:

1、必须不能影响到节点上的其他 Pod;

2、必须不能损害节点的健康;

3、必须不允许使用超出 Pod 的资源限制的 CPU 或内存资源。

至今为止,大多数 有命名空间的 sysctl 参数不一定被认为是 安全 的。 以下几种 sysctl 参数是 安全的:

  • kernel.shm_rmid_forced,
  • net.ipv4.ip_local_port_range,
  • net.ipv4.tcp_syncookies,
  • net.ipv4.ping_group_range(从 Kubernetes 1.18 开始),
  • net.ipv4.ip_unprivileged_port_start(从 Kubernetes 1.22 开始),
  • net.ipv4.ip_local_reserved_ports(从 Kubernetes 1.27 开始)。

安全 sysctl 参数有一些例外:

  • net.* sysctl 参数不允许在启用主机网络的情况下使用;
  • net.ipv4.tcp_syncookies sysctl 参数在 Linux 内核 4.4 或更低的版本中是无命名空间的。

在未来的 Kubernetes 版本中,若 kubelet 支持更好的隔离机制, 则上述列表中将会列出更多 安全的 sysctl 参数。

四、启用非安全Sysctl参数

所有 安全的 sysctl 参数都默认启用;所有 非安全的 sysctl 参数都默认禁用,且必须由集群管理员在每个节点上手动开启。 那些设置了不安全 sysctl 参数的 Pod 仍会被调度,但无法正常启动。

参考上述警告,集群管理员只有在一些非常特殊的情况下(如:高可用或实时应用调整), 才可以启用特定的 非安全的 sysctl 参数。 如需启用 非安全的 sysctl 参数,请在每个节点上分别设置 kubelet 命令行参数,例如:

kubelet --allowed-unsafe-sysctls \
'kernel.msg*,net.core.somaxconn' ...

如果使用 Minikube,可以通过 extra-config 参数来配置:

minikube start --extra-config="kubelet.allowed-unsafe-sysctls=kernel.msg*,net.core.somaxconn"...

只有有命名空间的 sysctl 参数可以通过该方式启用。

五、设置Pod的Sysctl参数

目前,在 Linux 内核中,有许多的 sysctl 参数都是 有命名空间的。 这就意味着可以为节点上的每个 Pod 分别去设置它们的 sysctl 参数。 在 Kubernetes 中,只有那些有命名空间的 sysctl 参数可以通过 Pod 的 securityContext 对其进行配置。

以下列出有命名空间的 sysctl 参数,在未来的 Linux 内核版本中,此列表可能会发生变化。

  • kernel.shm*,
  • kernel.msg*,
  • kernel.sem,
  • fs.mqueue.*,
  • 那些可以在容器网络命名空间中设置的 net.*。但是,也有例外(例如 net.netfilter.nf_conntrack_max 和 net.netfilter.nf_conntrack_expect_max 可以在容器网络命名空间中设置,但在 Linux 5.12.2 之前它们是无命名空间的)。

没有命名空间的 sysctl 参数称为 节点级别的 sysctl 参数。 如果需要对其进行设置,则必须在每个节点的操作系统上手动地去配置它们, 或者通过在 DaemonSet 中运行特权模式容器来配置。

可使用 Pod 的 securityContext 来配置有命名空间的 sysctl 参数, securityContext 应用于同一个 Pod 中的所有容器。

此示例中,使用 Pod SecurityContext 来对一个安全的 sysctl 参数 kernel.shm_rmid_forced 以及两个非安全的 sysctl 参数 net.core.somaxconn 和 kernel.msgmax 进行设置。 在 Pod 规约中对 安全的 和 非安全的 sysctl 参数不做区分。

注意:为了避免破坏操作系统的稳定性,请在了解变更后果之后再修改 sysctl 参数。

apiVersion: v1
kind: Pod
metadata:
name: sysctl-example
spec:
securityContext:
sysctls:
- name: kernel.shm_rmid_forced
value: "0"
- name: net.core.somaxconn
value: "1024"
- name: kernel.msgmax
value: "65536"
...

由于 非安全的 sysctl 参数其本身具有不稳定性,在使用 非安全的 sysctl 参数时可能会导致一些严重问题, 如容器的错误行为、机器资源不足或节点被完全破坏,用户需自行承担风险。

最佳实践方案是将集群中具有特殊 sysctl 设置的节点视为 有污点的,并且只调度需要使用到特殊 sysctl 设置的 Pod 到这些节点上。建议使用 Kubernetes 的污点和容忍度特性 来实现它。

设置了 非安全的 sysctl 参数的 Pod 在禁用了这两种 非安全的 sysctl 参数配置的节点上启动都会失败。 与 节点级别的 sysctl 一样, 建议开启污点和容忍度特性或 为节点配置污点以便将 Pod 调度到正确的节点之上。

  • 广告合作

  • QQ群号:707632017

温馨提示:
1、本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。邮箱:2942802716#qq.com(#改为@)。 2、本站原创内容未经允许不得转裁,转载请注明出处“站长百科”和原文地址。