目录

Laf 1.0私有部署: 虚拟机与内网专集

laf 是云开发平台,提供云函数、云数据库、云存储等开箱即用的应用资源。让开发者快速释放创意。ChatGPT 自动写函数,秒级上线,世界上只有两种 serverless,30 秒上线的 和 30 秒劝退的!

我们来聊聊如何在虚拟机、内网环境下部署 Laf 1.0。

适用场景

如果想体验 Laf 1.0 的功能,或者上线业务,建议直接使用官方在线云服务 laf.run,体验的话免费套餐足够。正式业务的话,官方的云服务稳定性肯定要更高些。而且在业务初期,流量不确定的情况下,官方的云服务能真正起到 Serverless 按需扩容缩容的效果。

因为环境搭在虚拟机,本身就不是奔着高可用去的,所以本文不会涉及高可用的问题,更多地是搭建一个临时的自用的 demo 环境。

本文面向的群体:

  • 就想部署一个玩玩
  • 尝鲜最新版功能(官方没发布到正式版、预览版的功能)
  • 想了解基本的 Laf 相关的 Kubernetes 基础知识
  • 想参与Laf开发,定制化 Laf
  • 学习云原生与 Serverless 技术

自己部署一个还是挺有意思的,通过观察 K8s 资源的变化,就能简单地反推出 Laf 的内部实现,比看代码更直观。

1 脉络

会从最简单的环境(裸机)讲起,然后逐步增加一些复杂的环境,比如虚拟机、内网等,建议顺序阅读。

2 Laf 与 Kubernetes

Laf 是构建在 Kubernetes(简称K8s)上的,所以部署 Laf 就等于:

  1. 安装 K8s 集群
  2. 部署 Laf
  3. 进一步设置,比如网络环境

简述一下这几步都有哪些途径去做:

  1. 安装 K8s 集群:如果你没有现成的 K8s 集群,但有服务器/电脑,可以用 sealos 在一台干净的裸机上一键安装(Laf官方的安装脚本里内置了sealos的安装命令)。
  2. 部署 Laf
    1. 如果你安装了 sealos,可以通过 sealos run 命令一键安装已经发行的 Laf 版本。
    2. 如果你想体验最新开发版的 Laf,或者没有安装 sealos,可以基于 Helm 安装。
  3. 进一步设置:我网络其实比较渣,主要会用到 frp 和端口转发来实现内网穿透(或许后面学习了Wireguard后,会有更好的内网解决方案)。详见下面的章节,会针对不同的网络环境给出不同的解决方案。

3 裸机部署/基于已有的K8s集群部署

适用场景
  • 拥有一台云服务器,无界面,并且拥有公网ip。
  • 或者拥有一台Linux物理机,装了图形化界面。
  • 或者拥有一台Linux物理机,无图形化界面。但有另外一台拥有图形化界面的电脑,能连到同一个局域网内。
  • 或者拥有一个公网可访问的K8s集群。 (如果环境不符合,也建议顺序阅读,后面的章节会引用前面的内容。)

3.1 安装最新发行版Laf/基于sealos安装Laf(推荐)

3.1.1 安装

先配置一下 Laf 的域名/公网IP:

# 如果你使用域名,假如域名是 abc.com,就运行这个
export DOMAIN=abc.com

# 如果你使用公网IP,需要在后面加一下 .nip.io,假如IP是1.2.3.4,就运行这个
export DOMAIN=1.2.3.4.nip.io

把这个安装脚本下载下来,或者新建文件并复制粘贴,并运行脚本就行:

curl https://raw.githubusercontent.com/labring/laf/main/deploy/scripts/install-on-linux.sh -o install-on-linux.sh
chmod +x install-on-linux.sh
sh ./install-on-linux.sh $DOMAIN    # 可能要加 sudo

上面的脚本会先安装 sealos,然后安装 K8s 集群,最后部署 Laf。

安装成功后,就能通过 https://$DOMAIN 访问 Laf 了。

3.1.2 简单看看 Laf 的架构

让我们从流量处理的角度,来简单看看 Laf 的架构(屏蔽了非常多的细节)。

  1. 用户的请求 http://<appid>.<DOMAIN>/<func> 打到服务器上,会被 Apisix 网关处理,转发到 Laf 内部
  2. Laf 会为某个应用建立一个单独的 Deployment,这个 Deployment 里可能有一到多个 Pod 实例(即容器,可以理解为应用副本),每个实例其实就是一个 express 进程。
  3. 整个 Laf 共享一个 MongoDB 数据库,其中一个应用对应一个 Mongo 的 DB;共享一个 Minio 对象存储,既可以从前端访问,也可以从云函数内部访问。
Laf架构(超级简化)
Laf架构(超级简化)

