Red Hat Training

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

第4章 設定

本章では、OpenStack Puppet モジュールに設定を追加する方法を考察します。これには、Puppet モジュール開発の基本指針も含まれます。

4.1. Puppet の基礎知識

次のセクションでは、Puppet の構文および Puppet のモジュールの構造を理解するのに役立つ基本事項を説明します。

4.1.1. Puppet モジュールの内容の検証

OpenStack モジュールに貢献する前に、Puppet モジュールを作成するコンポーネントについて理解する必要があります。

マニフェスト

マニフェストとは、リソースセットおよび属性を定義するコードが含まれるファイルのことです。リソースは、システムの設定可能なコンポーネントです。リソースの例には、パッケージ、サービス、ファイル、ユーザー、グループ、SELinux 設定、SSH キー認証、 cron ジョブなどが挙げられます。マニフェストは、属性の key-value ペアのセットを使用して必要な各リソースを定義します。以下に例を示します。

  package { 'httpd':
    ensure => installed,
  }

この宣言では、httpd パッケージがインストールされているかどうかを確認します。されていない場合は、マニフェストにより yum が実行されて、httpd パッケージがインストールされます。マニフェストは、モジュールの manifest ディレクトリーに置かれています。また Puppet モジュールは、テストマニフェストのテストディレクトリーを使用します。これらのマニフェストを使用して、正式なマニフェストが含まれている特定のクラスをテストします。

クラス
クラスは、マニフェスト内の複数のリソースを統一するメソッドとして機能します。たとえば、HTTP サーバーをインストールして設定する場合には、HTTP サーバーパッケージをインストールするリソース、HTTP サーバーを設定するリソース、サーバーを起動または有効化するリソースの 3 つのリソースでクラスを作成します。また、他のモジュールからのクラスを参照して設定に適用することもできます。たとえば、Web サーバーも必要なアプリケーションを設定する必要がある場合に、上述した HTTP サーバーのクラスを参照することができます。
静的ファイル

モジュールには、システムの特定の場所に、Puppet がコピーできる静的ファイルが含まれます。これらの場所や、パーミッションなどのその他の属性は、マニフェストのファイルのリソース宣言で定義されます。

静的ファイルは、モジュールの files ディレクトリーに配置されています。

テンプレート

設定ファイルにはカスタムのコンテンツが必要な場合があります。このような場合にユーザーは静的ファイルの代わりにテンプレートを使用します。静的ファイルと同じように、テンプレートはマニフェストで定義され、システム上の場所にコピーされます。相違点は、テンプレートでは Ruby 表現でカスタマイズのコンテンツや変数入力を定義することができる点です。たとえば、カスタマイズ可能なポートで httpd を設定する場合には、設定ファイルのテンプレートには以下が含まれます。

Listen <%= @httpd_port %>

この場合には、httpd_port 編集はこのテンプレートを参照するマニフェストに定義されています。

テンプレートは、モジュールの templates ディレクトリーに配置されています。

プラグイン

プラグインにより、Puppet のコア機能を拡張することができます。たとえば、プラグインを使用してカスタムファクト、カスタムリソース、または新機能を定義することができます。また、データベースの管理者が、PostgreSQL データベース向けのリソース種別を必要とする場合があります。プラグインを使用すると、データベース管理者は PostgreSQL のインストール後に新規データベースセットで PostgreSQL にデータを投入しやすくなり、PostgreSQL のインストールとその後のデータベース作成を確実に行う Puppet マニフェストのみを作成するだけで良くなります。

プラグインは、モジュールの lib ディレクトリーに配置されています。このディレクトリーには、プラグインのタイプに応じたサブディレクトリーセットが含まれます。以下に例を示します。

  • /lib/facter: カスタムファクトの場所
  • /lib/puppet/type: 属性の key-value ペアを記述するカスタムリソース種別の定義の場所
  • /lib/puppet/provider: リソースを制御するためのリソース種別の定義と併せて使用するカスタムリソースプロバイダーの場所
  • /lib/puppet/parser/functions: カスタム関数の場所

4.1.2. サービスのインストール

一部のソフトウェアには、パッケージのインストールが必要です。これは、Puppet モジュールが実行可能な機能で、特定のパッケージの設定を定義するリソース定義を必要とします。

たとえば、mymodule モジュールを使用して httpd パッケージをインストールするには、mymodule モジュールの Puppet マニフェストに以下のコンテンツを追加します。

class mymodule::httpd {
  package { 'httpd':
    ensure => installed,
  }
}

このコードは、httpd パッケージのリソース宣言を定義する httpd と呼ばれる mymodule サブクラスを定義します。ensure => installed の属性は、パッケージがインストールされているかどうかを確認するように Puppet に指示を出します。インストールされていない場合には、Puppet は yum を実行してパッケージをインストールします。

4.1.3. サービスの起動と有効化

パッケージのインストール後には、サービスを起動します。service と呼ばれる別のリソース宣言を使用します。これには、以下の内容が含まれるようにマニフェストを編集する必要があります。

