psviderski/uncloud
GitHub: psviderski/uncloud
一个轻量级的去中心化容器编排工具,在 Docker 和 Kubernetes 之间找到平衡点,让开发者无需运维负担即可跨多台服务器部署应用。
Stars: 4794 | Forks: 134
Uncloud 是一个轻量级的集群和容器编排工具,可让你在云虚拟机和裸机服务器上以最小的集群管理开销部署和管理 Web 应用。它在你的 Docker 主机之间创建安全的 WireGuard mesh 网络,并提供自动服务发现、负载均衡、带有 HTTPS 的 ingress,以及简单的 CLI 命令来管理你的应用。
与传统的编排器不同,Uncloud 没有需要维护的中央控制平面和仲裁机制。每台机器通过点对点 (P2P) 通信维护集群状态的同步副本,即使部分机器离线也能保持集群操作正常运行。
Uncloud 专为那些希望拥有自托管基础设施的灵活性,但又不想承担 Kubernetes 运维复杂性的开发者打造。
## ✨ 功能特性
* **随处部署**:将云虚拟机、独立服务器和裸机整合为一个统一的计算环境,不受地理位置或服务商限制。
* **Docker Compose**:使用熟悉的 [Docker Compose](https://compose-spec.io/) 格式定义服务和卷。无需学习新的定制 DSL。
* **零停机部署**:执行滚动更新而不中断服务。故障自动回滚功能即将推出。
* **[Unregistry](https://github.com/psviderski/unregistry) 集成**:直接将 Docker 镜像构建并推送到你的机器,无需外部镜像仓库。它仅传输缺失的层 (layer),快速且高效。
* **服务发现**:内置 DNS 服务器将服务名解析为容器 IP。
* **持久化存储**:使用跨机器管理的 Docker 卷运行有状态服务。
* **零配置私有网络**:自动 WireGuard mesh 网络,具备节点发现和 NAT 穿透功能。容器获得唯一 IP 以实现跨机器直接通信。
* **无控制平面**:完全去中心化的设计消除了单点故障,降低了运维负担。
* **命令式优于声明式**:采用命令式操作而非状态协调,简化了心智模型和故障排查过程。
* **托管 DNS**:通过托管的 [Uncloud DNS](https://github.com/psviderski/uncloud-dns) 服务,为具有公共访问权限的服务自动生成 `*.xxxxxx.uncld.dev` DNS 记录。
* **自动 HTTPS**:内置 Caddy 反向代理使用 Let's Encrypt 处理 TLS 证书的自动配置和续期。
* **类 Docker CLI**:使用熟悉的命令管理基础设施和应用程序。
* **远程管理**:通过 SSH 访问集群中的任意一台机器,即可控制你的整个基础设施。
## 🎬 快速演示
下面的截图展示了如何使用 Uncloud 从本地机器上的 [`compose.yaml`](website/compose.yaml) 文件将 https://uncloud.run 网站部署到 2 台远程机器。
它将容器端口 `8000/tcp` 以域名 `uncloud.run` 通过 HTTPS 暴露,由远程机器上的 Caddy 反向代理提供服务。全权由 Uncloud 管理。

这是一个更高级的用例。只需几分钟,即可在多个区域和本地环境中部署一个具有自动 HTTPS 功能的高可用 Web 应用。
## 💫 为什么选择 Uncloud? 像 Heroku 和 Render 这样的现代云平台提供了极佳的开发者体验,但价格昂贵。像 Kubernetes 这样的传统容器编排器虽然功能强大且灵活,但需要相当高的运维专业知识。我相信这中间存在一个最佳平衡点——一种为大多数未达到 Google 规模的用户提供的务实解决方案。你应该能够: * **拥有你的基础设施和数据**:无论是出于成本、合规性还是灵活性的考虑,你都可以在云虚拟机和个人硬件的任意组合上运行应用程序,同时掌控数据并保持你喜爱的云般体验。 * **在成长中保持简单**:从单台机器开始,随时按需添加更多机器,无需改变工作流程。无需担心高可用控制平面或复杂的 YAML 配置。 * **基于成熟的原语构建**:开箱即用的生产级网络、部署原语、服务发现、负载均衡和 HTTPS ingress,无需成为分布式系统专家。 * **支持可持续计算** 🌿:最小化系统开销,最大化应用程序可用资源。 Uncloud 的目标是让容器化应用的部署和管理像使用云平台一样无缝,无论你运行的是 5 美元的 VPS、闲置的 Mac mini,还是一整架裸机服务器。 ## 🚀 快速开始 1. 安装 Uncloud CLI: brew install psviderski/tap/uncloud # 或者使用 curl (macOS/Linux) curl -fsS https://get.uncloud.run/install.sh | sh 更多选项请参见 [安装说明](https://uncloud.run/docs/getting-started/install-cli)。 2. 初始化你的第一台机器: uc machine init root@your-server-ip 3. 从 Docker 镜像部署你的应用,并使用 `app.example.com` 域名将其容器端口 8000 以 HTTPS 发布: uc run -p app.example.com:8000/https image/my-app 4. 在你的 DNS 服务商(Cloudflare, Namecheap 等)处创建一条 DNS A 记录,将 `app.example.com` 指向你的服务器 IP 地址。请等待几分钟以便 DNS 传播。 完成!你的应用现已运行并可访问 https://app.example.com ✨ 5. 完成后进行清理: uc ls # 从输出中复制服务名称并运行 rm 命令: uc rm my-app-name 如果你想在机器上完全卸载 Uncloud,请运行: uncloud-uninstall 更多信息请查看 [文档](https://uncloud.run/docs)。 ## ⚙️ 工作原理 查看 [设计文档](misc/design.md) 以了解 Uncloud 的设计理念和目标。 下图展示了一个由 3 台机器组成的 Uncloud 多提供商集群: 
## 🧪 交互式教程
为了让你无需离开浏览器即可体验 Uncloud,我们在 [iximiuz Labs](https://labs.iximiuz.com/) 平台上提供了交互式教程和实验环境。
可用教程:
1. [搭建一个新的 Uncloud 集群](https://labs.iximiuz.com/tutorials/uncloud-create-cluster-ebebf72b) - 该教程将引导你创建一个包含两台机器的集群,然后在其中部署一个简单的 Web 服务。
你也可以启动 [Uncloud 实验环境](https://labs.iximiuz.com/playgrounds/uncloud-cluster-64523f7c),在其中体验一个已初始化的 Uncloud 集群。
## 🏗 项目状态
Uncloud 目前处于活跃开发阶段,**尚未准备好用于生产环境**。功能可能会发生重大变化,版本之间可能存在破坏性更新。
我们很乐意听取你的意见!你可以通过以下方式做出贡献:
* 🐛 发现 Bug?[提交 Issue](https://github.com/psviderski/uncloud/issues)
* 💡 有问题、想法或需要帮助?
* 在 [Discussions](https://github.com/psviderski/uncloud/discussions) 中发起讨论或加入现有讨论。
* 加入我们的 [Discord 社区](https://discord.gg/eR35KQJhPu),我们在那里讨论功能、路线图、实现细节并互相帮助。
## 🙏 灵感与致谢
我要感谢以下项目,它们启发了 Uncloud 的设计和实现:
* [Kamal](https://kamal-deploy.org/) — 证明了即使在 Kubernetes 的声明式时代,仍然有空间给那些使用命令式操作且无复杂编排的简单部署工具。Kamal 支撑着其创造者价值数十亿美元的公司 [37signals](https://37signals.com/),这真的非常鼓舞人心!
* [Fly.io](https://fly.io/) — 启发了我对自托管基础设施应有体验的愿景,证明了开发者体验与强大的基础设施可以完美共存。
* [Tailscale](https://tailscale.com/) — 开创了去中心化扁平 mesh 网络的愿景,其如魔法般神奇的用户体验令人惊叹。
* [Talos Linux](https://github.com/siderolabs/talos)
和 [KubeSpan](https://www.talos.dev/v1.10/talos-guides/network/kubespan/) — 感谢其使用 [grpc-proxy](https://github.com/siderolabs/grpc-proxy) 的机器 API 设计,以及其优雅的零配置安全 WireGuard overlay 网络方案。
* [Docker Swarm Classic](https://github.com/docker-archive/classicswarm) 和
[Rancher 1.x](http://rancher-com-website-main-elb-elb-1798790864.us-west-2.elb.amazonaws.com/docs/rancher/v1.6/en/)
— 展示了容器编排中简单和务实的力量,证明并非所有问题都需要 Kubernetes 那样的复杂性。
特别感谢 Fly.io 的 [Corrosion](https://github.com/superfly/corrosion) 项目,提供了用于共享 Uncloud 集群状态的分布式 SQLite 数据库。
## 📫 保持更新
* 加入我们的 [Discord 服务器](https://discord.gg/eR35KQJhPu) 进行实时讨论、获取支持和更新。
* 在 X/Twitter 上关注 [@psviderski](https://x.com/psviderski)。
* 订阅 [我的简报](https://uncloud.run/#subscribe) 了解进度,获取新功能的早期见解,并在准备好投入生产时第一时间获知。
* 关注本仓库以获取发布通知。
## ❤️ 贡献者
感谢 [@cedws](https://github.com/cedws) 成为 Uncloud 的首位贡献者! 🎉
## 💫 为什么选择 Uncloud? 像 Heroku 和 Render 这样的现代云平台提供了极佳的开发者体验,但价格昂贵。像 Kubernetes 这样的传统容器编排器虽然功能强大且灵活,但需要相当高的运维专业知识。我相信这中间存在一个最佳平衡点——一种为大多数未达到 Google 规模的用户提供的务实解决方案。你应该能够: * **拥有你的基础设施和数据**:无论是出于成本、合规性还是灵活性的考虑,你都可以在云虚拟机和个人硬件的任意组合上运行应用程序,同时掌控数据并保持你喜爱的云般体验。 * **在成长中保持简单**:从单台机器开始,随时按需添加更多机器,无需改变工作流程。无需担心高可用控制平面或复杂的 YAML 配置。 * **基于成熟的原语构建**:开箱即用的生产级网络、部署原语、服务发现、负载均衡和 HTTPS ingress,无需成为分布式系统专家。 * **支持可持续计算** 🌿:最小化系统开销,最大化应用程序可用资源。 Uncloud 的目标是让容器化应用的部署和管理像使用云平台一样无缝,无论你运行的是 5 美元的 VPS、闲置的 Mac mini,还是一整架裸机服务器。 ## 🚀 快速开始 1. 安装 Uncloud CLI: brew install psviderski/tap/uncloud # 或者使用 curl (macOS/Linux) curl -fsS https://get.uncloud.run/install.sh | sh 更多选项请参见 [安装说明](https://uncloud.run/docs/getting-started/install-cli)。 2. 初始化你的第一台机器: uc machine init root@your-server-ip 3. 从 Docker 镜像部署你的应用,并使用 `app.example.com` 域名将其容器端口 8000 以 HTTPS 发布: uc run -p app.example.com:8000/https image/my-app 4. 在你的 DNS 服务商(Cloudflare, Namecheap 等)处创建一条 DNS A 记录,将 `app.example.com` 指向你的服务器 IP 地址。请等待几分钟以便 DNS 传播。 完成!你的应用现已运行并可访问 https://app.example.com ✨ 5. 完成后进行清理: uc ls # 从输出中复制服务名称并运行 rm 命令: uc rm my-app-name 如果你想在机器上完全卸载 Uncloud,请运行: uncloud-uninstall 更多信息请查看 [文档](https://uncloud.run/docs)。 ## ⚙️ 工作原理 查看 [设计文档](misc/design.md) 以了解 Uncloud 的设计理念和目标。 下图展示了一个由 3 台机器组成的 Uncloud 多提供商集群: 
揭开面纱,看看运行某些命令时发生了什么。
**当你在机器上初始化一个新集群时:** ``` $ uc machine init --name oracle-vm ubuntu@152.67.101.197 Downloading Uncloud install script: https://raw.githubusercontent.com/psviderski/uncloud/refs/heads/main/scripts/install.sh ⏳ Running Uncloud install script... ✓ Docker is already installed. ⏳ Installing Docker... ... ✓ Docker installed successfully. ✓ Linux user and group 'uncloud' created. ✓ Linux user 'ubuntu' added to group 'uncloud'. ⏳ Installing Uncloud binaries... ⏳ Downloading uncloudd binary: https://github.com/psviderski/uncloud/releases/latest/download/uncloudd_linux_arm64.tar.gz ✓ uncloudd binary installed: /usr/local/bin/uncloudd ⏳ Downloading uninstall script: https://raw.githubusercontent.com/psviderski/uncloud/refs/heads/main/scripts/uninstall.sh ✓ uncloud-uninstall script installed: /usr/local/bin/uncloud-uninstall ✓ Systemd unit file created: /etc/systemd/system/uncloud.service Created symlink /etc/systemd/system/multi-user.target.wants/uncloud.service → /etc/systemd/system/uncloud.service. ⏳ Downloading uncloud-corrosion binary: https://github.com/psviderski/corrosion/releases/latest/download/corrosion-aarch64-unknown-linux-gnu.tar.gz ✓ uncloud-corrosion binary installed: /usr/local/bin/uncloud-corrosion ✓ Systemd unit file created: /etc/systemd/system/uncloud-corrosion.service ⏳ Starting Uncloud machine daemon (uncloud.service)... ✓ Uncloud machine daemon started. ✓ Uncloud installed on the machine successfully! 🎉 Cluster "default" initialised with machine "oracle-vm" Waiting for the machine to be ready... Reserved cluster domain: xuw3xd.cluster.uncloud.run [+] Deploying service caddy 1/1 ✔ Container caddy-c47x on oracle-vm Started 0.9s Updating cluster domain records in Uncloud DNS to point to machines running caddy service... [+] Verifying internet access to caddy service 1/1 ✔ Machine oracle-vm (152.67.101.197) Reachable 0.1s DNS records updated to use only the internet-reachable machines running caddy service: *.xuw3xd.cluster.uncloud.run A → 152.67.101.197 ``` 1. CLI 通过 SSH 连接到机器并安装 Docker、`uncloudd` 机器守护进程以及由 systemd 管理的 [corrosion](https://github.com/superfly/corrosion) 服务。 2. 生成唯一的 WireGuard 密钥对,为机器及其容器分配专用子网 `10.210.0.0/24`,并相应地配置 `uncloudd`。所有后续通信均通过 SSH 经由其 gRPC API 与 `uncloudd` 进行。 3. 配置并启动 `corrosion`,这是一个基于 CRDT 的分布式 SQLite 数据库,用于在机器间共享集群状态。 4. 创建一个连接到 WireGuard 接口的 Docker bridge 网络。 5. 此机器成为新创建集群的入口点,集群配置存储在本地机器的 `~/.config/uncloud` 下。 **当你添加另一台机器时:** ``` $ uc machine add --name hetzner-server root@5.223.45.199 Downloading Uncloud install script: https://raw.githubusercontent.com/psviderski/uncloud/refs/heads/main/scripts/install.sh ⏳ Running Uncloud install script... ✓ Docker is already installed. ✓ Linux user and group 'uncloud' created. ⏳ Installing Uncloud binaries... ⏳ Downloading uncloudd binary: https://github.com/psviderski/uncloud/releases/latest/download/uncloudd_linux_amd64.tar.gz ✓ uncloudd binary installed: /usr/local/bin/uncloudd ⏳ Downloading uninstall script: https://raw.githubusercontent.com/psviderski/uncloud/refs/heads/main/scripts/uninstall.sh ✓ uncloud-uninstall script installed: /usr/local/bin/uncloud-uninstall ✓ Systemd unit file created: /etc/systemd/system/uncloud.service Created symlink /etc/systemd/system/multi-user.target.wants/uncloud.service → /etc/systemd/system/uncloud.service. ⏳ Downloading uncloud-corrosion binary: https://github.com/psviderski/corrosion/releases/latest/download/corrosion-x86_64-unknown-linux-gnu.tar.gz ✓ uncloud-corrosion binary installed: /usr/local/bin/uncloud-corrosion ✓ Systemd unit file created: /etc/systemd/system/uncloud-corrosion.service ⏳ Starting Uncloud machine daemon (uncloud.service)... ✓ Uncloud machine daemon started. ✓ Uncloud installed on the machine successfully! 🎉 Machine "hetzner-server" added to cluster Waiting for the machine to be ready... [+] Deploying service caddy 1/1 ✔ Container caddy-d36c on hetzner-server Started 1.0s Updating cluster domain records in Uncloud DNS to point to machines running caddy service... [+] Verifying internet access to caddy service 2/2 ✔ Machine hetzner-server (5.223.45.199) Reachable 0.2s ✔ Machine oracle-vm (152.67.101.197) Reachable 0.1s DNS records updated to use only the internet-reachable machines running caddy service: *.xuw3xd.cluster.uncloud.run A → 152.67.101.197, 5.223.45.199 $ uc machine ls NAME STATE ADDRESS PUBLIC IP WIREGUARD ENDPOINTS oracle-vm Up 10.210.0.1/24 152.67.101.197 10.0.0.95:51820, 152.67.101.197:51820 hetzner-server Up 10.210.1.1/24 5.223.45.199 5.223.45.199:51820, [2a01:4ff:2f0:128b::1]:51820 ``` 1. 第二台机器的配置过程与第一台类似。非 root SSH 用户需要具有 `sudo` 权限。 2. 为第二台机器及其容器分配新的子网 `10.210.1.0/24`。 3. 在集群状态中注册第二台机器,并与第一台机器交换 WireGuard 密钥。 4. 两台机器之间建立 WireGuard 隧道,允许连接到 bridge 网络的 Docker 容器跨机器直接通信。 5. 在第二台机器上配置并启动 `corrosion` 以同步集群状态。 6. 第二台机器作为备用入口点添加到集群配置中。 7. 如果其中一台机器离线,另一台机器仍可处理集群操作。 如果再添加一台机器,该过程将以新的子网重复进行。新机器只需与任意一台现有机器建立 WireGuard 连接。其他机器将通过共享的集群状态获悉新机器,并自动与其建立 WireGuard 隧道。 **当你运行一个服务时:** ``` $ uc run -p app.example.com:8000/https image/my-app [+] Running service my-app-1b3b (replicated mode) 1/1 ✔ Container my-app-1b3b-tcex on oracle-vm Started my-app-1b3b endpoints: • https://app.example.com → :8000 • https://my-app-1b3b.xuw3xd.cluster.uncloud.run → :8000 ``` 1. CLI 选择一台机器来运行你的容器。 2. 与 CLI 通信的 `uncloudd` 使用 [`grpc-proxy`](https://github.com/siderolabs/grpc-proxy) 将请求转发到目标机器,以便在那里启动容器。 3. 目标机器上的 `uncloudd` 在 bridge 网络中启动 Docker 容器,并将其信息存储在集群的分布式状态中。 4. 容器从 bridge 网络获得一个集群唯一的 IP 地址(在 `10.210.X.2-254` 范围内),并可被集群中的其他机器访问。 5. 在每台机器上以 [`global`](https://github.com/compose-spec/compose-spec/blob/main/deploy.md#mode) 模式运行的 Caddy 反向代理会监视集群状态中的新服务,并更新其配置以将流量路由到新容器。 看,没有需要维护的控制平面或主节点!只有一个简单的 overlay 网络和最终一致的状态同步,让机器协同工作。想要检查情况或进行更改?使用 CLI 隐式连接或直接通过 SSH 连接到任何机器。它们都拥有完整的集群状态,并且可以控制一切。这就像每台机器都是你控制平面的完整备份。标签:Docker管理, EVTX分析, HTTPS入口, NIDS, P2P同步, PE 加载器, Python工具, WireGuard, 分布式系统, 去中心化, 响应大小分析, 基础设施, 容器化, 容器编排, 应用部署, 提示注入, 日志审计, 服务发现, 服务器管理, 网格网络, 自托管, 裸金属部署, 请求拦截, 负载均衡, 轻量级Kubernetes替代, 集群管理