5.9. コンテナーでの sysctl の使用
sysctl 設定は Kubernetes 経由で公開され、ユーザーがコンテナー内の namespace の特定のカーネルパラメーターをランタイム時に変更できるようにします。namespace を使用する sysctl のみを Pod 上で独立して設定できます。sysctl に namespace が使用されていない場合 (この状態は ノードレベル と呼ばれる)、OpenShift Container Platform 内でこれを設定することはできません。さらに 安全 とみなされる sysctl のみがデフォルトでホワイトリスト化されます。 他の 安全でない sysctl はノードで手動で有効にし、ユーザーが使用できるようにできます。
5.9.1. sysctl について
Linux では、管理者は sysctl インターフェースを使ってランタイム時にカーネルパラメーターを変更することができます。パラメーターは /proc/sys/ 仮想プロセスファイルシステムで利用できます。これらのパラメーターは以下を含む各種のサブシステムを対象とします。
- カーネル (共通のプレフィックス: kernel.)
- ネットワーク (共通のプレフィックス: net.)
- 仮想メモリー (共通のプレフィックス: vm.)
- MDADM (共通のプレフィックス: dev.)
追加のサブシステムについては、カーネルのドキュメント で説明されています。すべてのパラメーターの一覧を表示するには、以下のコマンドを実行します。
$ sudo sysctl -a
5.9.1.1. namespace を使用した sysctl vs ノードレベルの 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 ファイルを変更) するか、または特権付きコンテナーで DaemonSet を使用することによって手動で設定する必要があります。
特殊な sysctl が設定されたノードにテイントのマークを付けることを検討してください。それらの sysctl 設定を必要とするノードにのみ Pod をスケジュールします。テイントおよび容認 (Toleration) 機能を使用してノードにマークを付けます。
5.9.1.2. 安全 vs 安全でない sysctl
sysctl は 安全な および 安全でない sysctl に分類されます。
sysctl が安全であるとみなされるには、適切な namespace を使用し、同じノード上の Pod 間で適切に分離する必要があります。Pod ごとに sysctl を設定する場合は、以下の点に留意してください。
- この設定はノードのその他の Pod に影響を与えないものである。
- この設定はノードの正常性に負の影響を与えないものである。
- この設定は Pod のリソース制限を超える CPU またはメモリーリソースの取得を許可しないものである。
OpenShift Container Platform は以下の sysctl を安全なセットでサポートするか、またはホワイトリスト化します。
- kernel.shm_rmid_forced
- net.ipv4.ip_local_port_range
- net.ipv4.tcp_syncookies
すべての安全な sysctl はデフォルトで有効にされます。Pod 仕様を変更して、Pod で sysctl を使用できます。
OpenShift Container Platform でホワイトリスト化されない sysctl は OpenShift Container Platform で安全でないと見なされます。namespace を使用するだけで、sysctl が安全であるとみなされる訳ではありません。
すべての安全でない sysctl はデフォルトで無効にされ、ノードごとにクラスター管理者によって手動で有効にされる必要があります。無効にされた安全でない sysctl が設定された Pod はスケジュールされますが、起動されません。
$ oc get pod NAME READY STATUS RESTARTS AGE hello-pod 0/1 SysctlForbidden 0 14s
5.9.2. Pod の sysctl 設定
Pod の securityContext
を使用して sysctl を Pod に設定できます。securityContext
は同じ Pod 内のすべてのコンテナーに適用されます。
安全な sysctl はデフォルトで許可されます。安全でない sysctl が設定された Pod は、クラスター管理者がそのノードの安全でない sysctl を明示的に有効にしない限り、いずれのノードでも起動に失敗します。ノードレベルの sysctl の場合のように、それらの Pod を正しいノードにスケジュールするには、テイントおよび容認 (Toleration)、またはノードのラベルを使用します。
以下の例では、Pod の securityContext
を使用して安全な sysctl kernel.shm_rmid_forced
および 2 つの安全でない sysctl net.ipv4.route.min_pmtu
および kernel.msgmax
を設定します。仕様では 安全な sysctl と 安全でない sysctl は区別されません。
オペレーティングシステムが不安定になるのを防ぐには、変更の影響を確認している場合にのみ sysctl パラメーターを変更します。
手順
安全なおよび安全でない sysctl を使用するには、以下を実行します。
以下の例に示されるように、Pod を定義する YAML ファイルを変更し、
securityContext
仕様を追加します。apiVersion: v1 kind: Pod metadata: name: sysctl-example spec: securityContext: sysctls: - name: kernel.shm_rmid_forced value: "0" - name: net.ipv4.route.min_pmtu value: "552" - name: kernel.msgmax value: "65536" ...
Pod を作成します。
$ oc apply -f <file-name>.yaml
安全でない sysctl がノードに許可されていない場合、Pod はスケジュールされますが、デプロイはされません。
$ oc get pod NAME READY STATUS RESTARTS AGE hello-pod 0/1 SysctlForbidden 0 14s
5.9.3. 安全でない sysctl の有効化
クラスター管理者は、高パフォーマンスまたはリアルタイムのアプリケーション調整などの非常に特殊な状況で特定の安全でない sysctl を許可することができます。
安全でない sysctl を使用する必要がある場合、クラスター管理者は特定のタイプのノードに対してそれらを個別に有効にする必要があります。sysctl には namespace を使用する必要があります。
安全でないという性質上、安全でない sysctl は各自の責任で使用されます。 場合によっては、コンテナーの正しくない動作やリソース不足、またはノードの破損などの深刻な問題が生じる可能性があります。
手順
ラベルを安全でない sysctl が設定されたコンテナーが実行される MachineConfigPool に追加します。
$ oc edit machineconfigpool worker
apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfigPool metadata: creationTimestamp: 2019-02-08T14:52:39Z generation: 1 labels: custom-kubelet: sysctl 1
- 1
key: pair
ラベルを追加します。
KubeletConfig カスタムリソース (CR) を作成します。
apiVersion: machineconfiguration.openshift.io/v1 kind: KubeletConfig metadata: name: custom-kubelet spec: machineConfigPoolSelector: matchLabels: custom-kubelet: sysctl 1 kubeletConfig: allowedUnsafeSysctls: 2 - "kernel.msg*" - "net.ipv4.route.min_pmtu"
オブジェクトを作成します。
$ oc apply -f set-sysctl-worker.yaml
99-worker-XXXXXXXXX-xxxxx-XXXX-xxxxx-kubelet
形式の新規の MachineConfig が作成されます。machineconfigpool
オブジェクトのstatus
フィールドを使用してクラスターが再起動するのを待機します。以下は例になります。
status: conditions: - lastTransitionTime: '2019-08-11T15:32:00Z' message: >- All nodes are updating to rendered-worker-ccbfb5d2838d65013ab36300b7b3dc13 reason: '' status: 'True' type: Updating
クラスターの準備ができると、以下のようなメッセージが表示されます。
- lastTransitionTime: '2019-08-11T16:00:00Z' message: >- All nodes are updated with rendered-worker-ccbfb5d2838d65013ab36300b7b3dc13 reason: '' status: 'True' type: Updated
クラスターが準備状態になる場合、新規 MachineConfig でマージされた
KubeletConfig
を確認します。$ oc get machineconfig 99-worker-XXXXXX-XXXXX-XXXX-XXXXX-kubelet -o json | grep ownerReference -A7
"ownerReferences": [ { "apiVersion": "machineconfiguration.openshift.io/v1", "blockOwnerDeletion": true, "controller": true, "kind": "KubeletConfig", "name": "custom-kubelet", "uid": "3f64a766-bae8-11e9-abe8-0a1a2a4813f2"
安全でない sysctl を必要に応じて Pod に追加することができるようになります。