class mymodule::httpd {
  package { 'httpd':
    ensure => installed,
  }
  service { 'httpd':
    ensure => running,
    enable => true,
    require => Package["httpd"],
  }
}

これにより、以下の操作が実行されます。

  • ensure => running 属性は、サービスが実行さているかどうかを確認します。実行されていない場合は Puppet により有効化されます。
  • enable => true 属性は、システムの起動時にサービスが実行されるように設定します。
  • require => Package["httpd"] 属性は、リソース宣言同士の順序関係を定義します。今回の場合は、httpd サービスが httpd パッケージのインストールの後に起動されるようにします。この属性により、サービスと関連のパッケージの間で依存関係が生まれます。

4.1.4. サービスの設定

上記の 2 つの手順では、Puppet を使用したサービスのインストールおよび有効化の方法を説明しましたが、サービスにカスタム設定を指定することもできます。本ガイドの例では、ポート 80 に Web ホストを設定するように、すでに /etc/httpd/conf/httpd.conf に HTTP サーバーのデフォルト設定が指定されています。このセクションでは、設定を追加して、ユーザー指定のポートに追加の Web ホストを設定します。

そのためには、HTTP 設定ファイルを保存するテンプレートファイルを使用します。これは、ユーザー定義のポートには、変数入力が必要なためです。モジュールの templates ディレクトリーに、以下の内容が含まれた myserver.conf.erb と呼ばれるファイルを追加します。

Listen <%= @httpd_port %>
NameVirtualHost *:<%= @httpd_port %>
<VirtualHost *:<%= @httpd_port %>>
  DocumentRoot /var/www/myserver/
  ServerName *:<%= @fqdn %>>
  <Directory "/var/www/myserver/">
    Options All Indexes FollowSymLinks
    Order allow,deny
    Allow from all
  </Directory>
</VirtualHost>

このテンプレートは、Apache Web 設定の標準構文に準拠します。唯一の相違点は、モジュールから変数を注入する際に Ruby のエスケープ文字が含まれる点です。たとえば、Web サーバーポートを指定するのに使用する httpd_port などです。

fqdn が追加されている点に注意してください。これは、システムの完全修飾ドメイン名を保存する変数で、システムファクト として知られています。システムファクトは、各該当システムの Puppet カタログを生成する前に各システムから取得します。Puppet は facter コマンドを使用して、これらのシステムファクトを収集します。また、これらのファクトの一覧を表示するには、facter を実行します。

このファイルを保存した後には、モジュールの Puppet マニフェストにリソースを追加します。

class mymodule::httpd {
  package { 'httpd':
    ensure => installed,
  }
  service { 'httpd':
    ensure => running,
    enable => true,
    require => Package["httpd"],
  }
  file {'/etc/httpd/conf.d/myserver.conf':
  notify => Service["httpd"],
    ensure => file,
    require => Package["httpd"],
    content => template("mymodule/myserver.conf.erb"),
  }
  file { "/var/www/myserver":
    ensure => "directory",
  }
}

これにより、以下の操作が実行されます。

  • サーバー設定ファイル (/etc/httpd/conf.d/myserver.conf) のファイルリソース宣言を追加します。このファイルのコンテンツは、以前に作成した myserver.conf.erb テンプレートです。このファイルを追加する前に、httpd パッケージがインストールされていることも確認します。
  • 2 番目のファイルリソース宣言を追加します。これにより、Web サーバーのディレクトリー (/var/www/myserver) が作成されます。
  • notify => Service["httpd"] 属性を使用して、設定ファイルと httpd サービスの間の関係も追加します。これにより、設定ファイルへの変更の有無がチェックされます。ファイルが変更された場合には、Puppet によりサービスが再起動されます。

4.2. OpenStack Puppet モジュールの取得

Red Hat OpenStack Platform は、Githubopenstack グループから取得する正式な OpenStack Puppet モジュールを使用します。https://github.com/openstack に移動して、フィルターセクションで puppet を検索します。すべての Puppet モジュールには、puppet- の接頭辞が使用されます。

この例では、以下のコマンドを使用してクローン作成し、正式な OpenStack Block Storage (cinder) を検証します。

$ git clone https://github.com/openstack/puppet-cinder.git

これにより、Cinder の Puppet モジュールのクローンを作成します。

4.3. Puppet モジュールの設定追加

OpenStack モジュールでは、主にコアサービスを設定します。モジュールの多くには、backendsagents または plugins として知られる追加のサービスを設定するための追加のマニフェストが含まれます。たとえば、cinder モジュールには backends と呼ばれるディレクトリーがあり、この中には NFS、iSCSI、Red Hat Ceph Storage など異なるストレージの設定オプションが含まれます。

たとえば、manifests/backends/nfs.pp ファイルには以下の設定が含まれます。

