cornus setup
cornus サーバーへ接続するための接続プロファイル (「コンテキスト」) を作成して検証し、利用するシナリオに応じたセットアップ手順を表示する対話型ウィザードです。cornus config set-context のガイド付きフロントエンドであり、新しいプロファイルの意味は導入しません。
概要
cornus setup
cornus setup --scenario local # 最初のシナリオ選択を省略する説明
cornus config set-context には、複数の異なるデプロイ構成にまたがる多数のフラグがあります。代わりに cornus setup は構成するトポロジーを尋ね、そのトポロジーに必要な質問だけを行い、同じクライアント設定ファイルにコンテキストを作成します。必要に応じて接続をテストし、最後に次の手順のチェックリストと等価な set-context コマンドを示します。
実際の端末ではリッチなダイアログを表示し、後述のセットアップ手順にも書式を付けます (太字の見出し、番号付きの手順、強調されたコマンド)。パイプ、CI、--output plain、NO_COLOR の指定時には、プレーンな行単位のプロンプトと書式なしのテキストに切り替わり、エスケープシーケンスは一切出力しません (非対話での利用 を参照)。プロンプトが NDJSON を壊すため、--output json は受け付けません。スクリプトでは cornus config set-context を使ってください。
ナビゲーション
どの質問でも戻るか中止できます。
- 一つ前の手順に戻る — リッチダイアログでは
Esc⎋ またはCtrl-D、プレーンなプロンプトでは<を入力してEnter⏎ を押します。最初の質問から戻るとシナリオ選択に戻ります。前の回答を変更すると、それに依存する質問だけを再度尋ねます。すべての質問に回答するまで何も書き込まれないため、いつでも安全に戻れます。 - ウィザードを中止する —
Ctrl-C⌃C を押します。プロファイルを保存する前なら設定は変更されません。保存は最後に一度だけアトミックに行われます。
シナリオ
最初の質問では次のいずれかを選びます。
- ローカルサーバー — このマシンで動く
cornus serve(プレーン HTTP ループバック)。 - リモート Docker ホスト (SSH) — SSH トンネル越しに docker ホストへ接続します。
- リモート containerd ホスト (SSH) — SSH トンネル越しに containerd ホストへ接続します。
- リモートのデーモンなしホスト (SSH) — サーバーが OCI ランタイム (
runc/crun/youki) を自分で駆動し、デーモンをまったく使わないホストへ接続します。bareバックエンド を参照してください。 - リモート Incus ホスト (SSH) — サーバーがワークロードを Incus のアプリケーションコンテナとしてデプロイするホストへ接続します。
incusバックエンド を参照してください。 - Kubernetes (自動ポート転送) — 自動ポート転送で接続するクラスター内インストールです。ウィザードは cornus Service とポートを自動検出し、検出できなければ手動入力に切り替えます。
- Kubernetes (直接 URL) — ingress URL で接続するクラスター内インストールです。
- その他のサーバー URL — すでに URL が分かっているサーバーです。
- Docker ホスト (サーバーをコンテナで実行) — この docker ホスト上でサーバー自体をコンテナとして実行します。プロファイルは通常のループバックのものです。このシナリオが加えるのは
docker runコマンドそのものです。バインドマウントこそが難所であり、一つ間違えると何も言わずに失敗するためです。サーバーをコンテナで実行する を参照してください。
四つの SSH シナリオはまったく同じ質問を行い、同じ種類のプロファイルを作成します。トンネルはバックエンドに依存せず、異なるのは接続先にいるサーバーだからです。どれを選ぶかで決まるのは、表示されるセットアップ手順と、生成される systemd ユニットが設定する CORNUS_DEPLOY_BACKEND です。
リモート Docker ホスト (SSH) ではさらに、サーバーをそのホスト上で コンテナ として実行するかどうかを尋ねます。そうすればリモートホストにバイナリをインストールする必要はありません。「はい」と答えると手順は ssh HOST 'docker run …' の形に切り替わり、ホスト側のデータディレクトリを尋ね、systemd ユニットは提案しません。起動すべきバイナリがなく、再起動を越えるのは --restart unless-stopped だからです。トンネルと保存されるプロファイルはどちらでも同一で、違うのは接続先だけです。そのホスト上でコンテナとして を参照してください。
各シナリオで尋ねるのは必要な項目だけです (エンドポイントまたは SSH/Kubernetes の接続先、TLS、認証、任意のレジストリホスト上書き)。高度な転送オプション (mTLS、via-server、一般的な conduit/SOCKS5 モード) は cornus config set-context --help を参照してください。
プリセット
--scenario NAME を指定すると最初のシナリオ選択を省略し、そのシナリオの質問から直接始まります。名前は選択肢の並び順に local、ssh-docker、ssh-containerd、ssh-bare、ssh-incus、kube-port-forward、kube-url、url、docker-container です。未知の名前は有効な名前一覧とともに拒否されます。他の動作は変わりません。ただし戻る先のシナリオ選択がないため、最初の質問から戻るとウィザードは中止されます。
サーバーのセットアップ
ウィザードが構成するのは クライアントのプロファイル であり、サーバーをインストールしたり起動したりはしません。そのため他のどの質問よりも先に、2 番目の質問としてサーバーが存在するかどうかを尋ねます。
Is the cornus server already set up?
いいえ と答えると、選んだシナリオ向けのセットアップ手順をその場で表示してから、質問を続けます。冒頭にはその構成が要するたった一つのコマンドを 1 行の概要として示し、続けて番号付きの詳細 (前提条件、それを確認する cornus daemon preflight コマンド、cornus serve の実行方法) を示します。はい と答えると手順は表示されません。
手順を質問の 前 に出すのは、後続の質問がそのセットアップ について 尋ねるものだからです。サーバー URL、公開ポート、ホスト側データディレクトリはいずれも、手順が今説明したサーバーを記述するものです。まだ尋ねていない値については、手順はウィザード自身の既定値を示します。それはこの後に提示する既定値そのものなので、意図的に両方から外れない限り両者は一致します。
手順は一度だけ表示されます。最後のチェックリストに載るのは次に何をするかだけです。そこでセットアップ手順を繰り返せば、そのチェックリスト自身がすでにディスクへ確定させたパラメーターを持つサーバーの作り方を説明することになります。
この回答は、待ち受けていないサーバーに対しては成功しようがない 3 つの処理も抑制します。Kubernetes シナリオでの ingress の調査 (そのままではタイムアウトを 2 回待つことになります)、SSH 鍵の登録、そして 接続テスト です。いずれもサーバーが起動したあとに実行するコマンドの提示に置き換わります。
ローカルサーバー のシナリオでだけ、「いいえ」の後にもう一つ質問が続きます。
Which container runtime will this server drive?
Docker、containerd、bare、Incus、Kubernetes のいずれかです。この回答は保存されるプロファイルには一切入りません。デプロイバックエンドはサーバー側の設定であり、サーバーで CORNUS_DEPLOY_BACKEND を使って選ぶものだからです。この質問があるのは、バックエンドごとに大きく異なる実際の前提条件を手順が示せるようにするためです。bare は root に加えて OCI ランタイムと CNI プラグインを必要とし、incus は incusd 6.3+ とデーモンホストにインストールされた skopeo および umoci を必要とします。kubernetes はそのいずれも必要とせず、KUBECONFIG で到達できるクラスターだけを必要とします。他のシナリオでは、その名前自体がどのランタイムを使うかを示しているため、この質問はありません。デプロイバックエンド を参照してください。
リファレンスが「サーバー / クラスター内のみ」と記していても、ここでは Kubernetes を選べます。 その制限が当てはまるのは サーバーなしの cornus deploy であり、こちらは警告とともに dockerhost へフォールバックします。しかし cornus serve は サーバーそのもの であり、このバックエンドはクラスター内の設定から通常の KUBECONFIG / ~/.kube/config の規則へフォールバックします。そのため手元のマシンで動く cornus serve から k3s、kind、minikube、リモートのクラスターへデプロイする構成は正式に対応しています。これは上記の二つの Kubernetes シナリオ とは別のものです。あちらはクラスター 内部 で動く cornus へ接続するクライアントを構成します。
この構成特有の落とし穴があるため、手順はそれを挙げます。ビルドしたイメージをサーバーのレジストリからプルするのはクラスターのノード自身なので、ループバックアドレスはノードの役に立ちません。ノードが到達できるアドレスを CORNUS_ADVERTISE_REGISTRY に設定してください (イメージのビルド を参照)。続けて手順は代わりの構成も示します。Cornus は本来クラスター 内部 で動かすことを主眼としており、その場合レジストリは構造上ノードが到達できるサービスエンドポイントになるので、この落とし穴自体が生じないからです。そこへ至る推奨経路は Helm です。
helm install cornus oci://ghcr.io/moriyoshi/charts/cornuschart にはバージョンがあり、イメージタグも chart のバージョンに追随します。そのためこの 1 コマンドで、互いに一致するサーバーとマニフェストが手に入ります。バージョンの指定を自分で正しく行う必要はありません。raw マニフェストでも構いませんが、ブランチではなくリリースタグに固定してください。インストール と、シングルノードの k3s クラスターで一連の流れをたどる クイックスタート を参照してください。
SSH の接続先
SSH シナリオでは、接続先の質問で ~/.ssh/config に定義された Host の alias を候補として表示し、それぞれの解決先 (ops@10.0.0.5:2222) を併記します。Host * のようなワイルドカードのパターンは候補になりません。これらは接続可能な 1 台を指すのではなく、ホストの集合を設定するものだからです。接続先を直接入力する選択肢は常に最後に残ります。対象のホストが設定ファイルに載っていないこともあるためです。読み取れる設定ファイルがない場合や、利用できる alias が一つも定義されていない場合、この質問は通常の自由入力のプロンプトになります。
SSH ホストと直接 URL のシナリオでは、認証方法を SSH 鍵、静的トークン、なし の 3 つから選びます。SSH 鍵の登録はプロファイルの保存後にだけ実行されるため、この手順を中止したり失敗したりしてもプロファイルは失われません。SSH ホストのシナリオでは、設定済みの SSH 転送経路を通じてリモートホスト上の cornus auth enrollment-code を最初に実行します。それ以外の場合は、サーバーホストで取得したコードの入力を求めます。
二つの Kubernetes シナリオでは、ウィザードがサーバーから通知された ingress (/.cornus/v1/info) も調べ、SOCKS5 conduit 経由でワークロードの ingress ホストに到達するかを提案します。サーバーが ingress controller を通知していれば native (検出した ingress controller へのトンネル)、ingress ドメインだけを公開していれば emulate (生成した証明書を使うクライアント側リバースプロキシ)、それ以外では off が既定候補です。選択はプロファイルの conduit.ingress ブロックに書き込まれ、socks5 conduit を選択します。イングレス を参照してください。
検証
保存後、ウィザードは接続テストを提案します。実際のコマンドとまったく同じようにプロファイルを解決し (ポート転送も含む)、サーバーの /.cornus/v1/info エンドポイントを呼び出します。結果を到達可能、認証が必要、接続拒否、TLS の問題、タイムアウトなどに分類して、対処のヒントを示します。検証に失敗してもコマンドは失敗せず、プロファイルはいずれの場合も保存されたままです。サーバーがまだセットアップされていないと答えた場合は、必ず失敗するため接続テスト自体が提案されません。
生成物
セットアップの生成物は最後の質問のあと、プロファイルを保存する 前 に提案します。そうすることで、事後ではなくサーバーをセットアップしている最中に手に入ります。これらは手順のコマンドをファイルの形にしたもので、回答から組み立てられます。だからこそ質問のあとに来るのであり、手順のほうは先に来ます。SSH シナリオでは、リモートホスト用の cornus.service systemd ユニットを作成することを提案します。Kubernetes シナリオでは、cornus-values.yaml Helm values スニペットを提案します。ローカルのデーモンなし サーバーにも同じユニットを提案します。bare では cornus 自身がワークロードの監督者であり、シェルから起動したサーバーは終了した瞬間にすべてのワークロードの再起動ポリシーの適用をやめてしまうからです。他のローカルバックエンドは監督をデーモンに任せているため、何も提案しません。いずれも書き込む前に確認し (ファイルへ書き込み、標準出力へ表示、スキップ)、既存ファイルを上書きする場合は確認します。
コンテナインストールのシナリオは、意図的に 何もファイルを作成しません。この構成に必要なのは Docker だけなので、手順には回答 (ホスト側のデータディレクトリとポート) を埋め込んだ docker run コマンドをそのまま表示します。使うために Compose が必要な Compose ファイルや、信頼する前に読まなければならないシェルスクリプトを配るのではありません。
systemd ユニットにはシナリオの CORNUS_DEPLOY_BACKEND が入り、そのバックエンドの前提条件がコメントとして書かれます。containerd と bare では root と /opt/cni/bin、bare ではランタイムの上書き、incus ではソケットとプロジェクトの上書きに加えて skopeo / umoci の要件です。これらをコメントに書くのは、いずれの前提条件もユニットの起動時には失敗しないからです。それらを欠いたユニットは一見正常に動いているように見え、原因から何層も離れたところでデプロイが失敗して初めて分かります。
非対話での利用
TTY ではない stdin ではエラーにせず、スクリプトからの入力に対してプレーンな行単位のプロンプトを実行します。そのためヒアドキュメントからウィザードを操作できます。
printf '1\n\n\n\n\n\n' | cornus --output plain setup # local シナリオ、すべて既定値
printf '\n\n\n\n\n' | cornus --output plain setup --scenario local # 同じ内容 (シナリオ選択の回答なし)すべてのプロンプトは既定値を表示します。EOF になると 保存せずに 中止します。途中で切れた、または誤ったスクリプトでも、気付かないうちに誤ったプロファイルを作成する代わりに中止されます。本格的な自動化には、決定的な cornus config set-context を直接使ってください。
config set-context との関係
ウィザードは cornus config と同じクライアント設定ファイルに書き込み、作成したプロファイルと等価な cornus config set-context … コマンドをガイダンスに表示します (bearer token は伏せ字にします)。ウィザードでできることはすべて set-context で非対話的に実行できます。ウィザードはガイド付きの経路とサーバー側のセットアップ手順を提供するだけです。
関連項目: cornus config、接続設定、リモートクラスターの利用。