(后面的图中,涉及Laf架构部分有细微的变化,请重点关注其他图的网络环境部分,架构部分仍以这张图为准。)

3.1.3 Kubernetes 简单介绍

安装成功后,你可以尝试运行 kubectlsudo kubectl 命令,这就是 K8s 的命令行工具。

插播一条关于 kubectl 的小知识。kubectl 只是一个控制 K8s 的命令行工具,既可以控制本地的集群,又可以控制远程的集群。它会自动读取 ~/.kube/config 文件(称为kubeconfig),这个文件里存储了集群的信息,比如集群的地址、证书(身份验证信息)等。我们安装完 K8s 后,~/kube/config 自动会有一份集群的配置文件。

我们完全可以通过命令行来管理 Kubernetes ,但通过图形化界面会更简单、直观、高效。这里推荐一款软件,叫 Lens,同时拥有 Windows、Mac 和 Linux 版本。

安装完成后,它会自动检测 ~/.kube/ 目录下的 kubeconfig 文件,连接集群。打开 Lens,按下图顺序点击,在右边的大框里,你的列表里应该只有一个集群(名字应该是 kubernetes),点进去就能看到集群的状态了。

Lens界面
Lens界面

第一次新建 Laf 应用的时候,需要重启 Laf Server,如下图所示:

你可能发现了,我们是直接「删除」了 laf-server- 开头的 Pod。不要慌,这是 K8s 的特性,Pod 是 K8s 的最小调度单元(由若干个容器组成),我们在 Deployment 里定义了 replicas 为 1,所以 K8s 会永远去努力地保证集群里有一个 laf-server- 开头的 Pod。当我们删除了这个 Pod 后,K8s 会自动创建一个新的 Pod。也就相当于重启了。

不过要注意的是,只有 Pod 能随手删,其他的资源都不能删,比如 Deployment、Service、Ingress 等等。删除就真没了!

重启laf-server
重启laf-server

我们也可以用 kubectl 即命令行来删除 Pod:

kubectl delete pods -l app.kubernetes.io/name=laf-server -n laf-system
# (意思是:删除 laf-system 命名空间下,标签为 app.kubernetes.io/name=laf-server 的 Pod)

Lens 还有很多功能,比如查看 Pod 的日志、利用终端进入 Pod、Port Forward 等等,如下图:

Lens操作
Lens操作

Lens 实战

还记得我前面说过的 Apisix 作为 Laf 的网关吗?我们可以通过 Lens 来查看 Apisix 的具体配置。

很简单,参考上面那张图,我们找到 Workloads->Podsapisix-dashboard- 开头的 Pod,点一下,然后往下拉,点一下 Forward->Start,就能在浏览器里看到 Apisix 的 Dashboard 了。账户密码都是 admin

我们也可以点击 Lens 的 Network->Services 里的 apisix-dashboard- 开头的 Service(svc),然后往下拉,点一下 Forward->Start,效果和使用 Port Forward 是一样的。

(Pod和Service的区别,简单来说,Pod是apisix-dashboard的进程本身,但 K8s 有很好的抽象,我们并不能直接访问到 Pod 的网络,需要用 Service 来将服务暴露出去。而 Lens 的 Forward 功能,对应的是 K8s 的 port-forward 命令,它可以将 Pod/Service 的网络临时映射到本地,方便我们访问。所以,基于 Pod 和 Service 来做 port-forward,效果是类似的。)

Apisix Dashboard
Apisix Dashboard

上面就是 Apisix 的 Dashboard 了。 我们可以看到

  • 源Host是 10.59.179.7.nip.io 的请求会被转发到 laf-web, 也就是 laf 的网页。(其中 10.59.179.7.nip.io 是我的临时域名)。
  • 源Host是 minio.10.59.179.7.nip.io 的请求会被转发到 Minio 对象存储服务。值得注意的是,如果一个路径同时匹配多个规则,那会按照匹配路径更长的来,比如 minio.10.59.179.7.nip.io 会匹配 minio ,而不是 laf-web
  • 最下面两条,hps54j.10.59.179.7.nip.ioi3p9lo.10.59.179.7.nip.io 就是分别为两个应用分配的域名,把 appid 作为了二级域名。

3.2 安装最新开发版Laf/基于Helm安装Laf

建议直接参考 https://forum.laf.run/d/241 (by 白夜安装)

4. 在虚拟机中部署Laf

适用场景
拥有一台电脑即可,Linux、Windows、Mac 都可以。后面的教程会把这台机器称为「宿主机」。

本教程采用 Multipass 安装虚拟机(一个轻量级的虚拟机,支持Linux、Windows、Mac,不过只能装出来Multipass)。

