将 homelab 从 docker 迁移到 kubernetes
目录
Prerequisite#
为什么要将 homelab 迁移到 kubernetes#
我的 homelab 由2个机器组成,一个是老的 dell laptop(4核心8线程, 20GB 内存, 256GB ssd),一个是专门用来存储的 nas(4核心4线程, 4GB 内存, 7TB hdd)。
原先的架构如下图所示。所有的服务都是通过 docker 的方式部署的。dell laptop 主机挂载 nas 的数据存储盘,并通过 cloudflare tunnel 对公网提供访问。

我希望尽量将服务部署在 cpu 和内存都比较强大的 dell laptop 上,但是如果 dell laptop 最终故障了,nas 服务也可以继续运行必要的服务。同样的,如果 nas 服务故障了,dell laptop 也可以继续运行必要的服务。
迁移到 k8s 之后,也可以尝试 gitops。
根据手上的资源,迁移到 k8s 之后,可以通过以下方式实现上诉需求:
- 将 node 打上标签,通过preferredDuringSchedulingIgnoredDuringExecution将 pod 分配到 dell laptop 上
- 通过 pod 的Qos保证必要的服务(Guaranteed)可以正常运行在 nas 上,而非必要的服务资源会被回收进入
pending状态。 - 另外一块4TB 的硬盘定期冷备份 Nas 的必要数据,如果 nas 服务故障,可以直接接入到 dell laptop 上,修改 pv 的配置,就可以快速恢复服务。
迁移后的预期架构如下图所示:

由于 docker 服务和 k8s 服务可以同时部署在 dell laptop 上,所以 cluster 搭建起来后,可以慢慢将服务从 docker 迁移到 k8s。
microk8s 上的入口、存储和安全#
K8s 服务使用 microk8s 搭建,整体比较简单,但是有一些细节需要注意。
Cloudflare Tunnel#
参考cloudflare tunnel k8s的文档。
在配置完成之后,如一般的ingress配置一样,我们可以将不同的子域名或者相同域名的不同路径路由到到不同的 k8s 服务上。
编辑 tunnel 信息

添加子域名映射关系


存储#
Microk8s 自带了mayastor的 addon,以及 nfs client。
Mayastor#
$ kubectl get storageClass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
mayastor io.openebs.csi-mayastor Delete WaitForFirstConsumer false 23h
mayastor-2 io.openebs.csi-mayastor Delete WaitForFirstConsumer false 23h
mayastor-3 io.openebs.csi-mayastor Delete WaitForFirstConsumer false 23h
需要注意的是,如果不需要数据冗余,那么就使用storageClass为mayastor的数据存储。其他两种的后缀表示数据会有2份拷贝和3份拷贝。(自用服务,不需要这么多冗余,定期备份就好)。
pv 的配置如下:
apiVersion: v1
kind: PersistentVolume
metadata:
name: calibre-config
spec:
capacity:
storage: 200Mi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: mayastor-1
hostPath:
path: /opt/data/calibre_web/config/
NFS#
参考nfs-subdir-external-provisioner
apiVersion: v1
kind: PersistentVolume
metadata:
name: calibre-books
spec:
capacity:
storage: 50Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
nfs:
path: "/storage/calibre"
server: "192.168.50.106"
readOnly: false
如果碰到提示 nfs 的文件只有访问权限,可以通过修改 nas 服务器上的文件权限来解决。
Security#
某些服务本身并不自带权限控制模块,可以直接使用 cloudflare tunnel 的 authentication 功能。

我使用 One-time PIN 的方式,但也可以使用 Google 或 Github 账户登录。有自建 sso 服务的,还可以直接使用 OpenID Connect。

如果数据比较重要,还可以在 Access 来限制访问地区等。