Howto

Armadillo Base OS:コンテナ内でUSBメモリやSDカードを使用する方法(autofs)

本ブログではArmadillo Base OS搭載製品で、USB メモリや SD カードを自動マウントしてコンテナ内で使用する方法を紹介します。
この方法は以下のような場面で役立ちます。

  • USB メモリや SD カードを常時ストレージとして使いたい
  • USB メモリ等がコンテナ稼働中に差し込まれる状況でコンテナ内からアクセスしたい

autofs とは

autofs は自動的にファイルシステムをマウントする Linux の機能です。マウントされていないファイルシステムをアクセスする要求を受け取ると、設定したディレクトリに自動的にマウントします。また、そのディレクトリを使わなくなった際にも自動的にアンマウントすることもできます。この機能は autofs パッケージをインストールすることで利用できるようになります。

ただし、autofs に限らず、コンテナ内から USB メモリや SD カードにアクセスするためには、コンテナに SYS_ADMIN 権限を与える必要があります。この権限は非常に強力なので、メインのアプリケーションを実行するコンテナ(以下、アプリケーションコンテナと呼ぶことにします)にこの権限を与えるやり方はセキュリティ的なリスクを伴います。

そこで、アプリケーションコンテナとは別に、autofs のサービス専用の「autofs コンテナ」を新たに用意して、このコンテナに先ほどの権限を与えます。そして、autofs コンテナは USB メモリや SD カードをアプリケーションコンテナがアクセスできる場所にマウントします。これによりアプリケーションコンテナに付与されるアクセス権限を最小限に留めておくことができます。

autofs コンテナの作成方法は2通りあります。 また、弊社では VS Code 上でのアプリケーションコンテナの開発環境として、拡張機能「Armadillo Base OS Development Environment(ABOSDE)」 を提供しています。 ABOSDE では作成したアプリケーションコンテナの SBOM 出力をサポートしています。また、脆弱性が見つかった場合にアプリケーションコンテナの更新が容易という利点があります。ABOSDE をすでにご使用いただいている場合は2つ目の方法を推奨します。

  1. ABOS 上でコマンド実行して作成する方法
     - 手早く確認したい人におすすめ
  2. ABOSDE から Atmark Container Project を使って作成する方法
     - ABOSDE からのプロジェクト作成に慣れている人におすすめ

どちらでも、お好きな方法をご使用ください。 autofs コンテナの作成方法や、アプリケーションコンテナに対する設定方法は次の流れで実施します。

ABOS 上でコマンド実行する場合の流れ

1-1. autofs コンテナのコンテナイメージを作成
1-2. autofs コンテナのコンフィグファイルを作成
1-3. ABOS 側に autofs の設定ファイルを配置
1-4. アプリケーションコンテナの設定変更
1-5. コンテナのコンフィグファイルの永続化

ABOSDE から Atmark Container Project を使って作成する場合の流れ

2-1. Atmark Container プロジェクトの作成
2-2. autofs コンテナイメージの作成設定
2-3. autofs コンテナのコンフィグファイルを作成
2-4. autofs コンテナの設定ファイルの作成
2-5. autofs コンテナの設定ファイルを ABOS 上に配置する設定
2-6. autofs コンテナを配置する SWU イメージの作成
2-7. アプリケーションコンテナの設定

ABOS 上でコマンド実行する場合の手順

1-1. autofs コンテナのコンテナイメージを作成

コンテナイメージを作成するための Dockerfile を作成します。もとになるイメージは alpine で、autofs パッケージをインストールさせます。

armadillo:~# vi Dockerfile
FROM docker.io/alpine

RUN apk add --no-cache  autofs

Dockerfile を作成したら、以下のコマンドを実行してこの Dockerfile から autofs コンテナイメージを作成します。

armadillo:~# abos-ctrl podman-rw build -t autofs -f Dockerfile
...
Successfully tagged localhost/autofs:latest

1-2. autofs コンテナのコンフィグファイルを作成

/etc/atmark/containers/autofs.conf を作成します。/var/app/rollback/volumes/autofsこの後の手順で用意します。

