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 を許可された安全なリストに追加します。

表7.4 システム全体の安全な sysctl

sysctl説明

kernel.shm_rmid_forced

1 に設定すると、現在の IPC namespace のすべての共有メモリーオブジェクトは自動的に IPC_RMID を使用します。詳しくは、shm_rmid_forced を参照してください。

net.ipv4.ip_local_port_range

TCP および UDP によって使用されるローカルポート範囲を定義して、ローカルポートを選択します。最初の番号は最初のポート番号で、2 番目の番号は最後のローカルポート番号になります。可能であれば、これらの数値は異なるパリティー (偶数値と奇数値) を持つ方が良い。ip_unprivileged_port_start よりも大きくなければなりません。デフォルト値は、それぞれ 32768 および 60999 です。詳細は、ip_local_port_range を参照してください。

net.ipv4.tcp_syncookies

net.ipv4.tcp_syncookies を設定すると、カーネルは、通常、半分に開いた接続キューが満杯になるまで TCP SYN パケットを処理します。この時点で、SYN クッキー機能が開始します。この機能により、サービス拒否攻撃下であっても、システムは有効な接続を受け入れることができます。詳細は、tcp_syncookies を参照してください。

net.ipv4.ping_group_range

これにより、ICMP_PROTO データグラムソケットがグループ範囲内のユーザーに制限されます。デフォルトは 1 0 で、nobody は root であっても ping ソケットを作成できます。詳細は、ping_group_range を参照してください。

net.ipv4.ip_unprivileged_port_start

これは、ネットワーク namespace 内の最初の権限のないポートを定義します。特権ポートをすべて無効にするには、これを 0 に設定します。特権ポートは ip_local_port_range と重複できません。詳細は、ip_unprivileged_port_start を参照してください。

表7.5 インターフェイス固有の安全な sysctl

sysctl説明

net.ipv4.conf.IFNAME.accept_redirects

IPv4 ICMP リダイレクトメッセージを受信します。

net.ipv4.conf.IFNAME.accept_source_route

SRR (Strict Source Route) オプションの付いた IPv4 パケットを受け入れる。

net.ipv4.conf.IFNAME.arp_accept

ARP テーブルにない IPv4 アドレスで余計な ARP フレームの動作を定義します。

  • 0: ARP テーブルに新しいエントリーを作成しません。
  • 1: ARP テーブルに新しいエントリーを作成します。

net.ipv4.conf.IFNAME.arp_notify

IPv4 アドレスとデバイスの変更を通知するモードを定義します。

net.ipv4.conf.IFNAME.disable_policy

この IPv4 インターフェイスの IPSEC ポリシー (SPD) を無効にします。

net.ipv4.conf.IFNAME.secure_redirects

インターフェイスの現在のゲートウェイリストにリストされているゲートウェイに対する ICMP リダイレクトメッセージのみを受信します。

net.ipv4.conf.IFNAME.send_redirects

送信リダイレクトは、ノードがルーターとして動作する場合にのみ有効になります。つまり、ホストは ICMP リダイレクトメッセージを送信しないでください。これは、特定の宛先で利用可能なルーティングパスの改善についてホストに通知するためにルーターによって使用されます。

net.ipv6.conf.IFNAME.accept_ra

IPv6 ルーター広告を受け入れ、それらを使用して自動設定します。また、ルーター要請の送信の可否を判断します。ルーターへの通知は、機能の設定がルーター広告を受け入れる場合にのみ送信されます。

net.ipv6.conf.IFNAME.accept_redirects

IPv6 ICMP リダイレクトメッセージを受信します。

net.ipv6.conf.IFNAME.accept_source_route

SRR オプションで IPv6 パケットを受信します。

net.ipv6.conf.IFNAME.arp_accept

ARP テーブルに存在しない IPv6 アドレスで余計な ARP フレームの動作を定義します。

  • 0: ARP テーブルに新しいエントリーを作成しません。
  • 1: ARP テーブルに新しいエントリーを作成します。

net.ipv6.conf.IFNAME.arp_notify

IPv6 アドレスとデバイスの変更を通知するモードを定義します。

net.ipv6.neigh.IFNAME.base_reachable_time_ms

このパラメーターは、IPv6 の neighbour テーブルで、IP マッピングの有効期間に対するハードウェアアドレスを制御します。

net.ipv6.neigh.IFNAME.retrans_time_ms

隣接する検出メッセージの再送信タイマーを設定します。

注記

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 仕様を追加します。

手順

  1. 以下の例のように、サンプル 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 プロファイルを有効にします。
  2. 以下のコマンドを実行して Pod を作成します。

    $ oc apply -f sysctl_pod.yaml
  3. 次のコマンドを実行して、Pod が作成されていることを確認します。

    $ oc get pod

    出力例

    NAME              READY   STATUS            RESTARTS   AGE
    sysctl-example    1/1     Running           0          14s

  4. 次のコマンドを実行して、Pod にログインします。

    $ oc rsh sysctl-example
  5. 設定された 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 仕様に追加する際に発生する内容を示しています。

手順

  1. 以下の例のように、サンプル 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"
  2. 以下のコマンドを使用して Pod を作成します。

    $ oc apply -f sysctl-example-unsafe.yaml
  3. 以下のコマンドを使用して安全でない 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 は各自の責任で使用されます。 場合によっては、コンテナーの正しくない動作やリソース不足、またはノードの破損などの深刻な問題が生じる可能性があります。

手順

  1. 以下のコマンドを実行して、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

  2. 以下のコマンドを実行して、安全でない sysctl が設定されたコンテナーが実行されるマシン設定プールにラベルを追加します。

    $ oc label machineconfigpool worker custom-kubelet=sysctl
  3. 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"
    1
    マシン設定プールからラベルを指定します。
    2
    許可する必要のある安全でない sysctl を一覧表示します。
  4. 以下のコマンドを実行してオブジェクトを作成します。

    $ oc apply -f set-sysctl-worker.yaml
  5. 以下のコマンドを実行して、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
  6. 次の例に示すように、サンプルの 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"
  7. 以下のコマンドを実行して 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

  8. 次のコマンドを実行して、Pod が作成されていることを確認します。

    $ oc get pod

    出力例

    NAME                         READY   STATUS    RESTARTS   AGE
    sysctl-example-safe-unsafe   1/1     Running   0          19s

  9. 次のコマンドを実行して、Pod にログインします。

    $ oc rsh sysctl-example-safe-unsafe
  10. 設定された sysctl フラグの値を確認します。たとえば、以下のコマンドを実行して net.core.somaxconn の値を見つけます。

    sh-4.4# sysctl net.core.somaxconn

    予想される出力

    net.core.somaxconn = 1024

安全でない sysctl が許可され、値は更新された Pod 仕様の securityContext 仕様で定義されているように設定されるようになりました。

7.9.7. 関連情報