Skip to content

クラスター上のリモート開発環境

シナリオ

軽量なノート PC で開発しているものの、コードには強力なマシンが必要だとします。大規模なビルド、GPU、冷却ファンを全開にするデータベースなどです。ファイルは自分のエディターでローカルに編集しながら、コードはクラスター上でリモートに実行し、ワークロードのポートには localhost で到達でき、普段の Docker / Dev Container ツールもそのまま使いたい場合に適しています。Cornus はリモートサーバーをローカルに感じさせます。接続プロファイルがエンドポイントの設定を省き、クライアントローカルバインドマウントが作業ツリーを 9P でストリームするため、コピーなしで編集内容が同期され、公開ポートは自動的に自分のマシンへ転送されます。

使用するもの

手順

1. クラスターをプロファイルとして保存します。 すべてのコマンドで --server やトークンが不要になります。イングレスのないクラスター内 cornus ではサービスを指定し、CLI がコマンドごとにそこへポート転送します。

sh
cornus config set-context devbox \
  --pf-namespace cornus --pf-service cornus --pf-remote-port 5000 \
  --kube-auth-service-account cornus-client --kube-auth-audience cornus
cornus config use-context devbox

URL を持つサーバーでは代わりに --server https://cornus.example.com --token "$(cat token.jwt)" を使います。--kube-auth-* フラグは自身の Kubernetes へのアクセス権から短命トークンを発行するため、静的シークレットを管理する必要がありません。リモートクラスターを参照してください。

2. 環境を Compose プロジェクトとして記述します。 volumes: 下のバインドマウントは自分のノート PC 上のパスです。ports:localhost で到達したいポートです。

yaml
name: devbox

services:
  app:
    build: .                      # Cornus エンジンでビルドし、レジストリへプッシュ
    command: ["npm", "run", "dev"]
    working_dir: /workspace
    volumes:
      - ./:/workspace             # クライアントローカル: 9P でストリームし、編集を即時同期
    ports:
      - "3000:3000"               # 開発サーバー。127.0.0.1:3000 で到達可能
    environment:
      NODE_ENV: development
    depends_on:
      - db

  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: dev
    volumes:
      - pgdata:/var/lib/postgresql/data
    ports:
      - "5432:5432"

volumes:
  pgdata:                         # 名前付き: up/down をまたいで共有、永続化

3. フォアグラウンドで起動します。 サーバーで必要なものをビルドし、依存関係順にデプロイして、バインドマウントを 9P で維持し、30005432127.0.0.1 へ自動転送し、ログをストリームします。

sh
cornus compose up --build

4. ローカルで編集し、リモートで実行します。 エディターはノート PC の ./src/... に書き込み、app コンテナは 9P マウントを通じて変更を確認し、開発サーバーが再読み込みします。http://localhost:3000 を開くと、要求はワークロード Pod へトンネルされます (クラスタープロファイルでは kubeconfig を使って Pod へ直接接続し、それ以外ではサーバーを経由します)。psql -h 127.0.0.1 -p 5432 も同じ方法でリモートデータベースへ到達します。Ctrl-C を押すと、up が起動したものを削除します。

5. 公開されていないポートにも、仕様を編集せず必要に応じて到達します。

sh
cornus port-forward app 9229:9229     # 例: デバッガーポート

仕組み

各要素が組み合わさることで、開発ループは変わりません。接続プロファイルは、エンドポイント、認証、ここではクラスター内ポート転送の対象を持つ CLI 側の kubeconfig 形式ファイルです。そのため、どの cornus compose 実行でもコマンドラインの指定なしにサーバーを解決します。クライアントローカルバインドマウントがローカル編集の鍵です。ホストパスを持つ Compose の volumes: エントリーは自分のマシンから 9P でストリームされ、セッションの存続期間、サーバー自身のマウント領域から提供されます。ワークロードはファイルをその場で読み取ります。事前コピーも rsync も不要で、ホスト権限ポリシーを緩めずに常にマウントを許可できます。公開ポートは Kubernetes バックエンドでも 127.0.0.1:<host> へ自動転送されるため、リモートワークロードは docker compose と同じようにローカルで応答します。三つは実行中のフォアグラウンド up に結び付いています。切り離した up -d はマウントと転送をバックグラウンドクライアントエージェントに渡します (cornus daemon status で確認できます)。詳しくはリモートクラスターで作業するワークロードをデプロイするのレシピを参照してください。

バリエーション

Compose ファイルの代わりに Dev Container を使う。 リポジトリに .devcontainer/devcontainer.json があれば、cornus compose は手書きの Compose ファイルなしでネイティブに読み取ります。ライフサイクルフック (initializeCommand はホストで、postCreate / postStart / postAttach はコンテナ内で実行) を実行し、プロジェクトを workspaceFolder に 9P でバインドマウントします。

sh
cornus compose --devcontainer . up

VS Code または Zed でリモートサーバー上の Dev Container を開く。 クライアント側の Docker Engine API プロキシを実行し、DOCKER_HOST をそれに向けます。通常の dockerdocker compose、公式 devcontainers CLI、エディターの Dev Container 対応はすべてリモートの Cornus 上でコンテナを実行し、ローカルのバインドマウントディレクトリは 9P でストリームされます。

sh
cornus daemon docker -d
export DOCKER_HOST="unix://$XDG_RUNTIME_DIR/cornus-docker.sock"
devcontainer up --workspace-folder .      # 公式 CLI。リモートで実行

プロキシは Docker の正確なプロトコル (create/start、attach、wait、ライフサイクルイベントストリーム) を扱うため、VS Code の Dev Containers 拡張機能のエンジンである公式 @devcontainers/cli が変更なしに操作できます。同じシェルからエディターを起動して DOCKER_HOST を継承させ、通常の Dev Container の手順を使えば、コンテナはリモートで実行されます。

  • VS Code — Dev Containers 拡張機能をインストールし、code . を実行して Dev Containers: Reopen in Container を選びます。
  • Zedzed . を実行してプロジェクトの Dev Container を開きます。Zed は同じ Docker エンドポイントを通じて起動します。

プロキシは Docker の /build エンドポイントをエミュレートしません (ビルドは cornus buildの役割です)。そのため、事前にビルドした image:devcontainer.json で参照し、build: / dockerFile: は使わないでください。Dockerfile 由来なら先に cornus build -t <registry>/devcontainer:latest . でビルドしてください。

一つのプロキシでサービス名を使ってすべてのサービスに到達する。 プロファイルのコンジットを SOCKS5 に設定すると、単一のスプリットトンネルプロキシが appdb、その他のサービスに名前で到達し、それ以外のトラフィックは直接エグレスします。

sh
cornus config set-context devbox --merge --conduit-mode socks5

関連項目: リモートクラスター · Compose、devcontainers、docker CLI · 接続設定 · クックブック

Released under the Apache-2.0 License.