define cinder::backend::nfs (
  $volume_backend_name  = $name,
  $nfs_servers          = [],
  $nfs_mount_options    = undef,
  $nfs_disk_util        = undef,
  $nfs_sparsed_volumes  = undef,
  $nfs_mount_point_base = undef,
  $nfs_shares_config    = '/etc/cinder/shares.conf',
  $nfs_used_ratio       = '0.95',
  $nfs_oversub_ratio    = '1.0',
  $extra_options        = {},
) {

  file {$nfs_shares_config:
    content => join($nfs_servers, "\n"),
    require => Package['cinder'],
    notify  => Service['cinder-volume']
  }

  cinder_config {
    "${name}/volume_backend_name":  value => $volume_backend_name;
    "${name}/volume_driver":        value =>
      'cinder.volume.drivers.nfs.NfsDriver';
    "${name}/nfs_shares_config":    value => $nfs_shares_config;
    "${name}/nfs_mount_options":    value => $nfs_mount_options;
    "${name}/nfs_disk_util":        value => $nfs_disk_util;
    "${name}/nfs_sparsed_volumes":  value => $nfs_sparsed_volumes;
    "${name}/nfs_mount_point_base": value => $nfs_mount_point_base;
    "${name}/nfs_used_ratio":       value => $nfs_used_ratio;
    "${name}/nfs_oversub_ratio":    value => $nfs_oversub_ratio;
  }

  create_resources('cinder_config', $extra_options)

}

これにより、以下の操作が実行されます。

  • define ステートメントでは、cinder::backend::nfs と呼ばれる定義型が作成されます。定義型はクラスによく似ていますが、主な相違点は Puppet は定義型を複数回評価する点です。たとえば、複数の NFS バックエンドが必要なため、この設定では NFS 共有ごとに評価を複数回実行する必要があります。
  • 次の数行では、設定内のパラメーターとそのデフォルト値を定義します。cinder::backend::nfs の定義型に新しい値が渡された場合には、デフォルト値は上書きされます。
  • file 関数は、ファイルの作成を呼び出すリソース宣言です。このファイルには、NFS 共有の一覧が含まれており、このファイルの名前はパラメーターで定義されます ($nfs_shares_config = '/etc/cinder/shares.conf')。以下は追加の属性です。
  • content 属性は、$nfs_servers パラメーターを使用して一覧を作成します。
  • require 属性は、cinder パッケージが確実にインストールされるようにします。
  • notify 属性は cinder-volume サービスにリセットするように指示を出します。
  • cinder_config 関数は、モジュールの lib/puppet/ ディレクトリーからプラグインを使用するリソース宣言です。このプラグインは /etc/cinder/cinder.conf ファイルに設定を追加します。このリソースのそれぞれの行により、cinder.conf ファイルの適切なセクションに設定オプションが追加されます。たとえば、$name パラメーターが mynfs の場合には、属性は以下のようになります。

      "${name}/volume_backend_name":  value => $volume_backend_name;
      "${name}/volume_driver":        value =>
        'cinder.volume.drivers.nfs.NfsDriver';
      "${name}/nfs_shares_config":    value => $nfs_shares_config;

    上記の属性により、cinder.conf のファイルに以下が追加されます。

    [mynfs]
    volume_backend_name=mynfs
    volume_driver=cinder.volume.drivers.nfs.NfsDriver
    nfs_shares_config=/etc/cinder/shares.conf
  • create_resources 関数は、ハッシュをリソースセットに変換します。この場合は、マニフェストにより $extra_options ハッシュがバックエンドの追加設定オプションに変換されます。これは、マニフェストのコアパラメーターに含まれていない設定オプションを追加する柔軟な方法を提供します。

これにより、ハードウェアの OpenStack ドライバーを設定するマニフェストを追加することの重要性が分かります。マニフェストは、director がハードウェアに適した設定オプションを追加する簡単な方法を提供します。マニフェストは、director がハードウェアをオーバークラウドで使用できるように設定する際の統合ポイントの役割を果たします。

4.4. Puppet 設定への階層データの追加

Puppet には、Hiera と呼ばれるツールが含まれています。このツールはノード固有の設定を提供する key/value システムとして機能します。これらのキーと値は通常 /etc/puppet/hieradata に配置されています。/etc/puppet/hiera.yaml ファイルは、Puppet が hieradata ディレクトリーのファイルを読み込む順序を定義します。

オーバークラウドを設定する際には、Puppet はこのデータを使用して特定の Puppet クラスのデフォルト値を上書きします。たとえば、puppet-cinder にある cinder::backend::nfs の NFS のマウントオプションはデフォルトでは未定義になっています。

  $nfs_mount_options    = undef,

ただし、cinder::backend::nfs の定義する型を呼び出す独自のマニフェストを作成して、このオプションを Hiera データに置き換えることができます。

  cinder::backend::nfs { $cinder_nfs_backend:
    nfs_mount_options   => hiera('cinder_nfs_mount_options'),
  }

これは、nfs_mount_options パラメーターが cinder_nfs_mount_options キーから取得した Hiera データの値を使用することを意味します。

cinder_nfs_mount_options: rsize=8192,wsize=8192

または、NFS 設定の全評価に適用されるように Hiera データを使用して cinder::backend::nfs::nfs_mount_options パラメーターを直接上書きすることができます。以下に例を示します。

cinder::backend::nfs::nfs_mount_options: rsize=8192,wsize=8192

上記の Heira データは cinder::backend::nfs の各評価上にあるこのパラメーターを上書きします。