11/Documentation
crewコマンド
1つのURLの背後にある複数マシンのCollie: invite、join、deputy、フェイルオーバー
crewは1つのleadのもとでCollieを実行する複数のマシンで構成され、スマートフォンはleadの単一のURL経由ですべてのマシンのherdにアクセスします。leadはスマートフォンがアクセスするマシンであり、その他のすべてのマシンはmemberです。deputyは引き継ぎを許可された唯一のmemberです。
| コマンド | 説明 | |
|---|---|---|
collie crew invite | 1回限り有効な10分間の登録トークンを発行する(lead 上で実行) | |
collie crew add <ssh-host> | 独自の SSH 経由でピアをインストールして登録する(lead 上で実行) | |
| `collie crew update <member>… \ | --all` | すべてのマシン、リード、各ピアの順に独自の SSH経由で1台ずつ事前チェックします。最初の失敗で実行を停止します (詳細) |
collie crew status | モード、member、到達可能性、シークレットの取得、リンクが拒否される理由 | |
collie crew rotate | crewシークレットを再発行し、到達可能なすべてのピアに配布する | |
collie crew rename <name> | crewに新しい名前を付ける(lead 上で実行) | |
collie crew remove <member> | メンバーの pin を解除して登録情報を削除する(lead 上で実行) | |
collie crew set-address <member> <host:port> | この lead がメンバーに接続する際のアドレスを修正する | |
collie crew deputy <member> | 引き継ぎを許可するピアを1台だけ指定して準備状態にする。--revoke を指定すると指定を解除する | |
collie crew approve-promote <member> | lead上での特定のmemberへの引き継ぎの承諾(有効期限10分、1回のみ有効。--cancelで消去) | |
collie crew join <lead-address> [<token>] | crewに参加する(参加するマシン上で実行)。トークンがない場合は入力を求められます。標準入力の場合は-、または@fileを指定します | |
collie crew leave | crewから離脱します。crewシークレットおよびこのマシン上の他のすべてのmemberの固定証明書を破棄します | |
collie promote | このマシンを lead に昇格させる(引き継ぎ先のピアで実行。lead が失われている場合は --force) | |
collie reconnect | メンバーの移動時: 再登録を行わずに新しいアドレスへ接続先を変更する |
collie join と collie leave は引き続き機能します。これらは collie crew join と collie crew leave のエイリアスであり、同じ引数と終了コードを使用します。
この表にあるすべての動詞について、collie packも引き続き動作します。これはcollie crewのエイリアスであり、同じ引数と終了コードを持ちます。collie docs packはこのページを出力し、Webアプリの/packアドレスは/crewへリダイレクトされます。これら3つはすべて2.0.0(ADR 0038)で廃止されます。
deputy、approve-promote、promote の各コマンドはフェイルオーバーを管理します。設定と復旧の手順については、docs/deployment.md → スタンバイへの移行 および 障害発生時の対応 を参照してください。
2台のマシン、1つのcrew
マシンの追加には2つのコマンドがあり、Herdr用とCollie用に1つずつ用意されています。crew addがSSH接続できないホストや、平文HTTPを提供するリード向けの手動手順も用意されています。
herdr machine add --label <name> <ssh-target> # prepare the remote host
collie crew add <ssh-host> # install Collie there and enroll itherdr machine addは手元のマシン上で実行します。リモートホストにHerdrを配置してHerdr独自の一覧に保存しますが、マシンをcrewには追加しません。collie crew addはlead上で実行します。<ssh-target>と<ssh-host>は同一のホストであり、user@hostまたは~/.ssh/configのHostエイリアスとして指定します。<name>はHerdrの一覧用のラベル付けにすぎません。
collie crew add <ssh-host>は既存のssh経由でリモートホストにCollieをインストールし、登録を行います。ローカルでトークンを生成し、リモートマシンにCollieをプロビジョニングして、そこでcollie crew joinを実行します。herdr machine addによって配置されるリモートホストに Herdr が事前インストールされていることが必要となるため、これら2つのコマンドは対で使用します。平文HTTPを提供するleadでは、crew addが--insecureをサポートしていないため、追加の手動手順が1つ必要です(参加するマシン上でcollie crew join --insecureを実行)。特定のホストに対しては、crew addまたは手動手順のいずれか一方のみを使用し、両方は実行しないでください。ターゲットを指定しないcollie crew addは、ssh configとHerdrがすでに認識しているホストを、各名前が解決されるホストごとに統合して一覧表示します。そのため、ホストを別の方法で再入力する(以下)のではなく、その一覧から選択してください。
crew addは自身のインストール種別に応じたルートを取ります。Herdrプラグインのインストールのようにgitチェックアウトから実行されているリードは、自身のコミットをメンバーにプッシュしてそこでビルドするため、そのメンバーにはgitとBunが必要です。スタンドアロンインストールまたはパッケージからのリードにはコミットがないため、自身が実行しているリリースからメンバーをインストールし、同じSSH経由でCollie自身のインストーラーを送信します。そのため、メンバーには代わりにcurl、tar、およびsha256sumまたはshasumが必要です。--pathは最初のルートではリモートチェックアウトを、2番目のルートではインストールルートを指定します。別の種類のインストールをすでに実行しているメンバーは、上書きされずに拒否されます。拒否メッセージには解決するための1つのコマンドが示されます。2番目のルートでは、メンバー自身がgithub.comからリリースをダウンロードするため、github.comへのルートがないメンバーには、チェックアウトから実行されているリードが必要です。
ターミナルのcollie crew updateも同じ2つのルートを取り、同じ条件を読み取ってどちらかを選択します。チェックアウトのリードは各メンバーに自身のコミットをプッシュし、スタンドアロンインストールまたはパッケージからのリードは、各メンバーを自身が実行しているリリースと同じバージョンに揃えます。リリースリードの場合、gitチェックアウトから実行されているメンバーはスキップされ、該当行に対処するためのコマンド(そのマシン上でのcollie update --to-tag v<version>)が表示されます。チェックアウトリードの場合、install.shによってインストールされたメンバーは逆向きにスキップされます。リリースを受け取る仕様であるため、スマートフォンのUpdatesページでバージョンを揃えます。スキップされたメンバーによって実行が停止することはなく、確認画面で分けてカウントされます。
手動手順は4つのコマンドで構成されます。SSHで到達できないホストや、平文HTTPを提供するリードに対して使用してください。リードのインストール種別を理由に使用するものではありません。どの種類のリードでもcrew addでメンバーを追加できます。リードはスマートフォンがすでにアクセスできているインスタンスであり、参加するマシンにはCollieがインストールされ実行されている必要があります。
- lead上でトークンを発行します。
collie crew invite # prints the token, then the join command to runトークンは1行です:
<token>.<lead-fingerprint>。
- 参加するマシン上でcrewに参加し、要求されたらトークンを貼り付けます。
collie crew join https://lead.tail1234.ts.netinviteの出力からアドレスをコピーしてください。この例ではなく、自身の lead のアドレスを使います。
- 実行中のプロセスが新しいmemberを認識できるよう、lead上で再起動します。
collie restart
- lead上でリンクが応答したことを確認します。
collie crew status # the new member, its address, and whether the link answered
トークンは1回のみ有効で、有効期限は10分間、表示は1回限りです。leadはハッシュのみを保存します。inviteを実行すると、leadプロセスが再起動して受信した登録を受け入れられるようになり、lead名を含む参加用コマンド行が出力されます。
ステップ3は2回目の再起動であり、joinの終了時にその旨が表示されます。inviteは登録を受け入れるためにleadを再起動しました。その後joinが新しいmemberをディスクに書き込みましたが、実行中のプロセスは再度再起動されるまでそのmemberへのトラフィックをプロキシしません。
インタラクティブターミナルでは、joinがトークンの入力を求めます。スクリプトでは-を渡し、標準入力からトークンを指定します。
collie crew join https://lead.tail1234.ts.net - # paste the token on stdinディスクからトークンを読み取る場合は、代わりに@<file>を渡します。生のトークンを引数として直接渡すと警告が出力されます。プロセス一覧によって引数がすべてのローカルユーザーに公開されるためです(CREW_PROTOCOL.md §8.3)。
lead のアドレスには、このノードから到達可能な任意のホスト名または host:port を設定します。スキームとポートのないアドレスは、Collie 自身のリスナーがバインドするポートである https://<host>:8787 として解決されます。
crew invite が出力する内容は、lead の公開方法によって異なります。デフォルトの HTTPS モードでは、lead はループバックでリッスンし、tailscale serve がポート 443 で公開します。そのため、invite はポート 443 に接続する https://<full-tailnet-name> を出力します。COLLIE_SERVE_PORT で公開ポートを変更した場合、<name>:<port> を出力します。COLLIE_SERVE_MODE=http を使用すると、lead 自身のリスナーが平文 HTTP でポート 8787 に応答し、invite は短い名前を出力します(ポートを変更した場合のみポート番号が含まれます)。join は平文 HTTP でトークンを送信する前に一度確認を求め、--insecure はこれを自動で確認します。明示的な http:// アドレスには引き続き --insecure が必要で、確認は求められません。
crew add は member に同じエントリーポイントを渡すため、member もポート 443 に接続します。名前のみを指定するとポート 8787 を意味しますが、tailscale serve の背後にある lead はこれを tailnet に開放しません。
crew join における --address は、lead がこのマシンに接続するためのアドレスであり、ポート(--address <host>:8787)が必要です。ポートがない場合、lead がポート 443 への接続を試みるため、join はこれを受け付けません。https://host:8787 アドレスは引き続き受け付けられ、host:8787 として保存されます。
マルチプレクサの選択は各ノードでローカルに行われます。 そのノード自身の.env内でCOLLIE_MUXを設定します。バイナリインストールの場合は~/.config/collie/.env、Herdrインストールの場合はHerdrのプラグイン設定ディレクトリです。マシン間の通信路であるcrewプロトコルには、マルチプレクサ固有のフィールドは含まれません。なお、v1(CREW_PROTOCOL.md §16)においてピアの動作確認が行われているのはHerdrのみです。
crew addは新しいメンバーのこの値を確定します。メンバー自身では常に確定できるとは限らないためです。実行中のマルチプレクサが1つだけの場合、そのメンバーはそのまま保持され、初回の自己起動時にそれが選択されます。複数実行されている場合、リードがユーザーに確認を求め、回答がそのメンバーの.envにCOLLIE_MUXとして書き込まれます。すでにマルチプレクサを1つ指定しているメンバーもそのまま保持されます。事前に入力する場合や、メンバーが保持している既存の名前を置き換える場合は、--mux <name>を渡してください。マルチプレクサが実行されていないメンバーには警告が表示され、何も書き込まれません。いずれかが実行されるまで初回の起動が拒否されるためです。
Herdrのマシンとcrew
Herdrの保存済みマシンとCollie crewは独立した2つのリストであり、互いに同期しません。
マシンを追加するには、上記の2台のマシン、1つのcrewを参照してください。
HerdrのマシンリストはHerdrウィンドウに属します。Herdr 0.9.0は保存されたSSHターゲットをクライアント側に保持し、使用するたびにSSH経由で各マシンを開きます。操作中のマシン上のそのウィンドウ内に、対象マシンのターミナルが表示されます。
crewとは、すべてのマシンにCollieが存在する構成であり、leadは既存のsshを利用したインストール時に1度セットアップされたCollie独自の暗号化リンク経由で各memberにアクセスします。crewはターミナルも表示し、ターミナル以外のデータも伝送します。アップロードファイルを転送し、各マシンのジャーナルと監査ログを該当ペインを実行したマシン上に保持します。スマートフォンからの1回の確認ですべてのcrewを更新します。leadの応答が途絶えた際には、エントリポイントをdeputyに引き渡すことができます。マシン一覧を一切持たないtmuxやzellijの下でも同様に動作します。
| 項目 | Herdrのマシンリスト | Collie crew |
|---|---|---|
| 接続元 | Herdrクライアント | lead Collie |
| 通信経路 | 利用ごとのssh | Collie独自の暗号化リンク |
| 表示内容 | ターミナル | ターミナル、アップロード、ジャーナル、監査ログ、アップデート、フェイルオーバー |
| 表示場所 | Herdrウィンドウ | スマートフォン |
| tmuxおよびzellijに対応 | 不可 | 可 |
これら2つの一覧が分離されている背景には3つの事実があり、それぞれが独立した理由となっています。
スマートフォンがssh鍵を保持することはありません。ssh鍵はマシンへの完全なシェルアクセスを意味し、スマートフォンは紛失する可能性があるためです。代わりにスマートフォンはleadが発行したペアリングコードを保持します。これはアプリを開く以外の権限を持たず、collie devices revoke <label>を実行すれば再起動なしで即座にそのコードを無効化できます(デバイスのペアリング)。
アップロードファイル、ジャーナル、監査ログは、ペインを実行するマシン上に配置されます。また、Collieにおけるマシン間の暗号化回線であるcrewリンクは、memberの登録完了後はsshを必要としません。
そのため、二重の設定は発生しません。一度SSHを設定すれば、両方のツールで利用できます。Herdrはそのウィンドウ専用にリストを保持し、Collieはスマートフォン向けにcrewを保持します。Herdrにマシンを追加してもcrewには追加されず、Herdrから削除してもcrewからは削除されません。tmuxやzellijを実行しているcrewメンバーがHerdrのリストに表示されることもありません。
ターゲットを指定しないcollie crew addは両方のリストから候補を提示するため、ホストを2度入力する必要がありません。~/.ssh/config内のHostエントリを読み取り、herdr machine list --jsonを実行します。各名前が解決されるsshターゲット上で2つのリストをマージします。このコマンドはその設定内のIncludeを1階層のみ、かつ~/.ssh/配下のパスに限り追跡します。インクルードされたファイルからさらにインクルードされたファイル内のエイリアスは提示しません。各行には、名前の由来(ssh config、herdr、またはその両方)が表示されます。すでにこのcrewに存在するマシンの行には、番号の代わりにそのメンバーのidが表示されます。
crewの接続構造
エントリポイントを公開するのはleadのみであり、crew内の他のすべてのマシンはエントリポイントを公開しません。
leadは管理されたエントリポイントであり、PWAを提供します。スマートフォンは/api/*上のHTTPS経由でleadにアクセスし、それ以外の対象とは通信しません。leadは/crew/v1/*上で、crewシークレットを運ぶ固定された相互TLS経由で各memberにアクセスします。memberはエントリポイントを持たない完全なCollieであり、独自のエージェント、ジャーナル、アップロードファイル、監査ログを保持します。管理は完全にCLIを通じて行われ、Herdr UIの操作はありません。通信仕様自体はCREW_PROTOCOL.mdで規定されています。
コードは既存のsshを経由してすべてのマシンに配信されます。crew addはその方法でmemberをインストールし、crew updateは状態を同期します。crewリンクはランタイムデータを伝送するものであり、配布経路になることはありません。
deputyは、leadがあらかじめ指定したピアです。3つのルートを持つスタンバイドアをバインドしますが、そのドアが公開されることはありません。leadからの応答が途絶えると作動し、ユーザー自身のペアリング認証情報を使って消費されるため、leadの不在時にもスマートフォンからdeputyにアクセスできます。
install.sh以外でインストールされたメンバー
crewは、他者が所有するファイルを持つメンバーを除き、スマートフォンからすべてのメンバーをアップデートします。
collie crew updateとスマートフォンのワンタップcrewアップデートは、どちらも古いリリースの横に新しいリリースをステージングして切り替えます。これはインストールスクリプトとHerdrが作成する2つのインストール環境で機能しますが、すべてのインストールで機能するわけではないため、crewはそれらを失敗させるのではなくレポートします。
パッケージ管理されているメンバーはパッケージマネージャーの実行を待機します。 pacman、nix、またはbrewがファイルを配置した場合、そのマネージャーがファイルを所有するため、Collieは自身が所有していないファイルを置換しません(パッケージ管理されたインストール)。crewはアップデートを送信せず、プレフィックスのコマンドが特定できる場合はそれを付けて「パッケージマネージャーを待機中」と表示し、そのメンバーを除外して実行を完了とみなします。そのマシンで該当コマンドを実行するとレベルが一致し、次のチェックで行が消去されます。
パッケージ化されたLEADも、引き続き各memberのバージョンを揃えます。 リードは同じ理由で自身の移行を拒否します。拒否の理由はこれだけです。スマートフォンとcollie crew updateは、両方ともすべてのメンバーをリードが現在実行しているバージョンに揃え、1回の確認ですべてを処理します。パッケージマネージャーがリードを更新し、その上でcollie restartを実行した後は、自動では更新されません。スマートフォンのUpdatesページでもう一度確認すると、メンバーがリードの新しいバージョンに更新されます。
ソースのチェックアウトは、同じくチェックアウトを持つリード配下の完全なメンバーです。 自身でクローンしてビルドしたメンバーは、チェックアウトリードからのクルー更新を受け取ります。そのリードは、自身の更新時とまったく同様に、コミットをプッシュし、リビルドして再起動します。コミットを持たないリード配下では、collie crew updateはそのメンバーをスキップし、そのマシンで実行すべきコマンドとしてcollie update --to-tag v<version>を提示します。
したがって、混在したcrewも通常のcrewです。1回のタップでleadがアップデート可能なすべてのメンバーを更新し、アップデートできないメンバーを一覧表示します。パッケージマネージャーを実行すれば、crewのバージョンは再び揃います。
crew名
crew名は表示用のデータであり、leadのみが表示します。collie crew invite --name "the shed"は作成時にcrewの名前を設定し、--nameなしで作成されたcrewは「collie crew」と呼ばれます。後から変更するには、leadでcollie crew rename <name>を実行します。この動詞はlead自身のcrew-trust.json内の名前を書き換えてブリッジを再起動するため、collie crew statusおよびスマートフォンのcrewページに新しい名前が即座に反映されます。
メンバーへは何も送信されません。名前は登録に対するリードの応答時に一度だけ渡され、メンバーはそれを表示することなく保存します。名前変更後に参加したマシンは新しい名前を受け取り、すでにcrew内にいるメンバーは誰も読み取らないフィールドに古い文字列を保持し続けます。名前は両端の空白が除去され、最大64文字で、制御文字を含みません。ピア上、またはcrewに属していないマシン上で実行した場合、このコマンドは拒否され、どこで実行すべきかを表示します。
1.7.0または1.8.xから1.9.0へのアップデート
leadを1.9.0に更新する前に、すべてのmemberを1.8.xにアップデートしてください。 1.9.0は crew リンクの特定のバージョンを1つだけ使用し、これに対応する最も古いビルドは1.8.0です。
該当するリリースを記憶しておく必要はありません。1.8.0以降では、次のリリースでcrew linkに変更が入る場合、帯域表示、Updatesカード、および日次の通知でアップデート予告が表示されます。そこでも同じ指示、すなわち「leadを先にアップデートし、メンバーはその後」と案内されます。
1.8.0ではマシンが読み取る名前が変更されます。通信経路、2つの環境変数、3つのステートファイル、およびジャーナルのプレフィックスがすべてcrew(ADR 0039)表記になります。リンクの動作は以前とまったく同一であり、スクリプト側で同日に移行しなければならないものはありません。
1.8.0では1.7.0のmemberを1リリース限定でサポートしましたが、1.9.0ではサポートしません。 1.8.0のleadは古いパスにも応答したため、1.7.0のままのmemberも追従できました。ADR 0039の決定どおり、1.9.0でこの動作は削除されました。
1.9.0のlead配下に1.7.0のmemberが残っている場合、2か所に表示され、いずれもエラーが明示されます。 leadの事前チェックでversionの検証が不合格(red)となり、両方のバージョンと実行すべきコマンドが示されます。不合格の時点で、完了できないローリングアップデートを開始せずに crew のアップデートがブロックされます。collie crew statusでは、同じmemberが理由の末尾に「this build speaks 2」を付けてincompatibleと表示されます。
そのmemberのマシン上でアップデートを実行してください。 1.9.0のleadはリンク経由でそのmemberに接続できなくなっています。その端末上でcollie updateを実行して1.8.x以降にアップデートしてください。次回のポーリング時にleadが再検出します。
新しい名前
| 1.7.0 | 1.8.0 | マシン上での動作 |
|---|---|---|
COLLIE_PACK_TIMEOUT_MS | COLLIE_CREW_TIMEOUT_MS | 1.9.0で削除されました。1.9.0のビルドは crew キーのみを読み取るため、名前を変更していない古いキーはデフォルトの予算が適用されます |
COLLIE_PACK_HELLO_TIMEOUT_MS | COLLIE_CREW_HELLO_TIMEOUT_MS | 同上 |
pack-trust.json、pack-ops.json、pack-runtime.json | crew-trust.json、crew-ops.json、crew-runtime.json | 1.8.x(~/.local/state/collie/)で一度リネームされ、1.9.0で削除されました。1.8.xを経由していないディレクトリは起動時に名前が付けられ、collieは単独で動作し続けます |
[pack] | [crew] | crew自体のジャーナル行のプレフィックス |
/pack/v1/… | /crew/v1/… | leadとmember間のリンクにあるすべてのパス。1.9.0で削除されました |
PACK_PROTOCOL.md | CREW_PROTOCOL.md | 通信プロトコル規約そのもの |
1.9.0に移行する前に、各自の.envで2つの環境変数のキー名を変更してください。1.9.0ビルドは古いキーを読み取らず、警告も出しません。
アップデートをまたぐジャーナルでは、両方のプレフィックスをgrepしてください:
journalctl --user -u collie | grep -E '\[(crew|pack)\]'アップデート前に書き込まれた行には[pack]、アップデート後の行には[crew]と表示されます。crew全体が1.8.0になったら、[crew]のみでフィルタリングしてください。