Filesystem configuration
========================

TPAを使用すると、各インスタンスに添付された\ ``volumes``
のリストを定義できます。

このリストには、プロビジョニング中に使用されるプラットフォーム固有の設定と、展開中に使用されるファイルシステムレベルの設定の両方が含まれています。

まず、 ``tpaexec provision``
は情報を使用してボリュームを作成し、インスタンスにアタッチします（該当する場合。詳細については、以下のプラットフォーム固有のセクションを参照）。次に、ボリュームの単純化されたリスト（非プラットフォーム固有の設定のみを含む）をインスタンスのホスト変数として書き込みます。最後に、
``tpaexec deploy``
は、必要に応じて、単純化されたリストに基づいて動作し、ファイルシステムをセットアップおよびマウントします。

AWSクラスターからの適度に複雑な例を次に示します。

.. code:: yaml

   instances:

   - Name: one
     …
     volumes:
     - device_name: root
       volume_type: gp2
       volume_size: 32
     - raid_device: /dev/md0
       device_name: /dev/xvdf
       volume_type: io2
       volume_size: 64
       raid_units: 2
       raid_level: 1
       iops: 5000
       vars:
         volume_for: postgres_data
         encryption: luks
     - raid_device: /dev/md1
       device_name: /dev/xvdh
       ephemeral: ephemeral0
       raid_units: all
       vars:
         mountpoint: /mnt/scratch

この例では、EC2インスタンスは32GB
EBSルートボリューム、/opt/postgres/dataとしてマウントされた2つのプロビジョンドiops
EBSボリュームで構成される64GB
RAID-1ボリューム、および使用可能なすべてのインスタンスで構成される/tmp/scratchファイルシステムになります。
-ストア（「エフェメラル」）ボリューム、その数とサイズはインスタンスタイプによって決まります。

詳細は以下のAWSのセクションに記載されていますが、 ``volume_type``
および\ ``volume_size`` のような設定はプロビジョニング中に使用され、
``volume_for`` または\ ``mountpoint`` のような\ ``vars``
の下の設定は展開中に使用するためにインベントリに書き込まれます。

default_volumes
---------------

ボリュームはインスタンスのプロパティです。プラットフォーム固有の設定が含まれているため、\ ``cluster_vars``
で設定することはできません。

 :ref:`instance_defaults <instance_defaults>` 

メカニズムは、ボリューム定義を特別に許可します。大規模なクラスターでのボリューム定義は非常に反復的である可能性があるため（特に、クラスター内のインスタンスをできるだけ近くに構成することをお勧めするため、ここに示すように\ ``default_volumes``
を指定できます。

.. code:: yaml

   instance_defaults:
     default_volumes:
     - device_name: root
       volume_type: gp2
       volume_size: 32
     - device_name: /dev/xvdf
       volume_size: 100

   instances:

   - Name: one
     …

   - Name: two
     volumes:
     - device_name: /dev/xvdf
       volume_size: 64
     - device_name: /dev/xvdg
       volume_size: 64
       …

   - Name: three
     volumes:
     - device_name: /dev/xvdf
       volume_type: none

   - Name: four
     volumes: []

ここで、すべてのインスタンスには、デフォルトで32GBのルートボリュームと100GBの追加ボリュームがあります（インスタンス\ ``one``
の場合と同様、別のものを指定しません）。インスタンス\ ``two``
は同じルートボリュームを持ちますが、 ``/dev/xvdf``
をオーバーライドして代わりに64GBになり、さらに別の64GBボリュームがあります。インスタンス\ ``three``
には同じルートボリュームがありますが、デフォルトの\ ``/dev/xvdf``
に\ ``volume_type: none``
を設定するため、追加のボリュームはありません。インスタンス\ ``four``
にはボリュームがまったくありません。

インスタンスは\ ``default_volumes``
で指定されたもので始まり、その\ ``volumes``
エントリは同じ\ ``device_name``
でデフォルトのエントリをオーバーライドしたり、 ``volume_type``
を\ ``none``
に設定してボリュームを削除したり、異なる名前で新しいボリュームを追加したり、デフォルトを完全に拒否したりできます。

