第8章 Docker フォーマットコンテナーを使用したストレージの管理

8.1. 概要

実稼働環境で数多くのコンテナーを実行するには、多くのストレージ領域が必要になります。さらに、コンテナーを作成し、実行するには、基礎となるストレージドライバーが最も効率のよいオプションを使用できるように設定される必要があります。Docker のデフォルトのストレージオプションはシステム間で異なり、場合によっては変更する必要がある場合もあります。RHEL のデフォルトインストールはループバックデバイスを使用し、RHEL Atomic Host ではインストール時に LVM シンプールが作成されます。ただし、ループバックオプションを実稼働システムで使用することは推奨されません。計画段階では、以下を確認してください。

1) direct-lvm を実行しており、LVM シンプールがセットアップされている。これは docker-storage-setup ユーティリティーを使用して実行できます。

2) インストール時に十分な空き領域を割り当てているか、または外部ストレージがシステムに割り当てられるように計画する。

本書では、領域が不足した場合にストレージを拡張する手順についても記載しています。これらの手順の一部は破壊的な操作を伴うため、前もってよく計画することをお勧めします。ご使用のシステムに関連した手順を使用して、環境のセットアップを行ってください。

8.2. docker-storage-setup の使用

docker-storage-setup ユーティリティーは docker パッケージと共にインストールされ、direct LVM ストレージのセットアップに役立ちます。

docker が起動すると、docker-storage-setup デーモンを自動的に起動します。デフォルトでは、docker-storage-setup は root 論理ボリュームを含むボリュームグループに空き領域を探そうとし、LVM シンプールのセットアップを試行します。ボリュームグループに空き領域がない場合、docker-storage-setup は LVM シンプールをセットアップせず、ループバックデバイスにフォールバックします。

docker-storage-setup のデフォルト動作は /usr/lib/docker-storage-setup/docker-storage-setup 設定ファイルによって制御されます。新しい値を使用してファイル /etc/sysconfig/docker-storage-setup を作成して、オプションを上書きできます。

docker-storage-setup では、シンプールをセットアップするために空き領域のある場所を認識している必要があります。以下は、docker-storage-setup が LVM シンプールをセットアップできるようにシステムを設定するいくつかの方法です。

詳細は、man docker-storage-setup(1) を参照してください。(man ページは RHEL Atomic ではデフォルトで利用できず、RHEL Atomic Tools コンテナーをダウンロードしておく必要があることに注意してください。)

8.2.1. root ボリュームを含むボリュームグループの LVM シンプール

デフォルトでは、docker-storage-setup は root ボリュームグループの空き領域を探し、LVM シンプールを作成します。そのため、インストール時に root ボリュームグループに空き領域を残すと、docker の起動時にシンプールが自動的にセットアップされ、使用されます。

8.2.2. ユーザー指定のボリュームグループの LVM シンプール

docker-storage-setup は、シンプールを作成するために特定のボリュームグループを使用するように設定できます。

# echo VG=docker-vg >> /etc/sysconfig/docker-storage-setup
# systemctl start docker

8.2.3. ユーザー指定のブロックデバイスでのボリュームグループおよび LVM シンプールのセットアップ

1 つまたは複数のデバイスを /etc/sysconfig/docker-storage-setup ファイルに指定できます。docker-storage-setup は、docker サービスが使用するボリュームグループと LVM シンプールを作成します。

# echo DEVS=/dev/vdb >> /etc/sysconfig/docker-storage-setup
# systemctl start docker

8.3. Red Hat Enterprise Linux におけるストレージの管理

Red Hat Enterprise Linux では、デフォルトでは root ボリュームグループに空き領域はありません。そのため、docker-storage-setup が空き領域を見つけられるようにするための操作が必要です。

簡単な方法として、インストール時に root を含むボリュームグループにいくらかの空き領域を残すことができます。以下のセクションでは空き領域を残す方法を説明します。

8.3.1. インストール時に root ボリュームグループに空き領域を残す方法

インストール時に root ボリュームグループに空き領域を確保する 2 つの方法があります。インタラクティブなグラフィカルインストールユーティリティーの Anaconda を使用するか、またはインストールを制御するキックスタートファイルを準備します。

