ブラウザで動く Kubernetes—その実装の選択
2026年6月に ngrok の開発者により発表された webernetes は、Kubernetes の機能をブラウザ上で再現する野心的なプロジェクトです。(出典)
驚くべきは、そのコンパクトさです。約100,000行のコードを552コミット、629ファイルに分けて、わずか2ヶ月で実装されています。最終的なサイズは140KB(gzip圧縮) に収まっており、この軽量性が実装戦略を大きく左右していることがわかります。
webernetes はブラウザで実行できる完全な環境をめざしたのではなく、Kubernetes の主要な概念と動作をブラウザに持ち込むことに注力している。
まず注目すべきは、WebAssembly による Kubernetes のコンパイルは採用されなかった という点です。出典記事では、「Hello, world! の Go プログラムを WebAssembly にコンパイルするだけで約540KB(gzip圧縮)になる」と明記されています。
すべての Kubernetes を WebAssembly に落とせば、メガバイト単位でのダウンロードが必要になり、ブラウザアプリケーションとしての実用性が失われます。さらに Kubernetes はシステムレベルの API を呼び出す箇所が多く、ブラウザの制限により単純なコンパイルでは動作不可能です。
この制約から、開発者は TypeScript による部分的な再実装 という道を選びました。結果として、Pod のライフサイクル管理、クラスター DNS、ネットワーク管理、コンテナガベージコレクション、IP アロケーション、Deployment・ReplicaSet の追跡など、Kubernetes の本質的な機能群をブラウザで実現できています。
コンテナイメージ—ブラウザ向けの新しいアプローチ
wbernetes では、Docker Hub のような従来のレジストリからイメージを引っ張るのではなく、ブラウザネイティブのレジストリと TypeScript API を用いてイメージを定義します。
import * as w8s from "@ngrok/webernetes";
class HelloWorld extends w8s.BaseImage {
static readonly imageName = "hello-world";
static readonly imageVersion = "1.0";
async exec(ctx: w8s.ProcessContext, argv: string[]): Promise<number> {
ctx.listenHttp(8080, async (_ctx, request) => {
return {
status: 200,
body: "Hello, world!",
};
});
return await ctx.waitUntilKilled();
}
}
コンテナを Deployment として実行するのは、標準的な Kubernetes YAML と変わりません。
const cluster = new w8s.Cluster();
await cluster.registerImage(HelloWorld);
const [pod] = await cluster.apply([
{
apiVersion: "apps/v1",
kind: "Deployment",
metadata: { name: "hello-world-deployment" },
spec: {
replicas: 1,
selector: {
matchLabels: { app: "hello-world-pod" },
},
template: {
metadata: {
labels: { app: "hello-world-pod" },
},
spec: {
containers: [
{
name: "hello-world-container",
image: "hello-world:1.0",
},
],
},
},
},
},
]);
ブラウザ内でコンテナを動かすために、実際のイメージレジストリは必要ない。代わり TypeScript で直接定義できるイメージモデルが、Kubernetes の複雑さを削ぎ落とし、学習用途に最適化している。
このアプローチは、エンジニアの個人プロジェクトでも十分実装可能です。実際に Claude Code のようなコーディングアシスタントに TypeScript API の仕様を投げれば、基本的なコンテナ定義はすぐに生成できそうな予感がします。
クラスター操作と相互通信の可視化
wbernetes はプログラマティックな API を提供し、Pod の列挙、イベント監視、Pod 間の通信傍受が可能です。
// Pod 一覧の取得
const pods = await cluster.api.corev1.listNamespacedPod({
namespace: "default",
});
// Pod の変更を監視
const informer = cluster.informer("pods", (type, pod) => {
console.log(`pod ${type}: ${pod.metadata?.name}`);
});
// Pod 間の HTTP リクエスト・レスポンスを監視
cluster.on("request", (event) => {
console.log(`request: ${event.request.method} ${event.request.url}`);
});
cluster.on("response", (event) => {
console.log(`response: ${event.response?.status}`);
});
// Pod への直接的なネットワークリクエスト送信
const pod = pods.items[0];
const resp = await cluster.fetch(`http://${pod.status?.podIP}:8080/`);
console.log(resp.body); // "Hello, world!"
デモでは、複数 Node にまたがる Pod 間の通信を「青い点」で可視化しており、Kubernetes のネットワークトポロジーが直感的に理解できるようになっています。これは Kubernetes を学ぶエンジニアにとって、抽象的な概念を「見える化」する強力な手段になるでしょう。
プロダクション環境では当然のこと、webernetes は本番利用を想定していません。むしろ、インタラクティブなコンテンツ制作やデモンストレーション、教育目的での活用が明示的なユースケースです。しかし、その軽量性と拡張性を考えると、ブラウザベースの開発環境やシミュレーションプラットフォームの基盤として、今後思わぬ派生プロジェクトが生まれるのではないでしょうか。
既存の Dockerfile 関連の取り組みとの位置づけ
このような「ブラウザでコンテナ」という試みは、最近の開発環境の変化を反映しています。Vercel が 2026年に発表した「Dockerfile.vercel」機能では、従来のコンテナ実行環境をサーバーレスで簡素化する動きが進んでいます。(参考)一方、webernetes はその逆を行く──クラウドで動かすコンテナをあえてクライアントサイドに持ち込むことで、クライアントサイドの学習・検証環境を豊かにする というアプローチです。
同様に、Microsoft が WSL(Windows Subsystem for Linux)に Linux コンテナ実行機能を統合したように、(参考)OS レイヤーでのコンテナサポートが拡大している時代背景があります。webernetes はそこから一歩進んで、ブラウザというユニバーサルプラットフォーム でコンテナの概念そのものを実行可能にした点が新規性です。