← 返回信息流
AI 资讯Hacker News·3 小时前

Kubernetes被成功移植到浏览器中运行

原标题:I ported Kubernetes to the browser

速览

一名开发者利用WebAssembly等技术,将Kubernetes的核心功能移植到了浏览器环境中。用户现在可以直接在浏览器中创建和管理Kubernetes集群,无需本地安装任何软件。这一移植展示了WebAssembly在系统级应用上的强大能力,为云原生技术的教学和轻量级部署提供了新思路。该项目已在GitHub上开源,引发了技术社区的关注。

AI 深度解读

背景

Kubernetes 作为云原生时代的操作系统,其复杂性让无数开发者望而生畏。传统的学习路径需要搭建真实的集群环境,配置网络、存储、计算资源,门槛颇高。与此同时,Web 技术在过去十年取得了长足进步,浏览器的计算能力早已今非昔比,能够承载越来越复杂的计算任务。

在这样的背景下,ngrok 工程师 Simon Rose 萌生了一个大胆的想法:能否将 Kubernetes 的核心逻辑移植到浏览器中,让开发者无需任何本地配置,就能在网页上直观地观察 Pod 调度、服务发现、网络请求等核心机制是如何运作的?

核心内容

2026 年 6 月 30 日,Simon Rose 发布了 webernetes——一个用 TypeScript 编写的 Kubernetes 部分移植版本,使得在浏览器中运行完整的 Kubernetes 集群成为可能。该项目历时 2 个月,累计 552 次提交,生成近 10 万行代码,分布在 629 个文件中。

浏览器里的真实集群

webernetes 的演示页面展示了一个完全在浏览器中运行的 Kubernetes 集群。它并非玩具模拟器,而是真实地执行着许多与生产集群相同的工作:Pod 生命周期管理、集群 DNS 和服务网络、容器垃圾回收、IP 地址分配、Deployment 和 ReplicaSet 的状态跟踪等。演示中蓝色圆点代表 Pod 之间相互发送 HTTP 请求,直观地展现了服务间通信。

为什么不编译到 WebAssembly?

面对"是否将 Kubernetes 编译为 WebAssembly"的疑问,答案是否定的。一个简单的 Go 语言"hello, world!"程序编译为 WebAssembly 后,gzip 压缩体积约为 540KiB,而整个 webernetes 项目 gzip 后仅约 140KiB。如果完整编译 Kubernetes,传输体积将达到兆字节级别。此外,Kubernetes 依赖大量浏览器中不可用的系统级 API,存在编译时错误。

架构组成

webernetes 由以下几个核心部分构成:

  • kubelet 的部分移植:足以运行 Pod 并对其进行健康探测
  • 多个控制器移植:包括 Pod 调度器、命名空间控制器、kube-proxy、Deployment 控制器等
  • 浏览器端 CNI 实现:使 Pod 能够通过模拟网络相互通信
  • 浏览器端容器运行时:kubelet 通过 CRI(容器运行时接口)与之交互来运行容器
  • 集群交互 API:用于应用 manifest、监听资源变更等操作

镜像定义方式

由于追求轻量化,webernetes 不从 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();
  }
}

部署到集群时,使用标准的 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",
            },
          ],
        },
      },
    },
  },
]);

集群交互 API 支持列出 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 之间的请求和响应
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!"

项目定位与未来计划

webernetes 明确其定位是用于制作交互式 Kubernetes 教学内容,而非生产就绪的 Kubernetes 发行版。它不需要运行真实镜像,只需要让内容创作者能够搭建特定的工作负载来演示他们想要讲解的知识点。

目前该项目尚不支持 ConfigMaps、Secrets、Pod 资源限制、持久卷等功能。作者表示,随着使用库制作更多内容,将逐步实现所需功能。

LLM 编写代码的质量保证

webernetes 几乎所有代码都由 LLM 生成。作者预见到外界会对项目质量产生质疑,甚至可能被指责为"slop-

查看原文 →ngrok.com