← シリーズに戻る

コンテナと A/B: 2面で置き換える

Part 4 / 6 Raspberry Pi デプロイ5方式を7軸比較

ここまでの3方式は、どれも変わったものだけを配っていました。ファイルを置く、アーカイブを展開する、パッケージを入れ替える。粒度は違いますが、機械の上には更新されなかった部分がそのまま残ります。

この章で扱う2つは、その前提を捨てます。動くもの一式を丸ごと置き換える。

7軸の評価が両端に振り切ります。ロールバックは5方式で最強で、機械が単独で前の面に戻ります。常駐コストと帯域は5方式で最低で、設定を1行変えるために領域ぶんを転送して再起動します。共通課題に当てると過剰ですが、現地に人が行けないという条件が1つ入るだけで評価が反転します。

この方式の検証状態: 実機では動かしていません。A/B 方式については RAUC の公式ドキュメントで確認した内容です(末尾に URL)。この方式だけは機材が足りず、パーティションを切り直せる機械がもう1台必要です。

2つの粒度

丸ごと置き換えると言っても、範囲が2段階あります。

置き換える範囲再起動追加で要る領域
コンテナ型アプリと依存ライブラリ不要(コンテナの作り直しのみ)イメージの保管分
A/B パーティション型システム領域まるごと必要もう1面ぶん

コンテナ型は、レジストリに新しいイメージを置き、機械側でそれを取得してコンテナを作り直します。カーネルやブートローダーには触りません。取得の向きは pull 型と同じで、定期的にレジストリを見に行く道具を常駐させる形が一般的です。

A/B パーティション型は組み込みの世界の標準解です。同じものが入る領域を2面持ち、更新は動いていないほうに書きます。

A/B の動き方

RAUC の公式ドキュメントで確認できる範囲で、流れはこうです。

  1. いま動いている領域を判定し、動いていない領域だけを書き込み先に選ぶ
  2. 更新の中身を検証してから、その領域に書く
  3. 書き終えたら、次回起動でそちらを使うようブートローダーに指示する
  4. 再起動する
  5. 起動が成功したことを明示的に記録する
  6. 記録されないまま問題が起きたら、ブートローダーが前の領域に戻す

5 が肝です。「起動した」と「正しく動いている」は別なので、アプリケーションが正常に立ち上がったことを自分で申告させる設計になっていて、申告が来なければ機械は誰の指示も待たずに前の面へ帰ります。ハードウェアのウォッチドッグを併用すると、固まった状態も検出できます。

A/B パーティションの更新が機械の中で進む順序。動いていない面に書き、ブートローダーに次回起動を指示して再起動し、アプリが正常起動を自分で申告する。申告が来なければブートローダーが前の面へ戻す

配る側との通信は一切要りません。ネットワークが切れていようが、機械は単独で復帰します。push 型で手続きとして書いていたロールバックが、ここでは機械の性質になっています。

もう1つ、RAUC は署名を必須にしています。「バンドルに署名することは必須である」と設計判断として明記されており、署名なしの更新を流し込む経路がありません。パッケージ型と同じく、経路ではなく中身を信じる型です。

何を買っているのか

ロールバックの軸だけを見ると圧勝に見えますし、実際現地に人が行けない機械ではこれ以外の選択肢が事実上ありません。壁の中の機械、遠隔地の機械、顧客先に納めた機械。文鎮化が許されない状況では、A/B の2面ぶんの領域は保険料として安く付きます。

代償は3つあります。

常駐コストが5方式で最大です。更新エージェントが常駐し、ブートローダー側にも状態を持たせ、そのうえで起動成功の申告を出す仕組みをアプリケーション本体に組み込むことになるので、「入れて終わり」の道具ではありません。

帯域も最大です。設定ファイル1行の変更で、システム領域ぶんが転送されます。差分更新の仕組みを持つ実装もありますが、基本は全体です。

再起動が要ります。数秒であっても、動いている機械を止めることになります。24時間動き続ける前提のものだと、これが制約になります。

コンテナ型の位置

A/B とファイル配布の中間にいます。

再起動が要らず、A/B ほどの領域も要りません。イメージという単位で丸ごと置き換わるので、「機械の上でだけ壊れる」種類の事故が減ります。手元で動いたイメージが、そのまま機械の上でも動く。

ただしロールバックは A/B ほど強くありません。前のイメージに戻すこと自体は簡単ですが、問題は戻す判断を誰がするかで、新しいコンテナが起動してしばらく動いてから壊れた場合、健全性の確認と自動復帰を自分で組み込んでいなければ、結局は push 型と同じ「手続きとして書く」領域へ戻ります。

そしてコンテナランタイムという常駐物が1つ増えます。設定ファイルを配りたいだけの機械に、そのために Docker を入れる判断は、素直とは言いにくいところです。

7軸で見ると

A/B パーティション型で書きます。コンテナ型はこの表と pull 型の中間だと考えてください。

評価補足
到達性機械側から取りに行く形にできます
常駐コスト5方式で最大。エージェント・ブートローダー連携・起動申告
権限の粒度更新エージェントは強い権限を持ちます
ロールバック5方式で最強。機械が単独で前の面に戻ります
帯域領域ぶん転送。設定1行でも同じ
改ざん耐性署名が必須の実装があります
観測性起動成功の申告があるぶん、pull 型より状態が分かります

両端に振り切った表になります。ロールバックと改ざん耐性で最高、常駐コストと帯域で最低。

このシリーズの共通課題(設定ファイル数十 KB を1台に、週数回)に当てると、明らかに過剰です。数十 KB のために数百 MB を転送し、再起動することになります。

ただし条件を1つ動かすだけで評価が反転します。現地に人が行けない。この条件が入った瞬間にロールバックの◎以外はすべて誤差になり、文鎮化した機械を直しに行く交通費と2面ぶんのストレージの値段を並べて比べる、という話に変わります。

次の章では、ここまで4方式で何度も出てきた署名の話を、まとめて扱います。

参考

  • RAUC — Basic Concepts — 非アクティブ領域への書き込み、ブートローダーとの分担、起動成功の記録とフォールバック、署名必須の設計判断