天天看點

雲上 K8s 叢集資料持久化方案之 JuiceFS

作為最流行的容器編排系統,Kubernetes 解決以下問題:

  • 服務發現和負載均衡
  • 存儲編排
  • 自動部署和復原
  • 自動完成裝箱計算
  • 自我修複
  • 密鑰與配置管理

毫無疑問,這些特性覆寫了容器化技術的方方面面,每個特性都是 Kubernetes 的核心主題。

現在請大家回想,在你第一次成功部署 Kubernetes 叢集以後,除了排除萬難後的興奮,是否也有這樣的疑惑:

應用容器跑起來了,資料該存在哪兒?

在使用 Docker 時,我們幾乎不用操心資料存儲(持久化)的問題,直接把本地存儲映射到容器就 OK。而 Kubernetes 起步就是由多節計算點組成的叢集,單純地将節點上的的存儲映射給容器,存儲會受限于所在節點的健康狀态,這顯然是不可靠的。

我們知道,Kubernetes 本身不提供存儲,它的存儲編排能力主要解決的是簡化容器與存儲之間的連接配接,讓我們可以輕松的實作本地存儲和雲存儲的挂載和使用。

而在 K8s 叢集中,常用的存儲不外乎基于本地網絡的 NAS 存儲,比如 SMB、NFS、iSCSI 等,以及基于雲的塊存儲和對象存儲。存儲類型之間并無優劣之分,每種存儲都有其擅長的應用場景。比如,使用雲平台托管的 Kubernetes 叢集服務與使用跨雲平台自建的叢集在存儲選型上就有很大差别,後者的節點分布在不同平台,無法公用某一特定雲平台的 NAS 存儲服務。而使用平台無關的雲存儲服務,就能同時滿足前面兩種場景的需求。

在本文中,我們就來分享一種平台無關的雲的存儲方案 —— JuiceFS。

什麼是 JuiceFS

JuiceFS

是一個雲原生的分布式檔案系統,由對象存儲和資料庫共同驅動。任何存入 JuiceFS 的檔案都會按照特定的規則被拆分成資料塊存入對象存儲,相對應的中繼資料則會存儲在獨立的資料庫。相比于直接使用對象存儲,JuiceFS 可以實作幾十倍甚至上百倍的性能提升。

通過架構圖可以了解,JuiceFS 的底層是資料庫和對象存儲,通過 JuiceFS 用戶端,向上提供豐富的接口滿足不同應用的存儲需求,比如面向 Kubernetes 提供了 CSI 驅動,面向 Hadoop 提供了 Java API,而面向正常作業系統環境則通過 FUSE 提供了 POSIX 檔案系統接口,可以挂載 JuiceFS 像本地磁盤一樣使用。

雲上 K8s 叢集資料持久化方案之 JuiceFS

使用 JuiceFS 的優勢

  • 十倍以上對象存儲性能提升
  • 簡單易用
  • 彈性存儲
  • 跨平台,資料自由遷移。
  • 開源軟體,安全透明。

在 Kubernetes 上使用 JuiceFS

前面已經提到,JuiceFS 是一套平台無關的存儲方案,既能應用在自建的 Kubernetes 叢集,也能應用在平台托管的 Kubernetes 叢集,而且二者的安裝和使用方法基本一緻。本文我們以阿裡雲上的容器服務 ACK 托管版為例,介紹如何安裝和使用 JuiceFS 持久化資料。

資源準備

我們需要準備以下資源:

  • JuiceFS 檔案系統
  • Kubernetes 叢集

1. 準備 JuiceFS 檔案系統

JuiceFS 檔案系統的建立非常簡單,不論你是否使用阿裡雲的服務,都可以參照《

在阿裡雲上安裝和使用 JuiceFS 存儲

》這篇文章建立檔案系統。

2. 準備 Kubernetes 叢集

這裡我們使用阿裡雲的 Kubernetes 容器托管服務 ACK 進行示範,它的特點是隻需建立 worker 節點,master 節點由平台統一提供。我們建立的叢集配置如下:

  • 阿裡雲 ACK 托管版
  • Kubernetes 版本:1.20.4-aliyun.1
  • 容器運作時:Containerd 1.4.8
  • workder 節點數:2

