Red Hat Training

A Red Hat training course is available for Red Hat OpenStack Platform

第4章 ハイパーコンバージドノード上におけるリソース分離の設定

デフォルトの hyperconverged-ceph.yaml ファイル (「単一型 HCI」) またはカスタムの OsdCompute ロール (「混合型 HCI」) のいずれを使用する場合も、director は Ceph OSD サービスと Compute サービスを同じ場所に配置してハイパーコンバージドノードを作成します。ただし、この配置をさらに調整しなければ、Ceph サービスと Compute サービスは、同じホスト上でお互いの存在を認識しないため、それらのサービス間で リソースの競合 が発生するリスクがあります。リソースの競合が発生すると、サービスのパフォーマンスが低下する可能性があり、その場合には、ハイパーコンバージェンスによって提供されるメリットが相殺されてしまいます。

競合が発生しないようにするには、Ceph サービスと Compute サービスの両方にリソースの分離を設定する必要があります。以下のサブセクションでは、その方法について説明します。

4.1. Compute 用の CPU とメモリーリソースの確保

デフォルトでは、Compute サービスのパラメーターは Ceph OSD サービスが同じノード上に配置されていることは考慮に入れません。この問題に対処して、安定を維持し、ホスト可能なインスタンス数を最大化するには、ハイパーコンバージドノードを調整する必要があります。本項の計算はを最適なベースラインの指針として使用してから、設定を変更し、決定論とインスタンスのホスティングキャパシティーの間の許容可能なトレードオフを特定してください。本書に記載する例では、決定論とアップタイムが優先されます。

以下の Heat テンプレートパラメーターは、Compute サービスがメモリーと CPU リソースをノードで消費する方法を制御します。

reserved_host_memory

これは、ホストノードに確保するメモリー容量 (MB 単位) です。ハイパーコンバージドノードに適切な値を決定するには、 各 OSD が 3 GB のメモリーを消費すると仮定します。メモリーが 256 GB で OSD が 10 の場合には、Ceph に 30 GB のメモリーを割り当てて、Compute に 226 GB 残します。このメモリー容量があるノードでは、たとえば、2 GB のメモリーを使用するインスタンスを 113 ホストすることができます。

ただし、ハイパーバイザーには、1 インスタンスあたりの追加のオーバーヘッドを考慮する必要があります。このオーバーヘッドが 0.5 GB と仮定すると、同じノードでは、90 インスタンスしかホストできません。この値は、226 GB を 2.5 GB で除算して割り出します。ホストノードに確保するメモリー容量 (Compute サービスが使用してはならないメモリー) は以下のように算出します。

(In * Ov) + (Os * RA)

ここで、

  • In はインスタンス数に置き換えます。
  • Ov は 1 インスタンスあたりに必要なオーバヘッドメモリーの容量に置き換えます。
  • Os はノード上の OSD 数に置き換えます。
  • RA は、各 OSD に割り当てる必要のある RAM 容量に置き換えます。

90 インスタンスの場合には、(90*0.5) + (10*3) = 75GB という計算になります。Compute サービスには、この値を MB 単位で指定します (75000)。

以下の Python コードは、この計算を実装します。

left_over_mem = mem - (GB_per_OSD * osds)
number_of_guests = int(left_over_mem /
    (average_guest_size + GB_overhead_per_guest))
nova_reserved_mem_MB = MB_per_GB * (
    (GB_per_OSD * osds) +
    (number_of_guests * GB_overhead_per_guest))
cpu_allocation_ratio

Compute スケジューラーは、インスタンスをデプロイする Compute ノードを選択する際にこの値を使用します。デフォルトでは、この値は 16.0 (16:1) です。1 台のノードに 56 コアある場合には、Compute スケジューラーは 1 台のノードで 896 の仮想 CPU を使用するのに十分なインスタンスをスケジュールすることになります。この値を超えると、そのノードはそれ以上インスタンスをホストできないと見なされます。

ハイパーコンバージドノードに適切な cpu_allocation_ratio を決定するには、各 Ceph OSD が最小で 1 コアを使用すると仮定します (ワークロードが I/O 集中型で、SSD を使用しないノード上にある場合を除く)。56 コア、10 OSD のノードでは、この計算で 46 コアが Compute に確保されます。各インスタンスが割り当てられた CPU の 100 パーセント使用すると、この比率は単にインスタンスの仮想 CPU 数をコア数で除算した値となります (46 / 56 = 0.8)。ただし、インスタンスは通常割り当てられた CPU を 100 パーセント使用することはないため、ゲストに必要な仮想 CPU 数を決定する際には、予想される使用率を考慮に入れて、cpu_allocation_ratio を高くすることができます。

