実行中のコンテナ内でWireGuardの設定を編集し、うまく動いても、次のイメージ更新で消えます。設定が間違っていたわけではありません。そのファイルはコンテナの書き込み可能レイヤーにあり、そのレイヤーはそのコンテナインスタンスのためだけに存在します。重要な比較は、どのツールを使うかではなく、デプロイがどの入力を宣言しているかです。手で編集したものはすべて、デプロイが知らない入力です。

二種類の状態、片方は使い捨て

コンテナには実行時の変更のための書き込み可能レイヤーがあり、そのレイヤーはコンテナが置き換えられると破棄されます。それは設定ストアでもバックアップでもありません。イメージと宣言された入力が、実行されるものの定義のすべてです。

どのVPNファイルが宣言された入力で、どれが偶然なのかを問いかけてください:

docker diff wg-vpn
docker inspect --format '{{json .Mounts}}' wg-vpn

diffは書き込み可能レイヤーで何が変わったかを一覧にし、それはまさに消えるものの集合です。マウント一覧は残るものを示します。二つを比べれば、何かを失う前に答えが出ます。

bindマウント、名前付きボリューム、シークレット:それぞれが守るもの

三つともVPNプロファイルを保持でき、誰が読めるか、置き換え時に何が起きるかが異なります。

MechanismSurvives recreationWho can read it
Writable layerNoAnyone with container access, until it is gone
Bind mountYes, while the host path existsWhatever the host permissions allow
Named volumeYes, until the volume is removedManaged by the runtime
SecretYes, as a declared inputThe container process, by design

bindマウントはホストのパスを対応づけるので、ファイルはそのパスと同じだけ守られ、ホストの権限が許すだけ見えます。名前付きボリュームはランタイムが管理し、コンテナを削除しても残るため、デプロイが所有する状態にとってより安全な既定になります。シークレットの仕組みは、イメージや環境変数に置きたくない素材のためのものです。

すべての環境変数とホストファイルは同等の保護ではないので、そう扱わないでください。

コンテナ内での編集が罠

罠はツールではなく、編集の向きです。実行中のコンテナ内で行った変更はデプロイから見えないので、次の再作成で黙って元に戻り、症状はイメージのリグレッションのように見えます。診断のためにそこで変更する必要があるなら、すぐに外へコピーし、宣言された入力に入れてください。そのうえで再作成し、デプロイがそれを再現することを証明します。

プロファイルは秘密鍵やアカウント情報を含むことがあり、そのファイルのバックアップはファイルコピーではなく秘密情報の取り扱い作業になります。所有者と読み取り権限をコンテナの実際のプロセスに限定し、権限エラーを消すためにホストのディレクトリを広げることは避けてください。

その拡大が、コンテナ内の便利さをホストの露出に変える道です。

意図して再作成し、それから四つの点を確認する

イメージのバージョン、必要なデバイスと権限、ネットワーク接続、永続的な入力を記録してください。デバイスと権限の一覧はVPNコンテナでは特に重要です。トンネルにはネットワークデバイスとそれを設定する権限が必要だからです。

生成された実行時状態のうち、保存するのではなく再構築すべきものを確認してください。トンネルが初回起動時に生成した鍵は状態であり、それを保持するか再生成するかは、古い公開鍵を知るすべてのピアに影響する判断です。

制御された再作成の後、同一性、ルーティング、DNS、必要な障害ブロックを確認してください。エラーなく起動するプロセスは、その四つのどれも証明しません。トンネルが動いている間に確認し、停止した後にもう一度確認してください。障害ブロックはトンネルが消えたときにだけ現れるからです。

コンテナの外に復旧コピーを置く

コンテナとは独立して存在する復旧コピーを保ち、文書化された手順で復元を試してください。テストされていないVPNプロファイルのバックアップは希望にすぎません。とくに復旧の経路がコンテナのプロセスに必要な権限を含む場合はそうです。

VPNを所有するコンテナが置き換えられるなら、そのネットワークスタックを共有するアプリケーションを、ランタイムが支持するライフサイクルの中で調整してください。

その調整が、再起動と停止の違いです。デプロイは設定がどこから来るのかを記述すべきで、ボリュームの文書はランタイムが実際に何を永続化するかを確認する場所です。

関連記事