Skip to content
赞赏-微信扫码

部署更多容器应用的前提是,我们需要一个持久化的存储。

首先,直接写到容器内的数据,会在容器重启后丢失。

其次,如果挂载一个物理节点的本地路径到容器内,容器重启时可能被分配到另一台物理节点上运行。

另外,还有共享的作用,多个容器实例可以共享一个存储。

全都要

我的 硬件组成 里有一个专业的群晖 nas,可以提供 集群外的公共存储。它不止 量大管饱,还有白群晖系统的 稳定可靠 和 UI界面。但是 nfs 也有不足的地方,它的性能可能不够极致,这里包括 硬件的性能,它经过了一层网络请求,时延比较高,群晖的网卡还只有千兆。也包括软件层面的性能,虽然在我的群晖 nas 上未出现过,但身边朋友有案例,用 truenas 经常发生 nfs server 故障且无法重启的情况(只能重启整个物理机),用威联通也经常发生整个 nas 的死机或文件系统只读。

集群内的分布式存储,能提供极致的性能,但需要找一个简洁轻量的实现,毕竟 homelab 的场景没啥运维资源能投入。k3s 官方推荐的它们自家的 longhorn 实现,在 易用 轻量 简洁 上就很符合要求。

我们没有更多的资金,在已经养了一台 nas 的情况下,让 node 节点也都上大容量的硬盘,而且低功耗小主机的 m2 接口速度也有限,大容量硬盘的读写速率也高到浪费。所以 nfs 和 longhorn 全都要,对性能有高要求的就用 longhorn,没啥特殊要求就都到 nfs 上去。

NFS

服务端

因为是在群晖上配置的 nfs server,没有在 linux 上用命令行实操搭建的经历,就不写服务端相关的搭建说明了。Kuboard 的文档里就应该能找到 相关教程

身边有个踩坑案例,在 /etc/exports 里配置相关权限的时候,需要配上 no_root_squash

客户端

在 Kuboard 的界面和文档里,都有相关的教程。

先建一个 存储类。

在挂载时,使用 存储卷声明 的方式 间接使用 NFS,这样的话 kubernetes 会自动帮我们创建 pvc-xxx 子目录。

如果不用“先建 存储类, 再用 存储卷声明”的方式,而是直接在挂载时配置 nfs 服务器地址 作为存储,每个应用的 NFS PATH 肯定要用不一样的,就都要去 nfs 服务端手动建一下目录,会很麻烦。

额外的好消息

nfs 不受 pvc 容量上限 的限制。不用考虑修改 pvc 去扩容的操作。k8s 的接口定义里虽然有容量上限这一项,但是 nfs 没有这个功能,就没支持容量限制。实测是可以无任何操作,直接超额使用的。

longhorn

longhorn.io

sh
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.7.2/deploy/longhorn.yaml

安装后,会有两个 存储类。longhorn 和 longhorn-static。如果搞不明白区别,就先当 longhorn-static 不存在好了。

longhorn-ui 默认没有配 应用路由,可以直接用 Kuboard 的页面代理。除了 flink 的后台页面,这是难得遇到的又一个可以正常被代理的 ui。

pvc 扩容

我试过用下面两个步骤操作扩容:

  1. 首先,到 longhorn-ui 上去操作 volume。
  2. 然后,如果 pvc 已经被 pod 在使用,相关的 pod 需要重启。

第二步的关键,是 pvc 的状态,状态不能是 被绑定使用中。有时候重启 pod 的动作是不够让 pvc 空闲的,要关闭 pod(把 pod 实例伸缩数量设置成 0)。

sc、pv、pvc

sc(StorageClass)存储类。对应着不同的存储实现方式。可以是 localpath,可以是上面提到的 nfs 或 longhorn。

pvc(PersistentVolumeClaim)存储卷声明。工作负载挂载存储时,直接使用的就是 pvc(存储卷声明)。新建 pvc 的时候,要指定这个 pvc 底层用哪个 StorageClass(存储类)。

pv(PersistentVolume)存储卷,可以当这个东西不存在,不要去了解它。kuboard 界面上新建 pvc 的时候,表面上是在建 pvc,实际上动态 1对1 帮忙建了个 pv。它是 pvc 和 sc 之间的中间层,归到 sc 那边,可以当作是 sc 的对外接口。古话说“没有什么是加一个层不能解决的,如果有,那就加两层”。pv 这个中间层是给运维用的,我们不会像专业的运维那样,成天把硬盘插来拔去,成天把工作负载导出来导入去。有 pv 在中间挡着,运维可以在不改动 pvc 的情况下更换底层 sc。