armadillo:~# vi /etc/atmark/containers/autofs.conf
# ビルドしたコンテナイメージ
set_image localhost/autofs
# コンフィグディレクトリ
add_volumes /var/app/rollback/volumes/autofs:/etc/autofs:ro
# 共有ディレクトリ
add_volumes /run/mnt:/mnt:shared
# マウントするために必要な権限
add_args --cap-add SYS_ADMIN
# sd と mmc は usb メモリ等のため
# misc は /dev/autofs のアクセス権限のため
add_hotplugs sd mmc misc
# pid が見えないとリクエストを受信できないため
add_args --pid=host
# サービス実行コマンド
set_command automount -f -v

1-3. ABOS 側に autofs の設定ファイルを配置

ABOS の /var/app/rollback/volumes ディレクトリ配下に autofs ディレクトリを作成して、autofs の設定を配置します。 作成するのは以下の三つです。

/var/app/rollback/volumes/autofs
├── auto.master
├── auto.mnt
└── autofs.conf

まずはディレクトリを作成します。

armadillo:~# mkdir /var/app/rollback/volumes/autofs

auto.master

マウントポイントの情報を記載します。以下は /mnt/automount に対して、auto.mnt の設定を適用する記述です。

armadillo:~# vi /var/app/rollback/volumes/autofs/auto.master
/mnt/automount /etc/autofs/auto.mnt

auto.mnt

マウント情報を記載します。以下は USBメモリと SDカードをそれぞれ usb、 sd ディレクトリにマウントする記述です。

armadillo:~# vi /var/app/rollback/volumes/autofs/auto.mnt
usb -nosuid,nodev,ro,fstype=auto :/dev/sda1
sd -nosuid,nodev,ro,fstype=auto :/dev/mmcblk1p1
# fat の場合(FAT32まで)は以下のようにユーザーも設定可能です
# usb_fat -nosuid,nodev,ro,uid=1000,gid=1000,fstype=vfat :/dev/sda1

autofs.conf

autofs の設定ファイルです。紛らわしいですが、コンテナの方のコンフィグファイル(/etc/atmark/containers/autofs.conf)ではありませんのでご注意ください。

armadillo:~# vi /var/app/rollback/volumes/autofs/autofs.conf
# 変更が必要な場合は man page を参照してください:
# https://manpages.debian.org/bookworm/autofs/autofs.conf.5.en.html
[autofs]
# デフォルトより早めにアンマウントします
timeout = 1
# マウントに失敗してから再試行可能になるまでの時間を早めに設定
negative_timeout = 1

上記のように設定することで、ABOS側からはUSBメモリやSDカードに以下の場所からアクセスできるようになります。

/run/mnt/
└── automount
    ├── sd
    └── usb

1-4. アプリケーションコンテナの設定変更

アプリケーションコンテナのコンフィグファイルには以下の行を追加します。

add_volumes /run/mnt:/mnt:shared,ro

1-5. コンテナのコンフィグファイルの永続化

念のため、すべてのコンテナ設定ファイルを永続化します。

armadillo:~# persist_file -r /etc/atmark/containers/

以上で設定は終了です。動作確認 に進んでください。

ABOSDE から Atmark Container Project を使う場合の手順

2-1. Atmark Container プロジェクトの作成

ABOSDE を使用する場合は Atmark Container プロジェクトを使用します。 ABOSDE を起動してメニューから [Atmark Container New Project] を選択します。 今回は atofs という名前で作成します。

2-2. autofs コンテナイメージの作成設定

もとにするコンテナイメージは alpine です。 autofs プロジェクト内の container_setup/alpine/Dockerfile の末尾に以下を追記します。

RUN apk add --no-cache autofs

2-3. autofs コンテナのコンフィグファイルを作成

autofs プロジェクト内の container_setup/conf/alpine.conf の内容を以下のように書き換えます。

set_image localhost/alpine:latest

