在 Kubernetes 集群中使用 sysctl
Kubernetes v1.21 [稳定]本文档描述了如何使用 sysctl 接口在 Kubernetes 集群中配置和使用内核参数。
说明
从 Kubernetes 1.23 版本开始,kubelet 支持使用/ 或 . 作为 sysctl 名称的分隔符。从 Kubernetes 1.25 版本开始,为 Pod 设置 Sysctl 支持使用斜杠设置带有斜杠的 sysctl。例如,您可以使用句点作为分隔符,或使用斜杠作为分隔符来表示相同的 sysctl 名称,如 kernel.shm_rmid_forced 或 kernel/shm_rmid_forced。有关更多 sysctl 参数转换方法详细信息,请参阅 Linux man-pages 项目中的 sysctl.d(5) 页面。开始之前
说明
sysctl 是一个 Linux 特定的命令行工具,用于配置各种内核参数,它在非 Linux 操作系统上不可用。您需要一个 Kubernetes 集群,并且 kubectl 命令行工具必须配置为与您的集群通信。建议在至少有两个节点(不充当控制平面主机)的集群上运行本教程。如果您还没有集群,可以使用 minikube 创建一个,或者可以使用以下 Kubernetes 游乐场
对于某些步骤,您还需要能够重新配置集群上运行的 kubelet 的命令行选项。
列出所有 Sysctl 参数
在 Linux 中,sysctl 接口允许管理员在运行时修改内核参数。参数可通过 /proc/sys/ 虚拟进程文件系统获得。这些参数涵盖了各种子系统,例如
- 内核(常见前缀:
kernel.) - 网络(常见前缀:
net.) - 虚拟内存(常见前缀:
vm.) - MDADM(常见前缀:
dev.) - 更多子系统在 Kernel docs 中描述。
要获取参数列表,您可以运行
sudo sysctl -a
安全和不安全的 Sysctl
Kubernetes 将 sysctl 分类为安全或不安全。除了适当的命名空间之外,安全的 sysctl 必须在同一节点上的 Pod 之间隔离。这意味着为 Pod 设置安全的 sysctl
- 不得对节点上的任何其他 Pod 产生任何影响
- 不得允许损害节点的健康
- 不得允许获取 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 起,需要内核 3.16+);net.ipv4.tcp_keepalive_time(自 Kubernetes 1.29 起,需要内核 4.5+);net.ipv4.tcp_fin_timeout(自 Kubernetes 1.29 起,需要内核 4.6+);net.ipv4.tcp_keepalive_intvl(自 Kubernetes 1.29 起,需要内核 4.5+);net.ipv4.tcp_keepalive_probes(自 Kubernetes 1.29 起,需要内核 4.5+)。net.ipv4.tcp_rmem(自 Kubernetes 1.32 起,需要内核 4.15+)。net.ipv4.tcp_wmem(自 Kubernetes 1.32 起,需要内核 4.15+)。
说明
存在一些安全 sysctl 集合的例外情况
- 启用主机网络时,不允许使用
net.*sysctl。 - 在 Linux 内核版本 4.5 或更低版本上,
net.ipv4.tcp_syncookiessysctl 未命名空间化。
当 kubelet 支持更好的隔离机制时,此列表将在未来的 Kubernetes 版本中扩展。
启用不安全的 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 上独立设置。只有通过 Kubernetes 中的 pod securityContext 可配置的命名空间 sysctl。
以下 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。规范中没有安全和不安全 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 设置的 Pod 调度到这些节点上。建议使用 Kubernetes 污点和容忍度功能来实现此目的。
具有不安全 sysctl 的 Pod 将无法在未显式启用这些两个不安全 sysctl 的任何节点上启动。与节点级别 sysctl 一样,建议使用 污点和容忍度功能 或 节点上的污点 将这些 Pod 调度到正确的节点上。