# イメージの扱い LXD はイメージをベースとしたワークフローを使用します。 LXD にはビルトイン のイメージ・ストアがあり、ユーザーが外部のツールがそこからイメージをインポート できます。 その後、それらのイメージからコンテナが起動されます。 ローカルのイメージを使ってリモートのインスタンスを起動できますし、リモートの イメージを使ってローカルのインスタンスを起動することもできます。こういった ケースではイメージはターゲットの LXD にキャッシュされます。 ## ソース LXD は 3 つの異なるソースからのイメージのインポートをサポートします。 - リモートのイメージサーバ (LXD か simplestreams) - イメージファイルの direct push - リモートのウェブサーバ上のファイル ### リモートのイメージサーバ (LXD か simplestreams) これは最も一般的なイメージソースで 3 つの選択肢のうちインスタンスの作成時に直接サポートされている唯一の選択肢です。 この選択肢では、イメージサーバは検証されるために必要な証明書(HTTPS のみがサポートされます)と共にターゲットの LXD サーバに提供されます。 次にイメージそのものがフィンガープリント (SHA256) あるいはエイリアスによって選択されます。 CLI の視点では、これは以下の一般的なアクションによって実行されます。 - lxc launch ubuntu:20.04 u1 - lxc launch images:centos/8 c1 - lxc launch my-server:SHA256 a1 - lxc image copy images:gentoo local: --copy-aliases --auto-update 上記の `ubuntu` と `images` のケースではリモートは simplestreams を読み取り専用のサーバプロトコルとして使用し、イメージの複数のエイリアスの 1 つによりイメージを選択します。 `my-server` リモートのケースでは別の LXD サーバがあり、上記の例ではフィンガープリントによってイメージを選択します。 ### イメージファイルの direct push これは主に外部サーバから直接イメージを取得できない隔離された環境で有用です。 そのような状況ではイメージファイルは他のシステムで以下のコマンドを使ってダウンロードできます。 - lxc image export ubuntu:20.04 その後ターゲットのシステムにイメージを転送してローカルイメージストアーに手動でインポートします。 - lxc image import META ROOTFS --alias ubuntu-20.04 `lxc image import` は統合イメージ (単一ファイル) と分割イメージ (2つのファイル) の両方をサポートします。 上の例では後者を使用しています。 ### リモートのウェブサーバ上のファイル 単一のイメージをユーザーに配布するためだけにフルのイメージサーバを動かすことの代替として、 LXD は URL を指定してイメージをインポートするのもサポートしています。 ただし、この方法にはいくつか制限があります。 - 統合ファイル(単一ファイル)のみがサポートされます - リモートサーバが追加の http ヘッダーを返す必要があります LXD はサーバに問い合わせをする際に以下のヘッダーを設定します。 - `LXD-Server-Architectures` にはクライアントがサポートするアーキテクチャーのカンマ区切りリストを設定します - `LXD-Server-Version` には使用している LXD のバージョンを設定します リモートサーバが `LXD-Image-Hash` と `LXD-Image-URL` を設定することを期待します。 前者はダウンロードされるイメージの SHA256 ハッシュで後者はイメージをダウンロードする URL です。 これによりかなり複雑なイメージサーバがカスタムヘッダーをサポートする基本的なウェブサーバだけで実装できます。 クライアント側では以下のように使用できます。 `lxc image import URL --alias some-name` ### インスタンスやスナップショットを新しいイメージとして公開する インスタンスやスナップショットの 1 つを新しいイメージに変換できます。 これは `lxc publish` で CLI 上で実行できます。 これを行う際には、たいていの場合公開する前にインスタンスのメタデータやテンプレートを `lxc config metadata` と `lxc config template` コマンドを使って整理するのが良いでしょう。 さらにホストの SSH キーや dbus/systemd の machine-id などインスタンスに固有な状態も削除するのが良いでしょう。 インスタンスから tarball を生成した後圧縮する必要があるので、公開のプロセスはかなり時間がかかるかもしれません。 この操作は特に I/O と CPU の負荷が高いので、公開操作は LXD により 1 つずつ順に実行されます。 ## キャッシュ リモートのイメージからインスタンスを起動する時、リモートのイメージが ローカルのイメージ・ストアにキャッシュ・ビットをセットした状態で ダウンロードされます。イメージは、 `images.remote_cache_expiry` に 設定された日数だけ使われない (新たなインスタンスが起動されない) か、 イメージが期限を迎えるか、どちらか早いほうが来るまで、プライベートな イメージとしてローカルに保存されます。 LXD はイメージから新しいインスタンスが起動される度にイメージの `last_used_at` プロパティを更新することで、イメージの利用状況を記録しています。 ## 自動更新 LXD はイメージを最新に維持できます。デフォルトではエイリアスで指定し リモートサーバから取得したイメージは LXD によって自動更新されます。 これは `images.auto_update_cached` という設定で変更できます。 (`images.auto_update_interval` が設定されない限り) 起動時とその後 6 時間毎に、 LXD デーモンはイメージ・ストア内で自動更新対象となっていて ダウンロード元のサーバが記録されている全てのイメージのより新しい バージョンがあるかを確認します。 新しいイメージが見つかったら、イメージ・ストアにダウンロードされ、 古いイメージを指していたエイリアスは新しいイメージを指すように変更され、 古いイメージはストアから削除されます。 リモート・サーバからイメージを手動でコピーする際に、特定のイメージを 最新に維持するように設定することもできます。 ユーザーがイメージのキャッシュから新しいインスタンスを作成しようとした時に、 アップストリームの新しいイメージ更新が公開されており、ローカルの LXD が キャッシュに古いイメージを持っている場合は、 LXD はインスタンスの作成を 遅らせるのではなく、古いバージョンのイメージを使います。 この振る舞いは現在のイメージが自動更新されるように設定されている時のみに 発生し、 `images.auto_update_interval` を 0 にすることで無効にできます。 ## プロファイル `lxc image edit` コマンドを使ってイメージにプロファイルのリストを関連付けできます。 イメージにプロファイルを関連付けた後に起動したインスタンスはプロファイルを順番に適用します。 プロファイルのリストとして `nil` を指定すると `default` プロファイルのみがイメージに関連付けされます。 空のリストを指定すると、 `default` プロファイルも含めて一切のプロファイルをイメージに適用しません。 イメージに関連付けされたプロファイルは `lxc launch` の `--profile` と `--no-profiles` オプションを使ってインスタンス起動時にオーバーライドできます。 ## 特別なイメージプロパティ プレフィックス***requirements***で始まるイメージプロパティ(例:requirements.XYZ)は、 LXDがホストシステムと当該イメージで生成されるインスタンスの互換性を判断するために使用されます。 これらの互換性がない場合にはLXDはそのインスタンスを起動しません。 現在のところ、以下の要件がサポートされています。 キー | タイプ | デフォルト | 説明 :-- | :--- | :------ | :---------- requirements.secureboot | string | - | "false" に設定すると、イメージがセキュアブートで起動しないことを示します。 requirements.cgroup | string | - | "v1" "に設定されている場合、ホストでCGroupV1が実行されている必要があることを示します。 ## イメージの形式 LXD は現状 2 つの LXD に特有なイメージの形式をサポートします。 1 つめは統合された tarball で、単一の tarball がインスタンスの root と 必要なメタデータの両方を含みます。 2 つめは分離されたモデルで、 2 つのファイルを使い、 1 つは root を 含み、もう一つはメタデータを含みます。 LXD 自身によって生成されるのは前者の形式で、 LXD 特有のイメージを使う 際はこちらの形式を使うべきです。 後者は、今日既に利用可能なものとして存在している LXD 以外の rootfs tarball を使ってイメージを簡単に作成できるように想定されているものです。 ### 統合された tarball tarball は圧縮できます。そして次のものを含みます。 - `rootfs/` - `metadata.yaml` - `templates/` (省略可能) このモードではイメージの識別子は tarball の SHA-256 です。 ### 分離された tarball 2 つの (圧縮しても良い) tarball 。 1 つはメタデータ、もう 1 つは rootfs です。 `metadata.tar` は以下のものを含みます。 - `metadata.yaml` - `templates/` (省略可能) `rootfs.tar` は、そのルートに Linux の root ファイルシステムを含みます。 このモードではイメージの識別子はメタデータと rootfs の tarball を(この順番で) 結合したものの SHA-256 です。 ### サポートされている圧縮形式 LXD は広範な tarball の圧縮アルゴリズムをサポートしますが、互換性のために gzip か xz が望ましいです。 分離されたイメージではコンテナの場合は rootfs ファイルはさらに squashfs 形式でフォーマットすることもできます。 仮想マシンでは `rootfs.img` ファイルは常に qcow2 であり、オプションで qcow2 のネイティブ圧縮を使って圧縮することもできます。 ### 中身 コンテナでは rootfs のディレクトリ (あるいは tarball) は完全なファイルシステムのツリーを含み、それが `/` になります。 VM ではこれは代わりに `rootfs.img` ファイルでメインのディスクデバイスになります。 テンプレートのディレクトリはコンテナ内で使用される pongo2 形式のテンプレート・ファイルを含みます。 `metadata.yaml` はイメージを (現状は) LXD で稼働されるために必要な情報を 含んでおり、これは以下のものを含みます。 ```yaml architecture: x86_64 creation_date: 1424284563 properties: description: Ubuntu 20.04 LTS Intel 64bit os: Ubuntu release: focal 20.04 templates: /etc/hosts: when: - create - rename template: hosts.tpl properties: foo: bar /etc/hostname: when: - start template: hostname.tpl /etc/network/interfaces: when: - create template: interfaces.tpl create_only: true ``` `architecture` と `creation_date` の項目は必須です。 `properties` は 単にイメージのデフォルト・プロパティの組です。 `os`, `release`, `name` と `description` の項目は必須ではないですが、記載されることが多いでしょう。 テンプレートで `when` キーは以下の 1 つあるいは複数が指定可能です。 - `create` (そのイメージから新しいインスタンスが作成されたときに実行される) - `copy` (既存のインスタンスから新しいインスタンスが作成されたときに実行される) - `start` (インスタンスが開始される度に実行される) テンプレートは常に以下のコンテキストを受け取ります。 - `trigger`: テンプレートを呼び出したイベントの名前 (string) - `path`: テンプレート出力先のファイルのパス (string) - `container`: インスタンスのプロパティ (name, architecture, privileged そして ephemeral) の key/value の map (map[string]string) (廃止予定。代わりに `instance` を使用してください) - `instance`: インスタンスのプロパティ (name, architecture, privileged そして ephemeral) の key/value の map (map[string]string) - `config`: インスタンスの設定の key/value の map (map[string]string) - `devices`: インスタンスに割り当てられたデバイスの key/value の map (map[string]map[string]string) - `properties`: metadata.yaml に指定されたテンプレートのプロパティの key/value の map (map[string]string) `create_only` キーを設定すると LXD が存在しないファイルだけを生成し、 既存のファイルを上書きしないようにできます。 一般的な規範として、パッケージで管理されているファイルをテンプレートの 生成対象とすべきではないです。そうしてしまうとインスタンスの通常の操作で 上書きされてしまうでしょう。 利便性のため、以下の関数が pongo のテンプレートで利用可能となっています。 - `config_get("user.foo", "bar")` => `user.foo` の値か、未設定の場合は `"bar"` を返します。