
在 Kubernetes 環境中運行需要持久儲存的應用程式時,可靠且高效能的檔案儲存方案至關重要。Google Kubernetes Engine (GKE) 的 Filestore 提供完全託管的 NFS 服務,專為滿足雲端原生工作負載的需求而設計。
本文將深入探討 Filestore for GKE 的使用方法,為應用程式提供可擴展且彈性的檔案儲存解決方案。我們將探討 Filestore 的優點、使用案例,並引導您完成設定和連接 GKE 叢集的步驟。
GKE Filestore 是一項全託管式檔案儲存服務,專為 Google Kubernetes Engine (GKE) 設計,讓你的應用程式可以輕鬆、高效地共享檔案。它基於 Google Cloud Filestore,提供高性能、可擴展且可用的網路檔案系統 (NFS),非常適合需要持久儲存和共享資料的應用程式。
使用 GKE Filestore,你可以:
GKE Filestore 非常適合以下應用場景:
GKE Filestore CSI 驅動程序會創建 StorageClass 以滿足您的特定需求。但是通常為了方便控制 Filestore 所在的 VPC 及底下的 PRIVATE_SERVICES_ACCESS(私人服務存取權),通常會客製化製作自己所需的 StorageClass。
下表比較了 Filestore 企業多共享性能與單共享選項:

| 服務層級 | Tier | GKE StorageClass | 每個實例的共享數 | GKE PVC 大小 | Filestore 容量 | 增量更改 | 部署 | 訪問模式 | 
|---|---|---|---|---|---|---|---|---|
| 基本 HDD | standard | 
standard-rwx | 
一個 | 1 TiB 到 64 TiB | 1 TiB 到 64 TiB | 1 GiB | 可用區級 | 讀/寫多次 | 
| 基本 SSD | premium | 
premium-rwx | 
一個 | 2.5 TiB 到 64 TiB | 2.5 TiB 到 64 TiB | 1 GiB | 可用區級 | 讀/寫多次 | 
| 大型企業 | enterprise | 
enterprise-rwx | 
一個 | 1 TiB 到 10 TiB | 1 TiB 到 10 TiB | 256 GiB | 區域級 | 讀/寫多次 | 
| 具有多共享功能的企業版 | enterprise-multishare-rwx | 
enterprise-multishare-rwx | 
最多 80 個 | 10 GiB 到 1 TiB | Filestore 實例池,每個實例的大小為 1 TiB 到 10 TiB 大小 | 
每個 Filestore 實例最多托管
80 個 PV(共享),每個共享的大小為 10 GiB 到 1 TiB | 每個實例 256 GiB
每個 PVC(共享)1 GiB | 區域級 | 讀/寫多次 |
先在 VPC 創建 **PRIVATE_SERVICES_ACCESS(私人服務存取權),**並連接到 servicenetworking-googleapis-com Private connections to services(私人服務連線),以下只指令創建
$ gcloud config set project $PROJECT_ID
$ gcloud compute addresses create $NAME \
    --global \
    --project=$PROJECT_ID \
    --purpose=VPC_PEERING \
    --addresses=$IP_ADRESS \
    --prefix-length=24 \
    --description="$description" \
    --network=$NETWORK \
&& gcloud services vpc-peerings connect \
    --service=servicenetworking.googleapis.com \
    --ranges=$NAME \
    --network=$NETWORK
到 VPC 頁面查看 PRIVATE_SERVICES_ACCESS(私人服務存取權),可以看到已經創建出來了,並且連接到了 Private connections to services(私人服務連線)


接下來將 GKE 的filestore_csi_driver 打開,如果 GKE 是使用 Terraform 建立的,將 filestore_csi_driver 參數改成 true
module "gke" {
  gcs_fuse_csi_driver = true #Cloud Storage FUSE CSI 驅動程式
}
在 GKE Cluster UI 頁面確認有打開 Filestore CSI 驅動程式

到 APIs & Services 頁面,啟用 Cloud Filestore API 及 Service Networking API


建立客製化的 Filestore StorageClass,此  Filestore 使用基本 SSD,所在的 VPC 為 ithome-202409-demo-vpc,PRIVATE_SERVICES_ACCESS(私人服務存取權) 為 private-service-connect-c1,以下就使用 服務級別為enterprise 來做示範,如需要使用其他的 Filestore 只需要修改以下 StorageClass Yaml 檔案的 tier 欄位。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: filestore-enterprise-rwx-demo-pvc
  namespace: example
spec:
  # 選擇所要使用的 storageClassName
  storageClassName: filestore-enterprise-rwx
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      # The min size is 1Ti for enterprise-rwx storage class.
      storage: 1Ti
deployment.yaml 掛載剛剛創建的 filestore-enterprise-rwx-demo-pvc,以及其 service.yaml 和 ingress.yaml。
這裡使用的a51907/path-download:v1鏡像是一個前端網頁,會顯示目錄中的檔案,並且可以下載目錄中的檔案,環境變數 MOUNT_PATH 為需要顯示的目錄。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: filestore-demo
  namespace: example
  labels:
    app: filestore-demo
  annotations:
    reloader.stakater.com/auto: "true"
