在 Kubernetes 叢集中使用 sysctls

特性狀態: Kubernetes v1.21 [stable]

本文件描述瞭如何使用 sysctl 介面在 Kubernetes 叢集中配置和使用核心引數。

準備工作

你需要擁有一個 Kubernetes 叢集,並且 kubectl 命令列工具已被配置為與你的叢集通訊。建議在至少有兩個不充當控制平面主機的節點的叢集上執行本教程。如果你還沒有叢集,你可以使用 minikube 建立一個,或者使用這些 Kubernetes 遊樂場之一

對於某些步驟,你還需要能夠重新配置在叢集上執行的 kubelet 的命令列選項。

列出所有 Sysctl 引數

在 Linux 中,sysctl 介面允許管理員在執行時修改核心引數。引數透過 /proc/sys/ 虛擬程序檔案系統提供。這些引數涵蓋了各種子系統,例如:

  • 核心(通用字首:kernel.
  • 網路(通用字首:net.
  • 虛擬記憶體(通用字首:vm.
  • MDADM(通用字首:dev.
  • 更多子系統在核心文件中描述。

要獲取所有引數的列表,你可以執行

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+)。

當 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 獨立設定。只有名稱空間化的 sysctl 可以透過 Kubernetes 中的 Pod securityContext 進行配置。

以下 sysctl 已知為名稱空間化。此列表可能會在未來的 Linux 核心版本中更改。

  • kernel.shm*,
  • kernel.msg*,
  • kernel.sem,
  • fs.mqueue.*,
  • 那些可以在容器網路名稱空間中設定的 net.*。但是,也有例外(例如,net.netfilter.nf_conntrack_maxnet.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.somaxconnkernel.msgmax。在規範中,**安全**和**不安全**的 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 設定的 Pod 排程到這些節點上。建議使用 Kubernetes 的 **汙點和容忍**特性 來實現這一點。

一個帶有**不安全**sysctl 的 Pod 將無法在任何未明確啟用這兩個**不安全**sysctl 的節點上啟動。與**節點級別**sysctl 一樣,建議使用 **汙點和容忍**特性節點汙點 來將這些 Pod 排程到正確的節點上。

最後修改於 2024 年 9 月 20 日太平洋標準時間上午 11:36:同步 v1.32 的安全 sysctl ipv4.rmen 和 ipv4.wmem (de6ead9316)