8.3.1.1. GUI インストール

  1. グラフィカルインストールを開始します。「Installation Destination」画面に移動し、「Other Storage Options」から「I will configure partitioning」を選択して「Done」をクリックします。
  2. マウントポイントを作成するようにプロンプトが出される「Manual Partitioning」画面で、「Click here to create them automatically」を選択します。これにより、デフォルトのパーティショニングスキームが作成されます。
  3. root パーティション (/) を選択します。これにより、「Desired Capacity」入力フィールドが表示されます。
  4. その容量を縮小し、root ボリュームグループに空き領域を確保します。
  5. デフォルトで、root LV を持つボリュームグループにはユーザーが作成したボリュームに対応する十分な大きさがあります。また、ディスク上のすべての空き領域は空き領域のままとなり、そのボリュームグループの一部にはなりません。この設定を変更するには、「Modify」をクリックし、「Size policy」を選択して「As large as possible」に設定し、「Save」をクリックします。これにより、ディスク上の使用されていない領域はボリュームグループ内の空き領域になります。
  6. 「Done」をクリックして、提案されるパーティション設定を受け入れます。
  7. 「Begin Installation」をクリックします。

8.3.1.2. キックスタートインストール

キックスタートファイルでは、"volgroup" キックスタートオプションを "--reserved-percent" および "--reserved-space" オプションと共に使用します。ここで、ボリュームグループ内でどの程度の領域を確保するかを指定できます。以下は、root LV に20% の空き領域を残すキックスタートファイルのセクション例です。

# Disk partitioning information
part /boot --size=500
part pv.1 --size=500 --grow
volgroup rhel --pesize=4096 pv.1 --reserved-percent=20
logvol /  --size=500 --grow --name=root --vgname=rhel
logvol swap --size=2048 --name=swap --vgname=rhel

8.4. Red Hat Enterprise Linux Atomic Host におけるストレージの管理

RHEL Atomic Host では、root ボリュームのサイズは 3GB です。root ボリュームグループには空き領域があり、その 60% は LVM シンプールのセットアップのために docker-storage-setup によって使用されます。残りの領域は空き領域となり、root ボリュームを拡張したり、シンプールを作成したりするために使用できます。

デフォルトのパーティションが設定されている RHEL Atomic Host では、docker-storage-setup サービスはコンテナーイメージで使用される LVM シンプールを作成します。インストール時に、インストールプログラムはデフォルトで 3GB の root 論理ボリュームを作成します。次は起動時に、docker-storage-setup サービスが、残りの領域の 60% を占める docker-pool という LVM シンプールを自動的にセットアップします。残りの領域は root または docker-pool を拡張するために使用できます。起動時に、docker-storage-setup は /etc/sysconfig/docker-storage ファイルを読み取り、使用されているストレージのタイプを判別し、Docker が LVM シンプールを利用できるようにこれを変更します。デフォルト値は、/etc/sysconfig/docker-storage-setup という名前のファイルを作成して上書きできます。これにより、起動時のサービスの動作が変更されます。このファイルを作成しない場合、LVM シンプールがデフォルトで作成されます。

デフォルトのパーティション設定でクラウドイメージからインストールされる Red Hat Enterprise Linux Atomic Host には、atomicos というボリュームグループと、そのグループの中に 2 つの論理ボリュームがあります。ボリュームグループの名前は、 Red Hat Enterprise Linux Atomic Host のイメージごとに異なります。ベアメタルおよび仮想インストールの場合、ボリュームグループにはホスト名に由来する名前が付きます。ホストの名前が付いていない場合、ボリュームグループは rah になります。ボリュームグループおよびそれらの中にある論理ボリュームのプロパティーはすべてのイメージ間で同一のプロパティーになります。

lvs コマンドを実行して、システムの論理ボリュームを一覧表示し、ボリュームグループ名を表示できます。

# lvs
LV                VG          Attr          LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
docker-pool       atomicos    twi-aotz--    7.69g             14.36  2.56
root              atomicos    -wi-ao----    2.94g
  1. root パーティション は root と呼ばれ、デフォルトでは 3GB です。root は以下を含む論理ボリュームです。

    • /var および /etc ディレクトリー。
    • OSTree バージョンを含む /ostree/repo
    • 一時データまたは docker ボリューム などのコンテナーのイメージデータが含まれる /var/lib/docker/ ディレクトリー。docker ボリューム は、実行中のコンテナーがホストシステムに要求できるストレージのユニットです。このストレージのユニットは別のコンテナーで提供されるだけでなく、ホストから直接提供することもできます。Red Hat Enterprise Linux Atomic Host の場合、それらのボリュームは /var/lib/docker/vfs/root パーティション に自動的に割り当てられます。
  2. コンテナーイメージパーティションdocker-pool と呼ばれ、残りの領域の 60% を使用します。これは docker-storage-setup サービスによって LVM シンプールとしてフォーマットされます。このパーティションはコンテナーイメージを保存するために使用されます。docker-pool で使用される領域は docker-storage-setup サービスによって管理されます。レジストリーからコンテナーイメージを取得する場合など、イメージはこのパーティションの領域を占めます。コンテナーイメージは読み取り専用です。イメージがコンテナーとして起動すると、すべての書き込み (マウントされたボリュームまたは docker ボリュームに対するものを除く) はこの論理ボリュームに保存されます。

