メインコンテンツにスキップ ナビゲーションにスキップ フッターにスキップ

Rediaccのルール

Rediaccプラットフォームでアプリケーションを構築するための基本ルールと規則。Rediaccfile、compose、ネットワーク、ストレージ、CRIU、デプロイについて説明します。

Rediaccのルール

すべてのRediaccリポジトリは、独自のDockerデーモン、暗号化されたLUKSボリューム、専用のIP範囲を持つ分離された環境内で動作します。これらのルールにより、このアーキテクチャ内でアプリケーションが正しく動作することが保証されます。

Rediaccfile

  • すべてのリポジトリにはRediaccfileが必要です — ライフサイクル関数を持つbashスクリプトです。
  • ライフサイクル関数: up()down()。オプション: info()
  • up() はサービスを開始します。down() はサービスを停止します。
  • info() はステータス情報を提供します(コンテナの状態、最近のログ、ヘルス)。
  • Rediaccfileはrenetによってsourceされます — 環境変数だけでなく、シェル変数にもアクセスできます。

Rediaccfileで利用可能な環境変数

変数説明
REDIACC_WORKING_DIR/mnt/rediacc/mounts/abc123/マウントされたリポジトリのルートパス
REDIACC_NETWORK_ID6336ネットワーク分離識別子
REDIACC_REPOSITORYabc123-...リポジトリGUID
{SVCNAME}_IPHEARTBEAT_IP=127.0.24.195サービスごとのループバックIP(サービス名は大文字)

最小限のRediaccfile

#!/bin/bash

_compose() {
  renet compose -- "$@"
}

up() {
  _compose up -d
}

down() {
  _compose down
}

Compose

  • renet composeを使用し、docker composeは絶対に使わないでください — renetはネットワーク分離、ホストネットワーキング、ループバックIP、サービスラベルを注入します。
  • composeファイルでnetwork_modeを設定しないでください — renetはすべてのサービスにnetwork_mode: hostを強制します。設定した値は上書きされます。
  • rediacc.*ラベルを設定しないでください — renetはrediacc.network_idrediacc.service_iprediacc.service_nameを自動注入します。
  • ports:マッピングは無視されます(ホストネットワーキングモード)。80以外のポートへのプロキシルーティングにはrediacc.service_portラベルを使用してください。
  • 再起動ポリシー(restart: alwayson-failureなど)は安全に使用できます — renetはCRIU互換性のために自動的にこれらを削除します。ルーターウォッチドッグは.rediacc.jsonに保存された元のポリシーに基づいて停止したコンテナを自動回復します。
  • 危険な設定はデフォルトでブロックされますprivileged: truepid: hostipc: host、およびシステムパスへのバインドマウントは拒否されます。自己責任でオーバーライドするには renet compose --unsafe を使用してください。

コンテナ内の環境変数

Renetはすべてのコンテナに以下を自動注入します:

変数説明
SERVICE_IPこのコンテナの専用ループバックIP
REDIACC_NETWORK_IDネットワーク分離ID

サービスの命名とルーティング

  • The compose service name becomes the auto-route URL prefix.
  • Grand repos: https://{service}.{repo}.{machine}.{baseDomain}(例: https://myapp.marketing.server-1.example.com)。
  • Fork repos: https://{service}-{tag}.{machine}.{baseDomain} — uses the machine wildcard cert to avoid Let’s Encrypt rate limits.
  • カスタムドメインには Traefik ラベルを使用してください(注意: カスタムドメインは fork との互換性がありません — ドメインは grand repo に属します)。