最终网络拓扑是这样的:

网络拓扑-虚拟机部署Laf
网络拓扑-虚拟机部署Laf

4.1 在 macOS 上安装 Multipass + sealos + Laf

这个最简单了,直接执行官方脚本 install-on-mac.sh 就行,里面内置了 Multipass 的安装动作。(不过需要保证你的电脑上有 Homebrew

4.2 在 Windows 上安装 Multipass + sealos + Laf

分为三步:

  1. 安装 Multipass
  2. 使用 Multipass 启动一个虚拟机
  3. 在虚拟机中安装 Laf

4.2.1 安装 Multipass

官网 自行下载安装。

4.2.2 使用 Multipass 启动一个虚拟机

运行以下命令,其中 laf-dev 是虚拟机的名称,可以自定义。

multipass launch --name laf-dev --cpus 2 --mem 4G --disk 50G

使用 multipass list 查看虚拟机,有一列是 IPv4,把第一个IP记下来,这个是虚拟机的IP。

4.2.3 在虚拟机中安装 Laf

先进入虚拟机:

multipass shell laf-dev

后面的步骤和在裸机上安装一样,参考本文 3.1 章节。注意域名填写虚拟机的IP+nip.io,比如我的虚拟机 IP 是 10.59.179.7,那么域名就是 10.59.179.7.nip.io

4.2.4 在宿主机中访问虚拟机

直接使用虚拟机的IP+nip.io访问即可,multipass 已经自动帮我们配置好了网络了,访问虚拟机 IP,流量自动会被转发到虚拟机里。

4.2.5 一些小细节

如果服务器的根目录容量不够了,可以根据这个文档,把虚拟机挂载到其他外置的磁盘上(注意一定要在 /mnt 或者 /home 目录下):

Configure where Multipass stores external data

4.3 关于 Kubernetes 访问

显然,我们的 Lens 是装在宿主机上的,我们怎么才能在宿主机上访问虚拟机里的 Kubernetes 呢?

我们先用 multipass shell laf-dev 进入宿主机,然后把宿主机的 ~/.kube/config 文件(也可能在 /root/.kube/config)拷贝一下,在宿主机建立一个 ~/.kube/config 文件,把内容粘贴进去。

有个地方需要修改,我们打开 ~/.kube/config 文件,找到 server 字段,把 apiserver.cluster.local 改成虚拟机的 ip,就行了。

后面的事就交给 Lens 了。

5. Laf 部署在内网机器(无图形界面),想使用自己的电脑开发

主要有两步:

  1. 用组网工具/内网工具,把自己电脑的网络和内网机器的网络连接起来
  2. 修改自己电脑上的 hosts 文件

第一步说起来简单,实现难;第二步不好理解,但是实现简单。

5.1 第二步(Hosts)

先来说第二步吧,为什么要配 hosts,怎么配?

因为,即使我们已经打通了两个网络,但是 apisix 是根据域名来转发流量的,所以哪怕我们把 127.0.0.1:80 连接到了内网机器的 80 端口,也会因为 apisix 无法解析域名而失败。

假设我们已经把 127.0.0.1:80 连接到了内网机器的 80 端口,我们就需要把 apisix 配置的域名解析到 127.0.0.1。然后访问 http://$DOMAIN,流量就会被转发到 127.0.0.1,再由组网工具连到内网机器。

hosts 大概是这样:

127.0.0.1 10.59.179.7.nip.io
127.0.0.1 minio.10.59.179.7.nip.io
127.0.0.1 oss.10.59.179.7.nip.io
127.0.0.1 api.10.59.179.7.nip.io
127.0.0.1 hps54j.10.59.179.7.nip.io
127.0.0.1 i3p9lo.10.59.179.7.nip.io

5.2 第一步(组网)

第二步组网,我对网络这块了解太浅了,采取的是 frp + termius port forwarding 的方式,后面采用 WireGuard 一类的工具应该会更优雅些。

先决条件
  • 组网需要拥有一台拥有公网ip的服务器用于搭建 frp server(即frps);如果会用 cloudflare 做内网穿透,也可以不需要公网服务器;或者你会其他更高级的组网工具。
  • 需要Termius Pro 来做 Port Forwarind,或使用GitHub做一下学生认证,然后使用 GitHub 登录 Termius;或者使用其他免费的 Port Forwarding 工具。

大概原理如下:

网络拓扑-内网部署Laf
网络拓扑-内网部署Laf
  1. 首先是配 frp:

在公网机器(假设ip为1.2.3.4)上装 frps,在内网机器(假设ip为192.168.1.2)上装 frpc,其中 frpc.ini 的一部分大概是这样:

[laf_ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 30022

(省略了 frps、frpc 的安装,以及 frps 的全部配置,frpc 的部分配置,详见官方文档)

这样,我们访问 1.2.3.4:30022,就相当于访问了 192.168.1.2:22,也就是能通过这个ip端口组合 ssh 到内网服务器了。(记得把云服务器的对应端口放行)。

  1. 然后是配 Termius 端口转发

① 在 Termius 的 Host 中,建立一个新的服务器,ip 和 port 填写公网机器的 ip 和 frp 的端口,比如我的是 1.2.3.4:30022。 ② 新建一个 Termius Port Forwarding,建立一个 Local 类型的,信息如下:

  • Local port number: 80
  • Bind address: 0.0.0.0
  • Select a host: 选择刚才新建的服务器
  • Destination address: 可以是内网服务器ip,也可以是 127.0.0.1
  • Destination port: 80

编辑后,双击图标,开启端口转发。

这样就把笔记本所有的 80 端口流量通过公网机器中转到了内网机器,再转发到内网机器的 80 端口。

当然 Bind address 也可以不填 0.0.0.0,填具体的域名,比如 minio.10.59.179.7.nip.io,这样就需要建立多个 Port Forwarding 了,数量和hosts文件中的域名数量一致。

注意 Port Forwarding 开启后,和科学上网可能会冲突,二者只能开一个。

5.3 为什么同时需要frp和端口转发

比如,为什么不能把开个 frp,直接把 1.2.3.4:1234 的流量转发到 192.168.1.2:80,再配一下 hosts,这样访问 1.2.3.4:1234 不也相当于访问内网的 http://$DOMAIN 了吗?

如果只访问单纯的 Laf 前端,当然是可以的。但问题是,Laf 前端还会请求 laf-server,这个请求是从你的电脑发出的,同时请求的后端地址是 http://$DOMAIN(内网地址),无法更改,而我们的笔记本电脑直接请求内网域名地址,显然是不行的。

换句话说,如果不配合端口转发,把所有的 80 端口流量都转发到内网机器,那么只能登录 Laf 的开发页面,遇到需要调用 laf-server(比如调试、发布、建数据库等等) 的时候,就会失败。

5.4 如何在自己的笔记本上连接 Kubernetes 集群

K8s 同样在内网里,怎么去连接呢?

这个相对简单些,只需要 frp 就行了。

按照前面的步骤,把 kubeconfig 文件放到自己的笔记本的 ~/.kube/config 目录下,然后配置一下网络,再修改 server 字段就行了。

默认的 server 字段的值是 https://apiserver.cluster.local:6443,其实这个 apiserver.cluster.local 就是本机ip(如果是虚拟机那就是虚拟机ip),在这里其实就是 192.168.1.2,大家可以 ping 一下试试。

所以我们只要建立一个新的 frpc,比如,把 1.2.3.4:1235 转发到内网的 6443 端口上。(前者的1235端口可以随便改,后者的6443端口是固定的,和 kubeconfig 原始的 server 字段中的端口一致)

后面,就又是 Lens 的事了。

6. Laf 部署在内网机器的虚拟机里,想使用自己的电脑开发

网络拓扑是这样的:

网络拓扑-内网虚拟机部署Laf
网络拓扑-内网虚拟机部署Laf

总体上和 「5. Laf 部署在内网机器(无图形界面),想使用自己的电脑开发」是一致的,只是需要修改一些配置。

首先是 Laf 的访问:

  1. frpc 的配置是一样的,不用改。
  2. Termius 关于 Laf 应用的 Port-forwarding 配置需要改一个地方,把 Destination address 改成虚拟机的 ip,比如 10.59.179.7,其他不变。

然后 K8s 访问,有两种方式,一种是用 frp,一种是用 Termius 的 Port-forwarding。

  1. 方式一:在内网机器上,建立一个属于 K8s 的 frpc,部分配置长这样:
[k8s]
type = tcp
local_ip = 10.59.179.7
local_port = 6443
remote_port = 1235

其中,local_ip 是虚拟机的 ip。

然后复制 kubeconfig 文件到自己的笔记本,修改 server 字段,改为 https://1.2.3.4:1235

后面就双是 Lens 的事了。

  1. 方式二:使用 Termius Port-forwarding

新建一条 Termius 的 Port-forwarding,配置如下:

  • Local port number: 随便选个,比如 1236
  • Bind address: 127.0.0.1
  • Select a host: 选择刚才新建的服务器
  • Destination address: 虚拟机ip,这里是10.59.179.7,也可以填 apiserver.cluster.local
  • Destination port: 6443

然后复制 kubeconfig 文件到自己的笔记本,修改 server 字段,改为 https://127.0.0.1:1236

后面就叒是 Lens 的事了。