在 Kubernetes 叢集中使用 sysctls
Kubernetes v1.21 [stable]
本文件描述瞭如何使用 sysctl 介面在 Kubernetes 叢集中配置和使用核心引數。
注意
從 Kubernetes 1.23 版本開始,kubelet 支援使用/
或 .
作為 sysctl 名稱的分隔符。從 Kubernetes 1.25 版本開始,為 Pod 設定 Sysctls 支援使用斜槓來設定 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.
) - 更多子系統在核心文件中描述。
要獲取所有引數的列表,你可以執行
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 設定的 Pod 排程到這些節點上。建議使用 Kubernetes 的 **汙點和容忍**特性 來實現這一點。
一個帶有**不安全**sysctl 的 Pod 將無法在任何未明確啟用這兩個**不安全**sysctl 的節點上啟動。與**節點級別**sysctl 一樣,建議使用 **汙點和容忍**特性 或 節點汙點 來將這些 Pod 排程到正確的節點上。