能力实在有限,可能会有不少错误,欢迎评论指出。
以下正文:
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 就等于:
- 安装 K8s 集群
- 部署 Laf
- 进一步设置,比如网络环境
简述一下这几步都有哪些途径去做:
- 安装 K8s 集群:如果你没有现成的 K8s 集群,但有服务器/电脑,可以用 sealos 在一台干净的裸机上一键安装(Laf官方的安装脚本里内置了sealos的安装命令)。
- 部署 Laf
- 如果你安装了 sealos,可以通过
sealos run
命令一键安装已经发行的 Laf 版本。
- 如果你想体验最新开发版的 Laf,或者没有安装 sealos,可以基于 Helm 安装。
- 进一步设置:我网络其实比较渣,主要会用到 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 的架构
- 用户的请求
http://<appid>.<DOMAIN>/<func>
打到服务器上,会被 Apisix 网关处理,转发到 Laf 内部
- Laf 会为某个应用建立一个单独的 Deployment,这个 Deployment 里可能有一到多个 Pod 实例(即容器,可以理解为应用副本),每个实例其实就是一个 express 进程。
- 整个 Laf 共享一个 MongoDB 数据库,其中一个应用对应一个 Mongo 的 DB;共享一个 Minio 对象存储,既可以从前端访问,也可以从云函数内部访问。
(后面的图中,涉及Laf架构部分有细微的变化,请重点关注其他图的网络环境部分,架构部分仍以这张图为准。)
3.1.3 Kubernetes 简单介绍
安装成功后,你可以尝试运行 kubectl
或 sudo kubectl
命令,这就是 K8s 的命令行工具。
插播一条关于 kubectl 的小知识。kubectl 只是一个控制 K8s 的命令行工具,既可以控制本地的集群,又可以控制远程的集群。它会自动读取 ~/.kube/config
文件(称为kubeconfig),这个文件里存储了集群的信息,比如集群的地址、证书(身份验证信息)等。我们安装完 K8s 后,~/kube/config 自动会有一份集群的配置文件。
我们完全可以通过命令行来管理 Kubernetes ,但通过图形化界面会更简单、直观、高效。这里推荐一款软件,叫 Lens,同时拥有 Windows、Mac 和 Linux 版本。
安装完成后,它会自动检测 ~/.kube/
目录下的 kubeconfig 文件,连接集群。打开 Lens,按下图顺序点击,在右边的大框里,你的列表里应该只有一个集群(名字应该是 kubernetes
),点进去就能看到集群的状态了。
第一次新建 Laf 应用的时候,需要重启 Laf Server,如下图所示:
你可能发现了,我们是直接「删除」了 laf-server-
开头的 Pod。不要慌,这是 K8s 的特性,Pod
是 K8s 的最小调度单元(由若干个容器组成),我们在 Deployment
里定义了 replicas
为 1,所以 K8s 会永远去努力地保证集群里有一个 laf-server-
开头的 Pod。当我们删除了这个 Pod 后,K8s 会自动创建一个新的 Pod。也就相当于重启了。
不过要注意的是,只有 Pod 能随手删,其他的资源都不能删,比如 Deployment、Service、Ingress 等等。删除就真没了!
我们也可以用 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 实战
还记得我前面说过的 Apisix 作为 Laf 的网关吗?我们可以通过 Lens 来查看 Apisix 的具体配置。
很简单,参考上面那张图,我们找到 Workloads->Pods
里 apisix-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 了。
我们可以看到
- 源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.io
和 i3p9lo.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)。
最终网络拓扑是这样的:
4.1 在 macOS 上安装 Multipass + sealos + Laf
这个最简单了,直接执行官方脚本 install-on-mac.sh 就行,里面内置了 Multipass 的安装动作。(不过需要保证你的电脑上有 Homebrew)
4.2 在 Windows 上安装 Multipass + sealos + Laf
分为三步:
- 安装 Multipass
- 使用 Multipass 启动一个虚拟机
- 在虚拟机中安装 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 部署在内网机器(无图形界面),想使用自己的电脑开发
主要有两步:
- 用组网工具/内网工具,把自己电脑的网络和内网机器的网络连接起来
- 修改自己电脑上的 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 工具。
大概原理如下:
- 首先是配 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 到内网服务器了。(记得把云服务器的对应端口放行)。
- 然后是配 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 部署在内网机器的虚拟机里,想使用自己的电脑开发
网络拓扑是这样的:
总体上和 「5. Laf 部署在内网机器(无图形界面),想使用自己的电脑开发」是一致的,只是需要修改一些配置。
首先是 Laf 的访问:
- frpc 的配置是一样的,不用改。
- Termius 关于 Laf 应用的 Port-forwarding 配置需要改一个地方,把 Destination address 改成虚拟机的 ip,比如
10.59.179.7
,其他不变。
然后 K8s 访问,有两种方式,一种是用 frp,一种是用 Termius 的 Port-forwarding。
- 方式一:在内网机器上,建立一个属于 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 的事了。
- 方式二:使用 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 的事了。