7.9. コンテナーでの sysctl の使用
Sysctl の設定は Kubernetes を通じて公開され、ユーザーは実行時に特定のカーネルパラメーターを変更することができます。namespace を使用する sysctl のみを Pod 上で独立して設定できます。sysctl に namespace がない場合 (ノードレベルと呼ばれる)、Node Tuning Operator をしようなどなど、sysctl を設定する別の方法を使用する必要があります。
ネットワーク sysctl は特殊な sysctl カテゴリーです。ネットワーク sysctl には、以下が含まれます。
-
すべてのネットワークで有効な、
net.ipv4.ip_local_port_range
ようなシステム全体の sysctl。これらは、ノード上の各 Pod に対して個別に設定できます。 -
特定の Pod の特定の追加ネットワークインターフェイスにのみ適用されるインターフェイス固有の sysctl (
net.ipv4.conf.IFNAME.accept_local
など)。これらは、追加のネットワーク設定ごとに個別に設定できます。ネットワークインターフェイスの作成後にtuning-cni
で設定を使用して、これらを設定します。
さらに 安全 とみなされる sysctl のみがデフォルトでホワイトリストに入れられます。 他の 安全でない sysctl はノードで手動で有効にし、ユーザーが使用できるようにできます。
関連情報
7.9.1. sysctl について
Linux では、管理者は sysctl インターフェイスを使用してランタイム時にカーネルパラメーターを変更することができます。パラメーターは /proc/sys/
仮想プロセスファイルシステムから利用できます。これらのパラメーターは以下を含む各種のサブシステムを対象とします。
-
カーネル (共通の接頭辞:
kernel.
) -
ネットワーク (共通の接頭辞:
net.
) -
仮想メモリー (共通の接頭辞:
vm.
) -
MDADM (共通の接頭辞:
dev.
)
追加のサブシステムについては、カーネルのドキュメント で説明されています。すべてのパラメーターの一覧を表示するには、以下のコマンドを実行します。
$ sudo sysctl -a
7.9.2. namespace とノードレベルの sysctl
Linux カーネルでは、数多くの sysctl に namespace が使用されています。これは、それらをノードの各 Pod に対して個別に設定できることを意味します。namespace の使用は、sysctl を Kubernetes 内の Pod 環境でアクセス可能にするための要件になります。
以下の sysctl は namespace を使用するものとして知られている sysctl です。
-
kernel.shm*
-
kernel.msg*
-
kernel.sem
-
fs.mqueue.*
また、net.
* グループの大半の sysctl には namespace が使用されていることが知られています。それらの namespace の使用は、カーネルのバージョンおよびディストリビューターによって異なります。
namespace が使用されていない sysctl は ノードレベル と呼ばれており、クラスター管理者がノードの基礎となる Linux ディストリビューションを使用 (例: /etc/sysctls.conf
ファイルを変更) するか、特権付きコンテナーでデーモンセットを使用することによって手動で設定する必要があります。Node Tuning Operator を使用して node-level を設定できます。
特殊な sysctl が設定されたノードにテイントのマークを付けることを検討してください。それらの sysctl 設定を必要とするノードにのみ Pod をスケジュールします。テイントおよび容認 (Toleration) 機能を使用してノードにマークを付けます。
7.9.3. 安全および安全でない sysctl
sysctl は 安全な および 安全でない sysctl に分類されます。
システム全体の sysctl を安全に考慮するには、namespace を指定する必要があります。namespace を使用した sysctl は namespace と Pod 間で分離されるようにします。1 つの Pod に sysctl を設定する場合は、以下のいずれかを追加することはできません。
- この設定はノードのその他の Pod に影響を与えないものである。
- ノードの正常性に切り離す。
- この設定は Pod のリソース制限を超える CPU またはメモリーリソースの取得を許可しないものである。
namespace を使用するだけでは、sysctl を安全に考慮するには不十分です。
OpenShift Container Platform で許可リストに追加されていない sysctl は、OpenShift Container Platform では安全でないと見なされます。
安全でない sysctl はデフォルトでは許可されません。システム全体の sysctl の場合、クラスター管理者はノードごとに手動で有効にする必要があります。無効にされた安全でない sysctl が設定された Pod はスケジュールされますが、起動されません。
インターフェイス固有の安全でない sysctls を手動で有効にすることはできません。
OpenShift Container Platform は以下のシステム全体およびインターフェイス固有の安全な sysctl を許可された安全なリストに追加します。
sysctl | 説明 |
---|---|
|
|
|
TCP および UDP によって使用されるローカルポート範囲を定義して、ローカルポートを選択します。最初の番号は最初のポート番号で、2 番目の番号は最後のローカルポート番号になります。可能であれば、これらの数値は異なるパリティー (偶数値と奇数値) を持つ方が良い。 |
|
|
|
これにより、 |
|
これは、ネットワーク namespace 内の最初の権限のないポートを定義します。特権ポートをすべて無効にするには、これを |
sysctl | 説明 |
---|---|
| IPv4 ICMP リダイレクトメッセージを受信します。 |
| SRR (Strict Source Route) オプションの付いた IPv4 パケットを受け入れる。 |
| ARP テーブルにない IPv4 アドレスで余計な ARP フレームの動作を定義します。
|
| IPv4 アドレスとデバイスの変更を通知するモードを定義します。 |
| この IPv4 インターフェイスの IPSEC ポリシー (SPD) を無効にします。 |
| インターフェイスの現在のゲートウェイリストにリストされているゲートウェイに対する ICMP リダイレクトメッセージのみを受信します。 |
| 送信リダイレクトは、ノードがルーターとして動作する場合にのみ有効になります。つまり、ホストは ICMP リダイレクトメッセージを送信しないでください。これは、特定の宛先で利用可能なルーティングパスの改善についてホストに通知するためにルーターによって使用されます。 |
| IPv6 ルーター広告を受け入れ、それらを使用して自動設定します。また、ルーター要請の送信の可否を判断します。ルーターへの通知は、機能の設定がルーター広告を受け入れる場合にのみ送信されます。 |
| IPv6 ICMP リダイレクトメッセージを受信します。 |
| SRR オプションで IPv6 パケットを受信します。 |
| ARP テーブルに存在しない IPv6 アドレスで余計な ARP フレームの動作を定義します。
|
| IPv6 アドレスとデバイスの変更を通知するモードを定義します。 |
| このパラメーターは、IPv6 の neighbour テーブルで、IP マッピングの有効期間に対するハードウェアアドレスを制御します。 |
| 隣接する検出メッセージの再送信タイマーを設定します。 |
tuning
CNI プラグインを使用してこれらの値を設定する場合は、値 IFNAME
をそのまま使用します。インターフェイス名は IFNAME
トークンによって表され、ランタイム時にインターフェイスの実際の名前に置き換えられます。
関連情報
7.9.4. 安全な sysctl での Pod の起動
Pod の securityContext
を使用して sysctl を Pod に設定できます。securityContext
は同じ Pod 内のすべてのコンテナーに適用されます。
安全な sysctl はデフォルトで許可されます。
この例では、Pod securityContext
を使用して以下の安全な sysctl を設定します。
-
kernel.shm_rmid_forced
-
net.ipv4.ip_local_port_range
-
net.ipv4.tcp_syncookies
-
net.ipv4.ping_group_range
オペレーティングシステムが不安定になるのを防ぐには、変更の影響を確認している場合にのみ sysctl パラメーターを変更します。
以下の手順を使用して、設定される sysctl 設定で Pod を起動します。
ほとんどの場合、既存の Pod 定義を変更し、securityContext
仕様を追加します。
手順
以下の例のように、サンプル Pod を定義し、
securityContext
仕様を追加する YAML ファイルのsysctl_pod.yaml
を作成します。apiVersion: v1 kind: Pod metadata: name: sysctl-example namespace: default spec: containers: - name: podexample image: centos command: ["bin/bash", "-c", "sleep INF"] securityContext: runAsUser: 2000 1 runAsGroup: 3000 2 allowPrivilegeEscalation: false 3 capabilities: 4 drop: ["ALL"] securityContext: runAsNonRoot: true 5 seccompProfile: 6 type: RuntimeDefault sysctls: - name: kernel.shm_rmid_forced value: "1" - name: net.ipv4.ip_local_port_range value: "32770 60666" - name: net.ipv4.tcp_syncookies value: "0" - name: net.ipv4.ping_group_range value: "0 200000000"
- 1
runAsUser
は、コンテナーが実行されるユーザー ID を制御します。- 2
runAsGroup
は、コンテナーが実行されるプライマリーグループ ID を制御します。- 3
allowPrivilegeEscalation
は、Pod が特権の昇格を許可するように要求できるかどうかを決定します。指定しない場合、デフォルトで true に設定されます。このブール値は、no_new_privs
フラグがコンテナープロセスに設定されるかどうかを直接制御します。- 4
capabilities
は、完全なルートアクセスを許可せずに権限操作を許可します。このポリシーにより、すべての機能が Pod から削除されます。- 5
runAsNonRoot: true
は、コンテナーが 0 以外の任意の UID を持つユーザーで実行されることを要求します。- 6
RuntimeDefault
は、Pod またはコンテナーワークロードのデフォルトの seccomp プロファイルを有効にします。
以下のコマンドを実行して Pod を作成します。
$ oc apply -f sysctl_pod.yaml
次のコマンドを実行して、Pod が作成されていることを確認します。
$ oc get pod
出力例
NAME READY STATUS RESTARTS AGE sysctl-example 1/1 Running 0 14s
次のコマンドを実行して、Pod にログインします。
$ oc rsh sysctl-example
設定された sysctl フラグの値を確認します。たとえば、以下のコマンドを実行して
kernel.shm_rmid_forced
の値を見つけます。sh-4.4# sysctl kernel.shm_rmid_forced
予想される出力
kernel.shm_rmid_forced = 1
7.9.5. 安全でない sysctl での Pod の起動
安全でない sysctl が設定された Pod は、クラスター管理者がそのノードの安全でない sysctl を明示的に有効にしない限り、いずれのノードでも起動に失敗します。ノードレベルの sysctl の場合のように、それらの Pod を正しいノードにスケジュールするには、テイントおよび容認 (Toleration)、またはノードのラベルを使用します。
以下の例では Pod の securityContext
を使用して安全な sysctl kernel.shm_rmid_forced
および 2 つの安全でない sysctl net.core.somaxconn
および kernel.msgmax
を設定します。仕様では 安全な sysctl と 安全でない sysctl は区別されません。
オペレーティングシステムが不安定になるのを防ぐには、変更の影響を確認している場合にのみ sysctl パラメーターを変更します。
以下の例は、安全な sysctl を Pod 仕様に追加する際に発生する内容を示しています。
手順
以下の例のように、サンプル Pod を定義し、
securityContext
仕様を追加する YAML ファイルsysctl-example-unsafe.yaml
を作成します。apiVersion: v1 kind: Pod metadata: name: sysctl-example-unsafe spec: containers: - name: podexample image: centos command: ["bin/bash", "-c", "sleep INF"] securityContext: runAsUser: 2000 runAsGroup: 3000 allowPrivilegeEscalation: false capabilities: drop: ["ALL"] securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault sysctls: - name: kernel.shm_rmid_forced value: "0" - name: net.core.somaxconn value: "1024" - name: kernel.msgmax value: "65536"
以下のコマンドを使用して Pod を作成します。
$ oc apply -f sysctl-example-unsafe.yaml
以下のコマンドを使用して安全でない sysctl がノードに許可されないため、Pod がスケジュールされているがデプロイされないことを確認します。
$ oc get pod
出力例
NAME READY STATUS RESTARTS AGE sysctl-example-unsafe 0/1 SysctlForbidden 0 14s
7.9.6. 安全でない sysctl の有効化
クラスター管理者は、高パフォーマンスまたはリアルタイムのアプリケーション調整などの非常に特殊な状況で特定の安全でない sysctl を許可することができます。
安全でない sysctl を使用する必要がある場合、クラスター管理者は特定のタイプのノードに対してそれらを個別に有効にする必要があります。sysctl には namespace を使用する必要があります。
Security Context Constraints の allowedUnsafeSysctls
フィールドに sysctl または sysctl パターンのリストを指定することで、どの sysctl を Pod に設定するかをさらに制御できます。
-
allowedUnsafeSysctls
オプションは、高パフォーマンスやリアルタイムのアプリケーションチューニングなどの特定ニーズを管理します。
安全でないという性質上、安全でない sysctl は各自の責任で使用されます。 場合によっては、コンテナーの正しくない動作やリソース不足、またはノードの破損などの深刻な問題が生じる可能性があります。
手順
以下のコマンドを実行して、OpenShift Container Platform クラスターの既存の MachineConfig オブジェクトをリスト表示し、マシン設定にラベルを付ける方法を決定します。
$ oc get machineconfigpool
出力例
NAME CONFIG UPDATED UPDATING DEGRADED MACHINECOUNT READYMACHINECOUNT UPDATEDMACHINECOUNT DEGRADEDMACHINECOUNT AGE master rendered-master-bfb92f0cd1684e54d8e234ab7423cc96 True False False 3 3 3 0 42m worker rendered-worker-21b6cb9a0f8919c88caf39db80ac1fce True False False 3 3 3 0 42m
以下のコマンドを実行して、安全でない sysctl が設定されたコンテナーが実行されるマシン設定プールにラベルを追加します。
$ oc label machineconfigpool worker custom-kubelet=sysctl
KubeletConfig
カスタムリソース (CR) を定義する YAML ファイルset-sysctl-worker.yaml
を作成します。apiVersion: machineconfiguration.openshift.io/v1 kind: KubeletConfig metadata: name: custom-kubelet spec: machineConfigPoolSelector: matchLabels: custom-kubelet: sysctl 1 kubeletConfig: allowedUnsafeSysctls: 2 - "kernel.msg*" - "net.core.somaxconn"
以下のコマンドを実行してオブジェクトを作成します。
$ oc apply -f set-sysctl-worker.yaml
以下のコマンドを実行して、Machine Config Operator が新規のレンダリングされた設定を生成し、これをマシンに適用します。
$ oc get machineconfigpool worker -w
数分後、
UPDATING
のステータスが True から False に変化します。NAME CONFIG UPDATED UPDATING DEGRADED MACHINECOUNT READYMACHINECOUNT UPDATEDMACHINECOUNT DEGRADEDMACHINECOUNT AGE worker rendered-worker-f1704a00fc6f30d3a7de9a15fd68a800 False True False 3 2 2 0 71m worker rendered-worker-f1704a00fc6f30d3a7de9a15fd68a800 False True False 3 2 3 0 72m worker rendered-worker-0188658afe1f3a183ec8c4f14186f4d5 True False False 3 3 3 0 72m
次の例に示すように、サンプルの Pod を定義する YAML ファイル
sysctl-example-safe-unsafe.yaml
を作成し、securityContext
の仕様を追加します。apiVersion: v1 kind: Pod metadata: name: sysctl-example-safe-unsafe spec: containers: - name: podexample image: centos command: ["bin/bash", "-c", "sleep INF"] securityContext: runAsUser: 2000 runAsGroup: 3000 allowPrivilegeEscalation: false capabilities: drop: ["ALL"] securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault sysctls: - name: kernel.shm_rmid_forced value: "0" - name: net.core.somaxconn value: "1024" - name: kernel.msgmax value: "65536"
以下のコマンドを実行して Pod を作成します。
$ oc apply -f sysctl-example-safe-unsafe.yaml
予想される出力
Warning: would violate PodSecurity "restricted:latest": forbidden sysctls (net.core.somaxconn, kernel.msgmax) pod/sysctl-example-safe-unsafe created
次のコマンドを実行して、Pod が作成されていることを確認します。
$ oc get pod
出力例
NAME READY STATUS RESTARTS AGE sysctl-example-safe-unsafe 1/1 Running 0 19s
次のコマンドを実行して、Pod にログインします。
$ oc rsh sysctl-example-safe-unsafe
設定された sysctl フラグの値を確認します。たとえば、以下のコマンドを実行して
net.core.somaxconn
の値を見つけます。sh-4.4# sysctl net.core.somaxconn
予想される出力
net.core.somaxconn = 1024
安全でない sysctl が許可され、値は更新された Pod 仕様の securityContext
仕様で定義されているように設定されるようになりました。