Prerequisite

为什么要将homelab迁移到kubernetes

我的homelab由2个机器组成,一个是老的dell laptop(4核心8线程, 20GB内存, 256GB ssd),一个是专门用来存储的nas(4核心4线程, 4GB内存, 7TB hdd)。

原先的架构如下图所示。所有的服务都是通过docker的方式部署的。dell laptop主机挂载nas的数据存储盘,并通过cloudflare tunnel对公网提供访问。

homelab docker

我希望尽量将服务部署在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的配置,就可以快速恢复服务。

迁移后的预期架构如下图所示:

homelab k8s

由于docker服务和k8s服务可以同时部署在dell laptop上,所以cluster搭建起来后,可以慢慢将服务从docker迁移到k8s。

细节

K8s服务使用microk8s搭建,整体比较简单,但是有一些细节需要注意。

Cloudflare Tunnel

参考cloudflare tunnel k8s的文档。

在配置完成之后,如一般的ingress配置一样,我们可以将不同的子域名或者相同域名的不同路径路由到到不同的k8s服务上。

编辑tunnel信息

cloudflare tunnel k8s

添加子域名映射关系 cloudflare tunnel edit

cloudflare tunnel public_hostname_page

存储

Microk8s自带了mayastor的addon,以及nfs client。

Mayastor

参考addon-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

需要注意的是,如果不需要数据冗余,那么就使用storageClassmayastor的数据存储。其他两种的后缀表示数据会有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功能。

cloudflare tunnel auth

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

cloudflare tunnel login method

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