在 Kubernetes 叢集中使用 sysctl
Kubernetes v1.21 [穩定]
本文說明如何在 Kubernetes 叢集中使用 sysctl 介面設定和使用核心參數。
注意
從 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 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 以上版本)。
注意
關於安全 sysctl 的集合,有一些例外
- 啟用主機網路時,不允許使用
net.*
sysctl。 - 在 Linux 核心版本 4.5 或更低版本上,
net.ipv4.tcp_syncookies
sysctl 沒有命名空間。
當 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_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 設定的節點視為叢集內的污點節點,並且僅將需要這些 sysctl 設定的 Pod 排程到這些節點上。建議使用 Kubernetes 的 污點和容忍度功能 來實作此功能。
具有不安全 sysctl 的 Pod 將無法在任何未明確啟用這兩個不安全 sysctl 的節點上啟動。與節點級別的 sysctl 一樣,建議使用 污點和容忍度功能 或 節點上的污點 將這些 Pod 排程到正確的節點上。