ネットワーク

  • 各リポジトリは独自のDockerデーモンを持ちます/var/run/rediacc/docker-<networkId>.sock)。
  • 各サービスは/26サブネット内でユニークなループバックIPを取得します(例: 127.0.24.192/26)。
  • SERVICE_IPにバインドしてください — 各サービスはユニークなループバックIPを取得します。
  • ヘルスチェックは${SERVICE_IP}を使用する必要がありますlocalhostではありません。例: healthcheck: test: ["CMD", "curl", "-f", "http://${SERVICE_IP}:8080/health"]
  • サービス間通信: ループバックIPまたはSERVICE_IP環境変数を使用してください。DockerのDNS名はホストモードでは動作しません。
  • リポジトリ間のポート競合は不可能です — 各リポジトリは独自のDockerデーモンとIP範囲を持っています。
  • TCP/UDPポートフォワーディング: 非HTTPポートを公開するためにラベルを追加します:
    labels:
      - "rediacc.tcp_ports=5432,3306"
      - "rediacc.udp_ports=53"

ストレージ

  • すべてのDockerデータは暗号化されたリポジトリ内に保存されます — Dockerのdata-rootはLUKSボリューム内の{mount}/.rediacc/docker/dataにあります。名前付きボリューム、イメージ、コンテナレイヤーはすべて暗号化され、バックアップされ、自動的にフォークされます。
  • ${REDIACC_WORKING_DIR}/...へのバインドマウントは明確さのために推奨されますが、名前付きボリュームも安全に使用できます。
    volumes:
      - ${REDIACC_WORKING_DIR}/data:/data        # バインドマウント(推奨)
      - pgdata:/var/lib/postgresql/data      # 名前付きボリューム(こちらも安全)
  • LUKSボリュームは/mnt/rediacc/mounts/<guid>/にマウントされます。
  • BTRFSスナップショットは、すべてのバインドマウントデータを含むLUKSバッキングファイル全体をキャプチャします。
  • データストアはシステムディスク上の固定サイズのBTRFSプールファイルです。rdc machine query <name> --systemで実際の空き容量を確認できます。rdc datastore resizeで拡張できます。

CRIU(ライブマイグレーション)

  • ラベルによるオプトイン: チェックポイントしたいコンテナにrediacc.checkpoint=trueを追加します。このラベルのないコンテナ(データベース、キャッシュ)はフレッシュスタートし、独自のメカニズム(WAL、LDF、AOF)で回復します。
  • backup push --checkpoint はラベル付きコンテナの実行中プロセスメモリ + ディスク状態をキャプチャします。
  • repo fork --checkpoint はfork前にプロセス状態をキャプチャします — forkはrepo up時に自動復元します。
  • repo down --checkpoint は停止前にプロセス状態を保存します — 次のrepo upで自動復元します。
  • repo up はチェックポイントデータを自動検出し、見つかった場合は復元します。フレッシュスタートには--skip-checkpointを使用してください。
  • 依存関係を考慮した復元: composeのdepends_onを使用してデータベースを先に起動(healthyを待機)し、その後アプリコンテナをCRIU復元します。
  • TCP接続は復元後に無効になります — アプリケーションはECONNRESETを処理して再接続する必要があります。
  • Docker実験モードはリポジトリごとのデーモンで自動的に有効になります。
  • CRIUはインストールされます rdc config machine setupの実行時に。
  • /etc/criu/runc.conf はTCP接続保持のためにtcp-establishedで設定されます。
  • コンテナのセキュリティ設定はラベル付きコンテナに自動注入されますrenet composerediacc.checkpoint=trueを持つコンテナに以下を追加します:
    • cap_add: CHECKPOINT_RESTORE, SYS_PTRACE, NET_ADMIN(カーネル5.9+でのCRIU最小セット)
    • security_opt: apparmor=unconfined(CRIUのAppArmorサポートはまだ上流で安定していません)
    • userns_mode: host(CRIUは/proc/pid/map_filesのためにinitネームスペースアクセスが必要)
  • ラベルのないコンテナはよりクリーンなセキュリティ姿勢で実行されます(追加のcapabilitiesなし)。
  • Dockerのデフォルトseccompプロファイルは保持されます — CRIUはPTRACE_O_SUSPEND_SECCOMP(カーネル4.3+)を使用してcheckpoint/restore中にフィルターを一時的に停止します。
  • CRIU capabilitiesをcomposeファイルに手動で設定しないでください — renetがラベルに基づいて処理します。
  • CRIU互換のリファレンス実装についてはheartbeatテンプレートを参照してください。