（2つのリストをマージするこの動作は、\ ``default_volumes``
に固有です。\ ``instance_defaults`` と\ ``instances``
の両方で他のリストを設定すると、後者は前者を完全にオーバーライドします。）

プラットフォームAWS
-------------------

AWS EC2インスタンスでは、EBSボリュームをアタッチできます。

.. code:: yaml

   instances:

   - Name: one
     …
     volumes:
     - device_name: root
       volume_type: gp2
       volume_size: 32
       encrypted: yes
       …
     - device_name: /dev/xvdf
       volume_type: io1
       volume_size: 32
       iops: 10000
       delete_on_termination: false
       …
     - device_name: /dev/xvdg
       ephemeral: ephemeral0
       …

TPAは、 ``root`` の\ ``device_name``
をインスタンスタイプに基づいて\ ``/dev/sda`` または\ ``/dev/xvda``
に変換するため、どちらを使用するかを覚え（または変更）する必要はありません。

``volume_type`` は、EBSボリュームタイプを指定します。例、 ``gp2``
（「汎用」EBSボリュームの場合）、プロビジョンドIOPSボリュームの\ ``io1``
（この場合、 ``iops: 5000`` も設定する必要があります）など。

``volume_size`` は、ボリュームのサイズをギガバイト単位で指定します。

``encrypted: yes`` を設定して、保存時のEBS暗号化を有効にします。
（これはAWSの機能であり、新しく生成されたTPA構成でデフォルトで有効になっており、以下で説明する
 :ref:`LUKS暗号化 <LUKS暗号化>`  とは異なります。）

``delete_on_termination`` を\ ``false``
に設定して、アタッチされたインスタンスが終了したときにボリュームが破棄されないようにします（これがデフォルトの動作です）。

``ephemeral: ephemeralN``
を設定して、以前はエフェメラルボリュームと呼ばれていた、物理的に接続された
 `instance store volume <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html>`_ 
を使用します。利用可能なインスタンスストアボリュームの数、タイプ、およびサイズは、インスタンスタイプによって異なります。すべてのインスタンスにインスタンスストアボリュームがあるわけではありません。インスタンスストアボリュームはテストまたは一時データにのみ使用し、EBSボリュームは気になるデータに使用します。

EBSボリュームの場合、 ``snapshot: snap-xxxxxxxx``
を設定して、既存のスナップショットからボリュームをアタッチすることもできます。スナップショットから復元されたボリュームは、S3から十分なデータが読み取られてローカルにキャッシュされるまで、非常に遅い場合があります。
（特に、スナップショットから\ ``PGDATA``
を使用して新しいインスタンスをスピンアップできますが、全負荷を処理する準備が整うまでに数時間かかることが予想されます。）

ボリュームの\ ``attach_existing: yes``
を設定し、名前/タイプ/サイズ/iopsが一致する既存の接続されていないEBSボリュームがある場合、インスタンスの起動時に新しいボリュームは作成されませんが、代わりに既存のボリュームがインスタンスに接続されますはじめて始まります。再アタッチされたEBSボリュームは、スナップショットから作成されたボリュームのパフォーマンス制限の影響を受けません。

プラットフォームベア
--------------------

TPAは、事前にプロビジョニングされた\ ``bare``
インスタンスに接続できるボリュームを制御できませんが、適切な\ ``device_name``
で\ ``volumes`` を定義すると、必要に応じてデバイスの\ ``mkfs``
および\ ``mount`` を処理します。

プラットフォームDocker
----------------------

Dockerコンテナにはボリュームをアタッチできますが、それらはバインドマウントされたディレクトリであり、通常のブロックデバイスではありません。個別に初期化またはマウントする必要はありません。このように、構成はかなり異なって見えます。

.. code:: yaml

   instances:

   - Name: one
     platform: docker
     …
     volumes:
     - /host/path/to/dir:/tmp/container/path:ro
     - named_volume:/mnt/somevol:rw

これらのボリューム指定は、\ ``docker run -v``
への引数として認識される場合があります。

ボリュームはコンテナーの作成時にアタッチされ、展開中にそれ以上のアクションはありません。

RAIDアレイ
----------

