Ubuntu Weekly Recipe

第649回 Ubuntu Coreの独自イメージを作成する

この記事を読むのに必要な時間:およそ 6 分

model assertionファイルの作成

GPG鍵を作成できたので,次にイメージの作成に必要なmodel assertionを作成します。これは作成されたイメージが,誰によって作られ,どのようなデバイスのためのもので,どのようなsnapファイルがインストールされているかなどを記述した署名済みのファイルです。

署名そのものはsnapコマンドで行えますので,まずは元データとなるJSONファイルをpc.jsonという名前で作成しましょう。

{
  "type": "model",
  "authority-id": "account-idの文字列",
  "brand-id": "account-idの文字列",
  "series": "16",
  "model": "pc",
  "architecture": "amd64",
  "base": "core18",
  "gadget": "pc=18",
  "kernel": "pc-kernel=18",
  "timestamp": "2021-01-08T10:54:39+00:00"
}

変更する必要がある部分のみを説明します。

  • authority-id/brand-id:Snap Storeから取得したaccount-idの文字列をそのまま記述してください。
  • model:モデル名を示す任意の文字列です。ファイル名と一緒にしておくとわかりやすいです。
  • architecture:ターゲットのCPUアーキテクチャー名です。PC向けなら「amd64⁠⁠,Raspberry Pi向けなら「arm64」⁠armhf」のいずれかになるでしょう。
  • base:ベースとなるsnapファイルです。Ubuntu Core 18ならcore18で,将来的にリリースされるUbuntu Core 20ならcore20になります。
  • gadget:gadget snapとしてインストールするsnapパッケージ名です。
  • kernel:kernel snapとしてインストールするsnapパッケージ名です。
  • timestamp:date -Iseconds --utcで生成したタイムスタンプです。GPG鍵の登録日時よりも後ろである必要があります。

gadget snapとkernel snapについて補足しておきます。これらはターゲットデバイス依存のsnapパッケージであるため,どのデバイス向けに作るかで指定方法が変わります。公式でサポートしているデバイスの場合,次のような関係になります。

  • KVM/NUC向け:gadgetはpcで,kenrelはpc-kernel
  • Raspberry Pi向け:gadgetはpiで,kernelはpi-kernel

さらにsnapパッケージはパッケージ名の後ろに=channnelのような指定が可能です。PC向けならcore18にはpi=18pi-kernel=18が正式リリースとなります。将来的にcore20がリリースされたら,baseの変更に合わせてpc=20などを指定することになります。

Raspberry Pi向けには18-pi418-pi3などターゲットごとにチャンネルが用意されているようなので,上記のリンク先のバージョン番号のところにあるプルダウンメニューを参照してください。

また「required-snaps」フィールドを追加すると,追加でsnapパッケージをインストール可能です。ここで指定するsnapパッケージはSnap Storeにあるものだけでなく,ローカルディレクトリにあるsnapパッケージも対象になります。Storeにないパッケージをバンドルしたい際に使えるでしょう。なお,required-snapsでインストールしたsnapパッケージは,イメージをインストール後に削除はできなくなるため注意してください。後述のイメージ作成時にも追加のsnapを指定できるので,⁠削除されたくないsnapパッケージ」以外にこのフィールドを利用することはないでしょう。

作成したJSONファイルを署名します。

$ cat pc.json | snap sign -k default &> pc.model

$ cat pc.model
type: model
authority-id: <account-id>
series: 16
(以下略)

「default」snapcraft list-keysの鍵名です。環境に応じてGPG鍵のパスフレーズを問い合わせる画面が出るでしょう。なお,状況によって署名がうまくいかず,次のような内容がpc.modelに記録されてしまうこともあるようです。

error: cannot sign assertion: cannot sign using GPG: /usr/bin/gpg
(中略)
署名に失敗しました: そのようなファイルやディレクトリはありません
(後略)

原因は不明ですが,次のようにgpgコマンドからGPG鍵のディレクトリを指定することで,解消するようです。

$ gpg --homedir ~/.snap/gnupg --detach-sig pc.json

これを実行したあとにもう一度snap signを実行すれば成功しているはずです。うまくmodel assertionが生成されなかったら試してみてください。

ちなみにUbuntu WikiのUbuntuCoreの開発ページには,Ubuntuが公式にリリースしているイメージファイルのリストが表示されています。このページにリストアップされているsnap known ...なコマンドを利用するとイメージごとのアサーションファイルを表示できます。設定に困ったらまずは公式イメージのアサーションを参考にすると良いでしょう。

カスタムイメージの作成

ようやくカスタムイメージを作成するための必要なファイルを準備できました。次にイメージの作成手順に移りましょう。

イメージの作成そのものは,UbuntuのLiveインストーラーの作成でも使われている「ubuntu-image」を利用します。まずはこのコマンドをインストールしておきましょう。

$ sudo snap install ubuntu-image --classic

では実際にイメージを作成します。

$ mkdir pc
$ sudo ubuntu-image snap -O pc pc.model

$ ls -1 pc/
pc.img
seed.manifest
snaps.manifest

イメージの作成はsnapパッケージのダウンロードに時間がかかる程度でほぼすぐに終わる印象です。作られたファイルのうち「pc.img」がイメージファイルです。manifestのほうは利用されたsnapパッケージのリビジョン番号などが記載されています。

このコマンド実行時に--disable-console-confを指定すると,console-confが無効化されます。つまり初回起動時や再起動後にコンソールにログインプロンプトが表示されて,パスワードログインが可能になります。

-c チャンネルでsnapパッケージインストール時に使用する標準のチャンネル名を指定できます。betaやedgeのパッケージをインストールしたい際に利用します。--snap パッケージ名で追加でsnapパッケージをインストールします。パッケージ名=チャンネル名のような指定も可能です。ローカルにあるsnapファイルも指定できます。

他にもいろいろなオプションがあるので,一度ubuntu-image snap --helpを参照しておくと良いでしょう。

作成したイメージは,公式のKVMイメージと同じ方法で起動できます。

$ cp pc/pc.img{,.bak}
$ kvm -smp 2 -m 1500 -netdev user,id=mynet0,hostfwd=tcp::8022-:22 \
  -device virtio-net-pci,netdev=mynet0 -nographic \
  -drive file=pc/pc.img,format=raw

今回は設定がほぼ同じなので,同じように初回セットアップが動きます。

これで独自イメージを作成する手順を確立できました。これの手順を把握しておけば,特定のsnapパッケージをインストール済みのカスタムイメージを簡単に構築できるというわけです。

たとえば第641回のLXDとmicrok8sでシングルサーバーをKubernetesクラスターにするで紹介したように,microk8sは簡単にKubernetesのクラスターを構築できるツールです。ubuntu-image snapのオプションとして--snap microk8s=classicを追加すれば,microk8sインストール済みのイメージとなります。このイメージを複数台のRaspberry Piにインストールすることで,microk8sインストール済みのRaspberry Piたちができあがります。もっと細かいセットアップをしたいのであれば,--cloud-initでCloud-Initのファイルを渡すという手もあります。

ぜひ各自で好みのsnapパッケージをバンドルした、カスタムイメージを作ってみてください。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。