docker-pool で空き領域を監視し、領域が不足した状態で実行されないようにすることは非常に重要です。LVM シンプールが領域が不足すると、LVM シンプールの基礎となる XFS ファイルシステムが I/O エラーに対して再試行を無制限に繰り返すため、障害が発生します。LVM2 ツールはユーザー設定に基づいてシンプールを監視し、これを拡張するための機能を提供します。詳細は、lvmthin(7) man ページの Automatically extend thin pool LV and Data space exhaustion セクションを参照してください。デフォルトでは、docker-storage-setup は自動拡張用にシンプールを設定します。つまり、プールが一杯になると、自動的にボリュームグループ内の利用可能な空き領域が拡張し、これが使用されます。ボリュームグループが一杯になると、自動拡張用の領域がなくなるため、領域を確保するために不要な古いコンテナーを破棄するなど措置を事前に取ることができます。または、追加のストレージがシステムに追加されるまで、コンテナーイメージの作成または変更を停止することもできます。

  • /etc/sysconfig/docker - ユーザーによって設定されます。
  • /etc/sysconfig/docker-storage - プログラムによって設定されますが、ユーザーが編集することもできます (docker-storage-setup を無効にする必要があります)。
  • /etc/sysconfig/docker-storage-setup - ユーザーによって設定されますが、RHEL Atomic Host でのみ利用できます。

8.4.1. インストール時の root パーティションのデフォルトサイズの変更

デフォルトの root パーティション のサイズを変更するには、ご使用のインストール用に以下の方法を使用します。

  • Anaconda: 「Installation Destination」画面に移動して、「Other Storage Options」から「I will configure partitioning」を選択して「Done」をクリックします。これにより、「Manual Partitioning」画面に移動し、マウントポイントを作成するようにプロンプトが出されます。「Click here to create them automatically」をクリックすると boot、root、および swap パーティションが提供されます (この時点ではこれらのパーティションのみがあり、docker-pool は docker-storage-setup サービスで後で作成されます)。root パーティション (/) を選択し、「Desired Capacity」入力フィールドに新たな値を入力します。インストールが終了したら、システムはカスタム設定で起動します。
  • キックスタート: キックスタートファイルの %post セクションで、/etc/sysconfig/docker-storage-setup ファイル (自動作成される) へのパスを指定し、コマンドの後に必要なオプションを指定します。構文は以下のようになります。
%post
cat > /etc/sysconfig/docker-storage-setup << EOF
ROOT_SIZE=6G
EOF
%end
  • cloud-init: user-data ファイルの write\_files ディレクティブは、上記のキックスタートの例のように /etc/sysconfig/docker-storage-setup ファイルをセットアップするために使用されます。この例の user-data ファイルは cloud-user のパスワードを "atomic" に設定し、root パーティションがデフォルトの 3GB ではなく 6GB になるように設定します。
#cloud-config
password: atomic
write_files:
  - path: /etc/sysconfig/docker-storage-setup
    permissions: 0644
    owner: root
    content: |
      ROOT_SIZE=6G

8.4.2. インストール後の root パーティションのサイズの変更

コンテナーイメージを、/var/lib/docker/ で領域を必要とする コンテナーイメージパーティション に追加する場合、イメージは現時点で root パーティション で利用可能なサイズよりも大きな領域を要求できます。コンテナーイメージは、データベースサーバーからのデータなど、コンテナーに保存できないデータがある場合に docker ボリュームを要求できます。root の領域が不足している場合は、以下の 3 つのオプションを選択できます。

  • root パーティションを拡張して、ボリュームグループ内の空き領域を使用する。
  • 新規ストレージをホストに追加し、root パーティションを拡張する。
  • root パーティションを拡張し、コンテナーイメージパーティションを縮小する。

8.4.2.1. root パーティションを拡張してボリュームグループの空き領域を使用する方法

ボリュームグループに空き領域がある場合、root ボリュームを拡張して、空き領域の一部およびすべてを使用して root パーティションを拡張することができます。

# lvextend -r -L +3GB /dev/atomicos/root

8.4.2.2. 追加ストレージをホストに追加し、root パーティションを拡張する方法

このオプションに破壊的は操作は伴わず、追加のストレージを root パーティション に追加し、これを使用することができます。これには、新規のディスクデバイスを使用して新規の物理ボリュームを作成することが必要になり (この場合は /dev/sdb)、これを atomicos ボリュームグループに追加してから root パーティション 論理ボリュームを拡張します。このタスクについては、docker デーモンおよび docker-storage-setup サービスを停止する必要があります。以下のコマンドを使用します。