したがって、インスタンスが仮想 CPU の 10 パーセント (または 0.1) のみを使用すると予想できる場合には、インスタンス用の仮想 CPU は 46 / 0.1 = 460 の式で示すことができます。この値をコア数 (56) で除算すると、比率は約 8 に増えます。

以下の Python コードは、この計算を実装します。

cores_per_OSD = 1.0
average_guest_util = 0.1 # 10%
nonceph_cores = cores - (cores_per_OSD * osds)
guest_vCPUs = nonceph_cores / average_guest_util
cpu_allocation_ratio = guest_vCPUs / cores
ヒント

「Compute の CPU およびメモリーの計算」のスクリプトを使用して、reserved_host_memory および cpu_allocation_ratio の両方のベースライン値を計算することもできます。

使用する値を計算した後には、HCI ノードのデフォルト値として追加します。そのためには、~/templates に compute.yaml という名前の新しい環境ファイルを作成して、reserved_host_memory と cpu_allocation_ratio の値を記述します。単一型の HCI デプロイメントの場合には、以下のように記載する必要があります。

parameter_defaults:
  NovaComputeExtraConfig:  # 1
    nova::compute::reserved_host_memory: 181000
    nova::cpu_allocation_ratio: 8.2
1
NovaComputeExtraConfig の行は、ネストされている全パラメーターをすべての Compute ロールに適用します。単一型 HCI デプロイメントの場合には、全コンピュートノードにハイパーコンバージドの設定も適用します。

混合型の HCI の場合には、~/templates/compute.yaml に以下の内容を記載する必要があります。

parameter_defaults:
  OsdComputeExtraConfig:  # 1
    nova::compute::reserved_host_memory: 181000
    nova::cpu_allocation_ratio: 8.2
1
OsdComputeExtraConfig の行は、ネストされている全設定をカスタムの OsdCompute ロールに適用するカスタムリソースです。これは、「混合型 HCI」で定義しています。

4.2. Ceph NUMA ピニングの設定

NUMA 機能を実装したホストにハイパーコンバージドロールを適用する際には、利用可能な NUMA ソケットの 1 つに Ceph OSD サービスをピニングすることにより、決定論を改善することができます。 この設定を行う場合は、ネットワーク IRQ とストレージコントローラーを備えたソケットに Ceph Storage サービスをピニングしてください。これは、Ceph OSD がネットワーク I/O を大量に使用する問題の対処に役立ちます。

これは、ネットワークインターフェースを引数として取り、必要な NUMA 関連の設定をそのインターフェースに適用するシェルスクリプトでオーケストレーションすることができます。このネットワークインターフェースは、Ceph OSD が使用するインターフェースと推定できます。このスクリプト (numa-systemd-osd.sh) を ~/templates に作成してください。

重要

numa-systemd-osd.sh の内容については、より詳細な記述を記載している「Ceph OSD サービス向けの NUMA ピニングを設定するカスタムスクリプト」を参照してください。

numa-systemd-osd.sh のスクリプトは、NUMA 設定ツールのインストールも試みます。そのため、「ノードの登録」 (『オーバークラウド向けの Red Hat Ceph Storage』) の説明に従って、オーバークラウドノードを Red Hat に登録しておく必要もあります。

オーバークラウドでこのスクリプトを実行するには、まず最初に ~/templates に以下の内容を記述した ceph-numa-pinning-template.yaml という名前の Heat テンプレートを作成します。

heat_template_version: 2014-10-16

parameters:
  servers:
    type: json

resources:
  ExtraConfig:
    type: OS::Heat::SoftwareConfig
    properties:
      group: script
      inputs:
        - name: OSD_NUMA_INTERFACE
      config: {get_file: numa-systemd-osd.sh} # 1

  ExtraDeployments:
    type: OS::Heat::SoftwareDeployments
    properties:
      servers: {get_param: servers}
      config: {get_resource: ExtraConfig}
      input_values:
        OSD_NUMA_INTERFACE: 'em2' # 2
      actions: ['CREATE'] # 3