AWS EC2インスタンスでは、RAIDボリュームを定義できます。

.. code:: yaml

   instances:

   - Name: one
     …
     volumes:
     - raid_device: /dev/md0
       device_name: /dev/xvdf
       raid_units: 2
       raid_level: 1
       volume_type: gp2
       volume_size: 100
       vars:
         volume_for: postgres_data

この例では、4×100GB EBS gp2ボリューム（\ ``/dev/xvd[f-i]``
）をアタッチし、それらを\ ``/dev/md0``
という名前のRAID-1ボリュームにアセンブルします。展開中の\ ``volume_for``
または\ ``mountpoint`` の処理は、他のボリュームと同様に発生します。

TPAは現在、他のプラットフォームでのRAIDアレイの作成とアセンブリをサポートしていませんが、
``device_name: /dev/md0`` または\ ``/dev/mapper/xyz``
でボリュームにエントリを追加することにより、既存のアレイを使用できます。
TPAは、他のブロックデバイスと同様に\ ``mkfs`` および\ ``mount``
を処理します。

LUKS暗号化
----------

TPAはLUKSで暗号化されたデバイスをセットアップできます。

.. code:: yaml

   instances:

   - Name: one
     …
     volumes:
     - device_name: /dev/xyz
       vars:
         encryption: luks
         luks_volume: mappedname
         volume_for: …

``encryption: luks``
が設定されたボリュームがまだ初期化されていない場合、TPAは\ ``cryptsetup``
を使用して最初に\ ``luksFormat`` 、次に\ ``luksOpen``
を使用して、他のデバイスと同様にファイルシステムの作成を処理する前に\ ``/dev/mapper/mappedname``
の下にマップします。

(データ損失の可能性を回避するために、TPAは有効なファイルシステムが既に含まれているデバイスでのLUKS暗号化のセットアップを拒否します。)

LUKSで暗号化された\ ``volume_for: postgres_data``
を作成すると、TPAはPostgresをブート時に自動的に起動しないように構成します。
``tpaexec start-postgres clustername``
を使用してボリュームをマウントし、Postgresを起動できます（および\ ``stop-postgres``
を使用してPostgresを停止し、ボリュームのマップを解除します）。

LUKSパスフレーズはローカルで生成され、ボールトに保存されます。

ファイルシステムの作成とマウント
--------------------------------

``device`` に有効なファイルシステムが含まれていない場合、\ ``mkfs``
で初期化されます。

.. code:: yaml

   instances:

   - Name: one
     …
     volumes:
     - device_name: /dev/xyz
       vars:
         volume_for: …
         fstype: ext4
         fsopts:
           - -cc
           - -m 2
         mountopts: defaults,relatime,nosuid
         readahead: 65536
         owner: root
         group: root
         mode: 0755

``fstype`` （デフォルト：ext4）、mkfsに渡す\ ``fsopts``
（デフォルト：none）、およびmountに渡してfstabに書き込む\ ``mountopts``
を指定できます（下記参照）。

TPAは、デバイスの先読みをデフォルトで16MBに設定します（そして値をリブートしても持続します）が、上記のようにボリュームに別の値を指定できます。

ボリュームがマウントされている場所を判断する方法は2つあります。
``mountpoint`` を明示的に指定するか、 ``volume_for``
を\ ``postgres_data`` 、\ ``postgres_wal`` 、\ ``postgres_tablespace``
、または\ ``barman_data``
に設定でき、TPAは設定をシステムの適切なマウントポイントに変換します。

``mountpoint`` が決定されると、 ``device`` は指定された\ ``mountopts``
（デフォルト：\ ``defaults,noatime`` ）でそこにマウントされます。
``/etc/fstab`` のファイルシステムのエントリーも作成されます。

オプションで、ボリュームに\ ``owner`` 、\ ``group`` 、または\ ``mode``
を指定でき、これらの属性は\ ``mountpoint``
で設定されます。デプロイメントのこの非常に早い段階では、 ``postgres``
ユーザーが存在するとは当てにできないことに注意してください。いずれにせよ、TPAは（個別に）Postgresが必要とするディレクトリに適切な所有権と権限があることを保証するため、自分で行う必要はありません。