worker 節點即 ECS 雲伺服器,數量和配置可以按需調整,這裡我建立了2個節點,配置為:

  • CPU:4 核
  • 記憶體:8 GB
  • 硬碟:40 GB ESSD

通路叢集

我們通常使用 kubectl 通路和管理叢集,如未安裝,請參考

官方文檔

。将叢集的通路憑據拷貝到用于控制叢集的主機上,通常拷貝到

$HOME/.kube/config

配置檔案中。

在 ACK 叢集資訊頁面,「連接配接資訊」頁籤檢視「叢集通路憑證」,根據需要選擇公網或内網憑證。如果要通過阿裡雲上其他的 ECS 通路叢集,則可以使用内網憑證。在本地計算機上遠端控制叢集,則需要使用公網憑證。

本文我們會在本地電腦上遠端控制 ACK 叢集,是以要将公網憑證複制到本地主機的

$HOME/.kube/config

檔案中。通路憑據添加完成以後,在本地使用 kubectl 可以看到 ACK 叢集的節點狀态:

$ kubectl get nodes
NAME                     STATUS   ROLES    AGE     VERSION
cn-shanghai.10.0.2.11    Ready    <none>   8m53s   v1.20.4-aliyun.1
cn-shanghai.10.0.4.209   Ready    <none>   8m53s   v1.20.4-aliyun.1           

安裝 JuiceFS CSI Driver

叢集配置妥當了,現在開始安裝 JuiceFS CSI Driver。根據你使用 Kubernetes 版本,選擇執行以下指令。

本文使用的版本是

1.20.4

,應執行第一條安裝指令。

Kubernetes v1.18 及以上版本

$ kubectl apply -f https://raw.githubusercontent.com/juicedata/juicefs-csi-driver/master/deploy/k8s.yaml           

Kubernetes v1.18 以下版本

$ kubectl apply -f https://raw.githubusercontent.com/juicedata/juicefs-csi-driver/master/deploy/k8s_before_v1_18.yaml           

叢集節點位于國内資料中心時,可能會因為連結被重置而無法應用配置的問題:

Unable to connect to the server: read tcp 192.168.3.88:64971->185.199.111.133:443: read: connection reset by peer           

這時可以先将配置檔案儲存到本地,然後直接通過本地的配置檔案進行部署,例如:

$ kubectl apply -f k8s.yaml           

該指令會在叢集上建立一系列必要的資源,執行成功會傳回類似下面的結果,

serviceaccount/juicefs-csi-controller-sa created
serviceaccount/juicefs-csi-node-sa created
clusterrole.rbac.authorization.k8s.io/juicefs-csi-external-node-service-role created
clusterrole.rbac.authorization.k8s.io/juicefs-external-provisioner-role created
clusterrolebinding.rbac.authorization.k8s.io/juicefs-csi-node-service-binding created
clusterrolebinding.rbac.authorization.k8s.io/juicefs-csi-provisioner-binding created
priorityclass.scheduling.k8s.io/juicefs-mount-critical created
statefulset.apps/juicefs-csi-controller created
daemonset.apps/juicefs-csi-node created
csidriver.storage.k8s.io/csi.juicefs.com created           

JuiceFS CSI Driver 的相關資源均建立在

kube-system

命名空間。

雲上 K8s 叢集資料持久化方案之 JuiceFS

其中包括一個 DaemonSet 守護程序,在每個節點上都有一個執行個體。

雲上 K8s 叢集資料持久化方案之 JuiceFS

建立存儲類

現在就可以通過 JuiceFS CSI Driver 建立存儲類了。建立一個配置檔案,例如:

juicefs-sc.yaml

,參照并調整以下配置資訊。在以下示例配置中聲明了

Secret

StorageClass

兩種資源,請注意兩種資源之間的名稱對應關系。

Secret

部分,

stringData

段落用來設定 JuiceFS 存儲的資訊,包括檔案系統名稱、中繼資料連結以及對象存儲相關的資訊。如果使用已經建立好的檔案系統,那麼直接填寫

name

metaurl

這兩項就可以了。其他不需要的設定項可以删除或将它的值留白。

apiVersion: v1
kind: Secret
metadata:
  name: juicefs-sc-secret
  namespace: kube-system
