k3s クラスターには、kubelet ドロップインによってmemorySwap.swapBehavior が NoSwap から LimitedSwap に調整され、Ansible を使用してノードごとに固定化されていることが記録されます。
概要
次の条件を満たします。
- K8s 1.34 以降
- ノードのシステム ディスクはローカル SSD または NVME 高速ストレージを使用します
- cgroup v2
ノードスワップを使用してください。
これを有効にするには、kubelet config に次の構成を追加することをお勧めします。
failSwapOn: false
memorySwap:
swapBehavior: LimitedSwap
👍利益
👍️利点
- お金を節約する: 適格なワークロードは、メモリ不足が発生した場合に空き匿名ページをスワップアウトでき、ポッド密度が大幅に向上します。
- 安定性の向上: メモリ スパイクはバッファリングされ、OOM によって強制終了される唯一の方法ではなくなりました。
- 小さな変更
/etc/fstab一行も変更されておらず、kubelet 構成項目が 1 つだけ変更されています。 - : 利用可能
node.status.nodeInfo.swap.capacityそしてkubectl top nodes --show-swap交換を確認します。
📝メモ:
- Burstable およびリクエスト < 制限を持つコンテナのみがボーナスを受け取り、保証されたワークロードはまったく関係ありません。
- スケジューラはスワップを認識しません。容量計画は依然としてノードの物理メモリ計画に基づいているため、考慮することはできません。
- スワップアウトされるのは匿名ページであり、ディスク上に置かれるのは I/O です。システムディスクがローカル SSD または NVME 高速ストレージではない場合は、これを有効にしないでください。
コミュニティの一般的な見解は、スワップは RAM の代替としてではなく、メモリのスパイクに対する保険として使用されるべきであるというものです。
ホームラボクラスターの概要
/swap.img 昔 swapon 起き上がります(スワップがオンになっていない場合は、実際の戦闘中にスワップをオンにする必要があります)。その上で実行されているのはk3sです v1.36.5+k3s1。
NodeSwap は Kubernetes v1.34 で GA になったので、有効にしてみましょう。
デフォルトを入れ替える
キュベレットの memorySwap.swapBehavior デフォルト値は次のとおりです NoSwap。
このデフォルト値では、ホストでスワップが有効になっている場合でも、次のように記述した場合でも、 failSwapOn: falseコンテナcgroup memory.swap.max まだ 0。
📝注意事項:
failSwapOn: false重要なのは、「ノードがスワップしたときに kubelet が起動を拒否するかどうか」です。swapBehavior
/etc/fstab
- cgroup v2:
stat -fc %T /sys/fs/cgroup戻るcgroup2fs; - ホストではスワップが有効になっています。
swapon --show/swap.img; - k3s バージョンに対応する Kubernetes バージョンには、すでに NodeSwap GA (>=1.34) が含まれています。
前提条件が満たされていない場合、kubelet 構成を変更しても意味がありません。
アップストリームが推奨する値は、 LimitedSwapこれは「完全に解放」するための戦略ではありません。
- 保証、BestEffort 一律 NoSwap;
- キーポッド(
IsCriticalPod
| ポッドのQoS | リクエストと制限 | スワップは使えますか? |
|---|---|---|
| バースト可能 | リクエスト != 制限 | ✓ リミテッドスワップ |
| バースト可能 | リクエスト == 制限 | ✗ スワップなし |
| 保証されています | リクエスト == 制限 | ✗ スワップなし |
| ベストエフォート | なし | ✗ スワップなし |
| 任意 | IsCriticalPod | ✗ スワップなし |
containerSwapLimit = (containerMemoryRequest / nodeTotalMemory) × totalPodsSwapAvailable
これは意図的な設計です。スワップはメモリのスパイクを吸収するためにのみ使用され、容量計画には関与しません。
🐾 知らせ: モデレータはスワップを認識しません。これは、ノードの物理 RAM であると認識され、過剰に販売される「余分なメモリ」として扱われません。遅かれ早かれ、ノードは不安定になります。
/var/lib/rancher/k3s/agent/etc/kubelet.conf.d/00-k3s-defaults.conf。
デフォルト値をオーバーライドするには、後続のファイルを同じディレクトリに配置する必要があります。
ファイル名は次で終わる必要があります .conf 结尾,按字典序追加。 ここで使用されるのは 90-swap.conf。
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
failSwapOn: false
memorySwap:
swapBehavior: LimitedSwap
failSwapOn: false
00-k3s-defaults.conf 上書きや削除は行わないでください。それは k3s 自体の責任です。
埋め込む
kubeletを再起動します。 k3s の場合は、k3s サービスを再起動します。
各駅間で確認 kubectl get nodes すべての Ready メンバーと etcd メンバーは、次のメンバーを開始する前に正常な状態になります。複数のマスターが同時に再起動されると、etcd クォーラムが一時的に失われます。
検証チェックリスト
kubectl get --raw "/api/v1/nodes//proxy/configz" \
| jq '.kubeletconfig | {failSwapOn, memorySwap}'
期待する memorySwap.swapBehavior == "LimitedSwap"。
例は次のとおりです。
❯ kubectl get --raw "/api/v1/nodes/n100-cheshi-0/proxy/configz" | jq '.kubeletconfig | {failSwapOn, memorySwap}'
{
"failSwapOn": false,
"memorySwap": {
"swapBehavior": "LimitedSwap"
}
}
-
unknown:
❯ kubectl get nodes -o jsonpath="{range .items[*]}{.metadata.name}{"\t"}{.status.nodeInfo.swap.capacity}{"\n"}{end}"
n100-cheshi-0 8589930496
n100-jumper-0 4294963200
n100-jumper-1 4294963200
n100-jumper-2 4294963200
- スワップの使用状況を確認できます。
❯ kubectl top nodes --show-swap
NAME CPU(cores) CPU(%) MEMORY(bytes) MEMORY(%) SWAP(bytes) SWAP(%)
n100-cheshi-0 671m 16% 11088Mi 35% 0Mi 0%
n100-jumper-0 853m 21% 8065Mi 53% 0Mi 0%
n100-jumper-1 759m 18% 6317Mi 41% 0Mi 0%
n100-jumper-2 466m 11% 7270Mi 47% 0Mi 0%
最後の 2 つの列では、 SWAP(bytes) SWAP(%)。
kubectl exec -- cat /sys/fs/cgroup/memory.swap.max
2 つのポッドを比較します。
- リクエスト
64Mi/制限256Miバースタブルポッド、memory.swap.max > 0; - request == 制限が設定されているポッド、およびリクエスト/制限が設定されていないポッド、
memory.swap.max == 0。
2 つの数値セットが一致していることは、境界が期待どおりに機能していることを示しています。例は次のとおりです。
バースト可能なポッド:
cat /sys/fs/cgroup/memory.swap.max
36200448
cat /sys/fs/cgroup/memory.swap.max
0
私のホームラボクラスターはしばらく request == 制限の Pod を見つけられなかったので、ここでは表示しません。
要約する
-
swapBehaviorまだNoSwap別に書いてあるfailSwapOn: false - 変更する必要がある構成は 1 つだけです。
memorySwap.swapBehavior: LimitedSwap; - 有効範囲はバースト可能およびリクエスト != 制限に制限されており、クォータはノード メモリ内のリクエストの割合に応じて分割されます。
.conf接尾辞 + 辞書順00-k3s-defaults.conf後;
それだけです。