CRIU互換のアプリケーションパターン

  • すべての永続接続(データベースプール、WebSocket、メッセージキュー)でECONNRESETを処理してください。
  • 自動再接続をサポートするコネクションプールライブラリを使用してください。
  • 内部ライブラリオブジェクトからの失効ソケットエラーに対するセーフティネットとしてprocess.on("uncaughtException")を追加してください。
  • 再起動ポリシーはrenetによって自動管理されます(CRIUのために削除され、ウォッチドッグが回復を処理します)。
  • Docker DNSに依存しないでください — サービス間通信にはループバックIPを使用してください。

セキュリティ

  • LUKS暗号化は標準リポジトリに必須です。各リポジトリは独自の暗号化キーを持っています。
  • 認証情報はCLI設定に保存されます~/.config/rediacc/rediacc.json)。設定を失うと暗号化ボリュームへのアクセスを失います。
  • 認証情報を絶対にバージョン管理にコミットしないでくださいenv_fileを使用し、up()でシークレットを生成してください。
  • リポジトリの分離: 各リポジトリのDockerデーモン、ネットワーク、ストレージは同じマシン上の他のリポジトリから完全に分離されています。
  • エージェント分離: AIエージェントはデフォルトでfork-onlyモードで動作します。各リポジトリはサーバーサイドのサンドボックス強制(sandbox-gateway ForceCommand)付きの独自のSSHキーを持ちます。すべての接続はLandlock LSM、OverlayFS homeオーバーレイ、リポジトリごとのTMPDIRでサンドボックス化されます。リポジトリ間のファイルシステムアクセスはカーネルによってブロックされます。

デプロイ

  • rdc repo up はすべてのRediaccfileでup()を実行します。
  • rdc repo up --mount はまずLUKSボリュームを開き、次にライフサイクルを実行します。新しいマシンへのbackup push後に必要です。
  • rdc repo downdown()を実行してDockerデーモンを停止します。
  • rdc repo down --unmount はLUKSボリュームも閉じます(暗号化ストレージをロックします)。
  • フォークrdc repo fork)は新しいGUIDとnetworkIdを持つCoW(コピーオンライト)クローンを作成します。フォークは親の暗号化キーを共有します。
  • テイクオーバーrdc repo takeover <fork> -m <machine>)はgrandリポジトリのデータをフォークのデータで置き換えます。grandはその識別情報(GUID、networkId、ドメイン、自動起動、バックアップチェーン)を保持します。古い本番データはバックアップフォークとして保存されます。使用例: フォークでアップグレードをテストし、確認後に本番にテイクオーバー。rdc repo takeover <backup-fork> -m <machine>で元に戻せます。
  • プロキシルートはデプロイ後約3秒で有効になります。repo up中の「Proxy is not running」警告はops/dev環境では情報提供目的です。

よくある間違い

  • renet composeの代わりにdocker composeを使用する — コンテナがネットワーク分離を取得できません。
  • 再起動ポリシーは安全です — renetが自動的に削除し、ウォッチドッグが回復を処理します。
  • privileged: true を使用する — 不要です。renetが代わりに特定のCRIUケーパビリティを注入します。
  • SERVICE_IPにバインドしない — リポジトリ間のポート競合を引き起こします。
  • IPをハードコードする — SERVICE_IP環境変数を使用してください。IPはnetworkIdごとに動的に割り当てられます。
  • backup push後の初回デプロイで--mountを忘れる — LUKSボリュームは明示的に開く必要があります。
  • 失敗したコマンドの回避策としてrdc term -cを使用する — 代わりにバグを報告してください。
  • repo deleteはループバックIPとsystemdユニットを含む完全なクリーンアップを実行します。古い削除の残骸をクリーンアップするにはrdc machine prune <name>を実行してください。