# コンフィグディレクトリ
add_volumes /var/app/rollback/volumes/autofs:/etc/autofs:ro
# 共有ディレクトリ
add_volumes /run/mnt:/mnt:shared
# マウントするために必要な権限
add_args --cap-add SYS_ADMIN
# sd と mmc は usb メモリ等のため
# misc は /dev/autofs のアクセス権限のため
add_hotplugs sd mmc misc
# pid が見えないとリクエストを受信できないため
add_args --pid=host
# サービス実行コマンド
set_command automount -f -v

2-4. autofs コンテナの設定ファイルの作成

container_setup ディレクトリ配下に autofs ディレクトリを作成して、autofs の設定を配置します。 作成するのは以下の三つです。

container_setup/autofs
├── auto.master
├── auto.mnt
└── autofs.conf

auto.master

マウントポイントの情報を記載します。以下は /mnt/automount に対して、auto.mnt の設定を適用する記述です。

/mnt/automount /etc/autofs/auto.mnt

auto.mnt

マウント情報を記載します。以下は USBメモリと SDカードをそれぞれ usb、 sd ディレクトリにマウントする記述です。

usb -nosuid,nodev,ro,fstype=auto :/dev/sda1
sd -nosuid,nodev,ro,fstype=auto :/dev/mmcblk1p1
# fat の場合(FAT32まで)は以下のようにユーザーも設定可能です
# usb_fat -nosuid,nodev,ro,uid=1000,gid=1000,fstype=vfat :/dev/sda1

autofs.conf

autofs の設定ファイルです。

# 変更が必要な場合は man page を参照してください:
# https://manpages.debian.org/bookworm/autofs/autofs.conf.5.en.html
[autofs]
# デフォルトより早めにアンマウントします
timeout = 1
# マウントに失敗してから再試行可能になるまでの時間を早めに設定
negative_timeout = 1

上記のように設定することで、ABOS側からはUSBメモリやSDカードに以下の場所からアクセスできるようになります。

/run/mnt/
└── automount
    ├── sd
    └── usb

2-5. autofs コンテナの設定ファイルを ABOS 上に配置する設定

container_setup/config/alpine.desc に以下を追記します。 countainer_setup/autofs に作成したファイルを /var/app/rollback/volumes/autofs ディレクトリに配置するための設定です。

swdesc_files --dest /var/app/rollback/volumes/autofs autofs

2-6. autofs コンテナを配置する SWU イメージの作成

ファイルの修正が完了したら ABOSDE のメニューから [Generate alpine container setup swu] を実行します。 作成に成功したら container_setup ディレクトリに alpine.swu が生成されているので、 ご使用の Armadillo にインストールしてください。 インストールが成功したら、autofs コンテナの設定は終了です。

2-7. アプリケーションコンテナの設定

自動マウントを使用したいアプリケーションコンテナのコンフィグファイルには、以下の行を追記して保存します。

add_volumes /run/mnt:/mnt:shared,ro

動作確認

まず、全てのコンテナ(autofs コンテナとアプリケーションコンテナ)を再起動します。alpine.swu のインストールに成功した場合は、Armadillo の再起動に伴い、コンテナも再起動しているためこのコマンド実行は不要です。

armadillo:~# podman_start -a

アプリケーションコンテナ内では /mnt/automount ディレクトリに sd と usb ディレクトリが現れるようになります。

armadillo:~# podman exec -ti [アプリケーションコンテナ] sh
# ls /mnt/automount/
sd  usb

USB メモリをArmadilloに接続して、アプリケーションコンテナからアクセスできることを確認します。

/ # ls /mnt/automount/usb
<USB メモリの中身>

USB メモリがない場合は「No such file or directory」としてエラーが出力されます。

注意点

本 howto では USB メモリのマウントオプションに「 ro 」を設定し、読み取り専用としてマウントさせています。 書き込みを行いたい場合はauto.mntから「 ,ro 」を消してください。なお、書き込みを行う際は必ず書き込みが完了してからUSBメモリを外すようにしてください。

また、アプリケーションコンテナから USB メモリや microSD カードにアクセスできないといった問題に遭遇した場合、autofsコンテナのエラー出力が問題解決のための参考になるかもしれません。 autofsコンテナのエラー出力(ログ)は以下のコマンドで確認できます。

armadillo:~# podman logs autofs