1
get_file 関数は、~/templates/numa-systemd-osd.sh を呼び出します。このスクリプトは、ネットワークインターフェースを入力として取って (この場合は OSD_NUMA_INTERFACE)、そのインターフェースに必要な NUMA 関連の設定を実行することができます。このスクリプトの内容と、それがどう機能するかについての詳しい説明は、「Ceph OSD サービス向けの NUMA ピニングを設定するカスタムスクリプト」を参照してください。
重要

単一型の HCI デプロイメントでは、~/templates/numa-systemd-osd.sh スクリプトの最上位の IF ステートメントを編集する必要があります。詳しくは、「Ceph OSD サービス向けの NUMA ピニングを設定するカスタムスクリプト」を参照してください。

2
OSD_NUMA_INTERFACE の変数は、Ceph OSD サービスが使用すべきネットワークインターフェース (この例では em2) を指定します。~/templates/numa-systemd-osd.sh スクリプトは、このインターフェースに必要な NUMA 設定を適用します。
3
actions には CREATE のみを指定するので、スクリプトは初回のデプロイメント時にのみ実行され、更新時には実行されません。

OSD_NUMA_INTERFACE に使用するインターフェースは、StorageNetwork 変数または StorageMgtmtNetwork 変数のいずれかを使用して、全デプロイメントに対して決定することができます。読み取りを大量に行うワークロードには、StorageNetwork インターフェースを使用し、書き込みを大量に行うワークロードには、StorageMgtmtNetwork のインターフェースを使用するとメリットがもたらされます。

Ceph OSD サービスが仮想ネットワークインターフェース (例: ボンディング) を使用する場合には、ボンディング自体ではなく、ボンディングを構成するネットワークデバイスの名前を使用します。たとえば、bond1em2em4 を使用する場合には、OSD_NUMA_INTERFACE を (bond1 ではなく) em2 または em4 に設定します。ボンディングが、同じ NUMA ノードにはない NIC を組み合わせている場合には (lstopo-no-graphics で確認)、numa-systemd-osd.sh を使用しないでください。

ceph-numa-pinning-template.yaml テンプレートを作成した後には、~/templates に以下の内容を記載した ceph-numa-pinning.yaml という名前のテンプレートを作成します。

resource_registry:
  OS::TripleO::NodeExtraConfigPost: /home/stack/templates/ceph-numa-pinning-template.yaml

この環境ファイルにより、後ほど、「6章デプロイメント」で ceph-numa-pinning-template.yaml テンプレートを呼び出すことができます。

4.3. Ceph のバックフィルおよびリカバリーの操作

Ceph OSD が削除されると、Ceph は バックフィルリカバリー の操作を使用して、クラスターをリバランスします。Ceph は、配置グループポリシーに従って複数のコピーを保管するためにこの操作を実行します。これらの操作は、システムリソースを使用するため、Ceph クラスターに負荷がかかっている場合には、リソースがバックフィルとリカバリーに回されるので、パフォーマンスが低下します。

OSD の削除時にこのようなパフォーマンスの影響を軽減するには、バックフィルとリカバリーの操作の優先度を低くすることができます。この方法を使用すると、データのレプリカがより少ない状態が長くなるので、データはより高いリスクにさらされることにます。

バックフィルとリカバリーの操作の優先度を設定するには、以下の内容を記述した ceph-backfill-recovery.yaml という名前の環境ファイルを ~/templates に追加します。

parameter_defaults:
  ExtraConfig:
    ceph::profile::params::osd_recovery_op_priority: 3 # 1
    ceph::profile::params::osd_recovery_max_active: 3 # 2
    ceph::profile::params::osd_max_backfills: 1 # 3
1
osd_recovery_op_priority は、OSD クライアント OP の優先度と相対的に、リカバリー操作の優先度を設定します。
2
osd_recovery_max_active は、1 OSD あたりの 1 回にアクティブなリカバリー要求の件数を設定します。要求がこの値を超えると、リカバリーが加速されますが、それらの要求によりクラスターにかかる負荷が増大します。レイテンシーを低くするには、この値を 1 に設定します。
3
osd_max_backfills は単一の OSD との間で許容されるバックフィルの最大数を設定します。
重要

このサンプルで使用される値は、現在のデフォルト値です。デフォルトとは異なる値を使用する予定でなければ、ceph-backfill-recovery.yaml をデプロイメントに追加する必要はありません。