# systemctl stop docker docker-storage-setup
# pvcreate /dev/sdb
# vgextend atomicos /dev/sdb
# lvextend -r -L +3GB /dev/atomicos/root
# systemctl start docker docker-storage-setup

8.4.2.3. ストレージを追加せずに root パーティションを拡張する方法

このオプションには、コンテナーイメージパーティション を破棄するような破壊的な操作を伴います。追加のストレージを root パーティション に追加できない場合、このパーティションを拡張することができます。root パーティション を拡張するには、コンテナーイメージパーティション を縮小しなければなりません。ただし、LVM は縮小するシンプロビジョニングされた論理ボリュームをサポートしません。

したがって、実行中のすべてのコンテナーを停止し、コンテナーイメージパーティション を破棄し、root パーティション を拡張する必要があります。docker-storage-setup は、再起動時に残りの領域を コンテナーイメージパーティション に再度割り当てます。以下のコマンドを使用します。

# systemctl stop docker docker-storage-setup
# rm -rf /var/lib/docker/*
# lvremove atomicos/docker-pool
# lvextend -L +3GB /dev/atomicos/root
# systemctl start docker-storage-setup
# systemctl start docker

この時点で、すべてのコンテナーイメージを再びダウンロードする必要があります。

8.5. Docker ストレージ設定の変更

Docker のストレージ設定を変更する場合、/var/lib/docker ディレクトリーを必ず削除してください。このディレクトリーには、新しい設定では無効となる古いイメージ、コンテナー、およびボリュームのメタデータが含まれます。ストレージ設定の変更が必要になる可能性のある例には、ループデバイスの使用から LVM シンプールに切り替える場合や、あるシンプールから別のシンプールに切り替える場合が含まれます。後者の場合、古いシンプールを削除する必要があります。

# systemctl stop docker docker-storage-setup
# rm /etc/sysconfig/docker-storage-setup
# lvremove docker/docker-pool
# rm -rf /var/lib/docker/
# systemctl start docker

8.6. Overlay グラフドライバー

overlay グラフドライバーは、スナップショットボリューム間のページキャッシュの共有を特長とする COW (copy-on-write) 方式の union ファイルシステムを使用します。LVM シンプールと同様に、OverlayFS はイメージ層の効率的な保存をサポートします。ただし、LVM シンプールと比較すると、OverlayFS を使用した場合、コンテナーの作成および破棄に使用されるメモリーはより少なくなるため、パフォーマンスがよくなります。

警告

OverlayFS は POSIX に準拠しておらず (一部のファイルシステムのセマンティクスの一部は ext4 および XFS などの標準ファイルシステムとは異なる)、SELinux をまだサポートしていないことに注意してください。したがって、OverlayFS を Docker で有効にする前に、アプリケーションが OverlayFS で機能することを確認してください。Docker で OverlayFS を使用する方法については、『Red Hat Enterprise Linux 7.2 リリースノート』の 第 17 章 ファイルシステム を参照してください。

Docker の overlay グラフドライバーを有効にする一般的な方法は、SELinux を無効にし、/etc/sysconfig/docker-storage-setupoverlay を指定する方法です。

重要

ストレージのバックエンドの変更には破壊的な操作が伴います。開始する前に、必ず docker save でイメージをバックアップしてください。その後に、docker load でバックアップからイメージを復元することができます。

Docker を停止し、現行のストレージを削除します。

# systemctl stop docker docker-storage-setup
# rm -rf /var/lib/docker/

/etc/sysconfig/dockerOPTIONS 変数からオプションの --selinux-enabled を削除して SELinux を無効にします。

# sed -i '/OPTIONS=/s/--selinux-enabled//' /etc/sysconfig/docker

/etc/sysconfig/docker-storage-setupSTORAGE_DRIVERoverlay に設定します。

STORAGE_DRIVER=overlay

docker-storage-setup を再起動してから docker を再起動します。

# systemctl start docker-storage-setup
# systemctl start docker
  • キックスタート

    キックスタートインストールの場合、%post セクションで以下のコマンドを使用します。

    %post
    sed -i '/OPTIONS=/s/--selinux-enabled//' /etc/sysconfig/docker
    echo "STORAGE_DRIVER=overlay" >> /etc/sysconfig/docker-storage-setup
    %end
  • cloud-init

    cloud-init インストールの場合、user-data ファイルに以下のスニペットを組み込みます。

    runcmd:
      - sed -i '/OPTIONS=/s/--selinux-enabled//' /etc/sysconfig/docker
      - echo "STORAGE_DRIVER=overlay" >> /etc/sysconfig/docker-storage-setup

8.7. ストレージについての追加情報