在 Kubernetes 叢集中使用 sysctl

功能狀態: Kubernetes v1.21 [穩定]

本文說明如何在 Kubernetes 叢集中使用 sysctl 介面設定和使用核心參數。

開始之前

您需要有一個 Kubernetes 叢集,並且必須設定 kubectl 命令列工具以與您的叢集通訊。 建議在至少有兩個節點且未充當控制平面主機的叢集上執行本教學課程。 如果您還沒有叢集,可以使用 minikube 建立一個,或者您可以使用以下 Kubernetes playground 之一

對於某些步驟,您還需要能夠重新設定叢集上執行的 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 AM PST:sync safe sysctl ipv4.rmen and ipv4.wmem for v1.32 (de6ead9316)