spec:
  selector:
    matchLabels:
      app: filestore-demo
  template:
    metadata:
      labels:
        app: filestore-demo
    spec:
      volumes:
        - name: storage
          persistentVolumeClaim:
            claimName: filestore-enterprise-rwx-demo-pvc
      containers:
        - name: filestore-demo
          image: a51907/path-download:v1
          env:
# 這裡將環境變數 MOUNT_PATH="/mnt/nfs",此鏡像就會去找/mnt/nfs目錄下的檔案
            - name: MOUNT_PATH
              value: "/mnt/nfs"
          imagePullPolicy: Always
          volumeMounts:
            - name: storage
              mountPath: /mnt
          resources:
            requests:
              cpu: 1m
              memory: 10Mi
            limits:
              cpu: 100m
              memory: 100Mi
          ports:
            - containerPort: 3000
              protocol: TCP
          readinessProbe:
            tcpSocket:
              port: 3000
          livenessProbe:
            tcpSocket:
              port: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: filestore-demo-service
  namespace: example
spec:
  type: ClusterIP
  selector:
    app: filestore-demo
  ports:
    - protocol: TCP
      port: 3000
      targetPort: 3000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: filestore-demo-ingress
  namespace: example
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-demo
spec:
  ingressClassName: external-nginx
  tls:
    - hosts:
        - filestore-demo.demoit.shop
      secretName: filestore-demo-tls
  rules:
    - host: "filestore-demo.demoit.shop"
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: filestore-demo-service
                port:
                  number: 3000
使用指令查看 PersistentVolumeClaim kubectl get pvc -n example
$ kubectl get pvc -n example      
NAME                                STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS               VOLUMEATTRIBUTESCLASS   AGE
filestore-enterprise-rwx-demo-pvc   Bound     pvc-7e334328-3727-4c40-ac05-68f82c37c7b4   1Ti        RWX            filestore-enterprise-rwx   <unset>                 3m
可以到 GCP Cloud Filestore 頁面找到剛剛使用 GKE 建立的 PVC 後面的 Filestore,可以看到其 IP 位置為 10.238.1.194,在我們 VPC 切出的 PRIVATE_SERVICES_ACCESS(私人服務存取權) CIDR 內。

建立一個 Compute Engine,**Identity and API access(身分及 API 存取權)**要記得打開,掛載剛剛建立的 Filestore(10.238.1.194) ,修改內部的檔案,進入同一 VPC,或是可以互通的 VPC 的 VM內,輸入以下指令

$ sudo apt-get -y update
$ sudo apt-get -y install nfs-common
$ sudo mkdir -p /mnt
# 進入 Filestore 詳細頁面查看掛接點
$ sudo mount 10.238.1.194:/vol1 /mnt && sudo chmod go+rw /mnt
# 輸入完以上指令,輸出如下就是成功了
Created symlink /run/systemd/system/remote-fs.target.wants/rpc-statd.service → /lib/systemd/system/rpc-statd.service.
NFS 掛接點可以進到 Filestore 詳細頁面查看,這裡的接點為 10.238.1.194:/vol1

以上操作會將虛擬機的 /mnt 目錄掛載到這顆 Filestore 硬碟,也就是對應到 filestore-demo-deployment 中的 /mnt,我們在虛擬機內使用以下指令創建 /mnt/nfs 目錄,及其下的檔案,接下來再到容器中查看檔案是否有出現
# 進入 VM 中輸入以下指令
$ mkdir /mnt/nfs
$ touch /mnt/nfs/2024-ithome-andrewchen-demo.txt
$ touch /mnt/nfs/andrewchen930511-demo.txt
# 進入 Pod 中輸入以下指令
$ touch /mnt/nfs/pod-create-file
接下來進入容器中及 Ingress 網址,因為我有使用 external dns,所以 DNS 紀錄會自動添加,可以查看 Day9 教學。
同時打開網頁,一開始 /mnt/nfs 目錄下沒有檔案

在 VM 中創建 /mnt/nfs/2024-ithome-andrewchen-demo.txt檔案後,可以看到 Pod 中也出現該檔案,刷新網頁後也會顯示目錄下的檔案出現

再到 Pod 中創建 /mnt/nfs/pod-create-file檔案後,會發現 VM 也會同步出現該檔案,刷新網頁後也會顯示目錄下的檔案出現

GKE Filestore 提供了一個簡單且可擴展的方式,讓 GKE 應用程式可以存取完全託管的網路檔案儲存。Filestore 支援多種效能層級,從標準檔案共用到高階檔案共用,滿足不同工作負載的需求,無論是需要高吞吐量的媒體處理應用程式,還是需要低延遲的資料庫應用程式。
透過簡單的 YAML 設定,可以將 Filestore 持久磁碟區動態掛載到您的 Pod 中,讓應用程式可以如同使用本地儲存一樣存取檔案。GKE Filestore 也可以和多個 Pod 及 VM 掛載同一個 Filestore 硬碟來達成資料的同步,如果上述示範的一樣。
筆者寫了一個程式的鏡像,讀者可以使用 a51907/path-download:v1 此鏡像來進行實驗,很方便地在前端網頁觀察到掛載的 Filestore 目前的檔案狀態。