type: Opaque
stringData:
  name: "test"
  metaurl: "redis://juicefs.afyq4z.0001.use1.cache.amazonaws.com/3"
  storage: "s3"
  bucket: "https://juicefs-test.s3.us-east-1.amazonaws.com"
  access-key: ""
  secret-key: ""
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: juicefs-sc
provisioner: csi.juicefs.com
reclaimPolicy: Retain
volumeBindingMode: Immediate
parameters:
  csi.storage.k8s.io/node-publish-secret-name: juicefs-sc-secret
  csi.storage.k8s.io/node-publish-secret-namespace: kube-system
  csi.storage.k8s.io/provisioner-secret-name: juicefs-sc-secret
  csi.storage.k8s.io/provisioner-secret-namespace: kube-system           

應用配置:

$ kubectl apply -f juicefs-sc.yaml
secret/juicefs-sc-secret created
storageclass.storage.k8s.io/juicefs-sc created           
雲上 K8s 叢集資料持久化方案之 JuiceFS

不難發現,一個存儲類中關聯了一個 JuiceFS 檔案系統。存儲類的數量沒有限制,你可以根據需要建立任意多個 JuiceFS 存儲類。建立多個存儲類時,注意配置檔案中的名稱及資源間的對應關系。

使用 JuiceFS 存儲

成功建立了存儲類,接下來我們建立一個 Nginx 應用并為它挂載聲明的 JuiceFS 存儲。建立配置檔案 nginx.yaml`,添加以下配置:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Pi
  storageClassName: juicefs-sc
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-run
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: linuxserver/nginx
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: /config
              name: web-data
      volumes:
        - name: web-data
          persistentVolumeClaim:
            claimName: nginx-pvc           

執行指令部署應用:

$ kubectl apply -f nginx.yaml

persistentvolumeclaim/nginx-pvc created
deployment.apps/nginx-run created           

應用部署成功以後,在存儲聲明清單中會看到我們在配置檔案中聲明的

nginx-pvc

雲上 K8s 叢集資料持久化方案之 JuiceFS

緊接着在 ACK 控制台為應用建立 service 和 ingress,然後使用平台提供的臨時域名即可通路 Nginx 的歡迎頁面。

說明:由于每個叢集選擇路由方案和設定方法各不相同,具體的設定步驟不做展開。
雲上 K8s 叢集資料持久化方案之 JuiceFS

我們可以在本地計算機上挂載同一個 JuiceFS 檔案系統,裡面是所有已經建立的 PVC 資料目錄。如下圖,紅框标注的是我們剛剛聲明的 PVC 的目錄。

雲上 K8s 叢集資料持久化方案之 JuiceFS

進一步檢視它的目錄結構,可以看到 Nginx 已經在裡面建立所需的目錄和檔案。

$ tree pvc-30873eae-58a1-4722-9911-8e5f2f061347
pvc-30873eae-58a1-4722-9911-8e5f2f061347
├── custom-cont-init.d
├── custom-services.d
├── geoip2db
├── keys
│   ├── cert.crt
│   └── cert.key
├── log
│   ├── nginx
│   │   ├── access.log
│   │   └── error.log
│   └── php
│       └── error.log
├── nginx
│   ├── nginx.conf
│   └── site-confs
│       └── default
├── php
│   ├── php-local.ini
│   └── www2.conf
└── www
    └── index.html

11 directories, 10 files           

我們嘗試在 www 目錄中添加一個新網頁

hello.html

,頁面内容如下:

Hello JuiceFS!           

将通路連結指向新添加的檔案,浏覽器中成功顯示出了我們新添加的頁面!

雲上 K8s 叢集資料持久化方案之 JuiceFS

至此,我們就完成了 JuiceFS 在 Kubernetes 叢集上的安裝和應用測試。

寫在最後

本文介紹了如何使用 JuiceFS 為平台托管的 Kubernetes 叢集提供資料持久化存儲,以阿裡雲 ACK 容器服務為藍本進行了執行個體示範。大家可以舉一反三,參照本文的内容,可以很容易的實作在其他雲平台托管的 Kubernetes 叢集上安裝和使用 JuiceFS。

有關于 JuiceFS CSI Driver 的更多技術細節,請檢視項目首頁:

https://github.com/juicedata/juicefs-csi-driver

如果你有其他疑問,歡迎在評論區給我留言。