Cloud Storage FUSEのCSIドライバによる簡単マウント設定のご紹介
Cloud Storage FUSEとは
Cloud Storage FUSEは、Googleがサポートするオープンソースプロダクトです。Cloud Storage FUSEを使用すると、Cloud Storageバケットをファイルシステムとしてマウントしてアクセスする事ができるようになります。
また、Cloud Storage FUSEのCSIドライバが提供されており、Kubernetes APIを使用して既存の Cloud Storageバケットをボリュームとして使用できます。
今回はこちらを使って、GKEコンテナにCloud Storageをマウントしてみたいと思います!
GKEコンテナへのFUSEマウント実装手順
GKE用Workload Identity連携
まずは、GKE用Workload Identity連携が有効になっている事を確認します。
次に、GKE用Workload Identity連携を使用するようにアプリケーションを構成します。
# アプリケーションで使用するKubernetes ServiceAccountを作成 kubectl create serviceaccount <Kubernetes ServiceAccount名> --namespace <名前空間名> # Kubernetes ServiceAccountを参照するIAM 許可ポリシーを作成 gcloud projects add-iam-policy-binding projects/<プロジェクトID> \ --role=roles/container.clusterViewer \ --member=principal://iam.googleapis.com/projects/<プロジェクト番号>/locations/global/workloadIdentityPools/<プロジェクトID>.svc.id.goog/subject/ns/<名前空間名>/sa/<Kubernetes ServiceAccount名> \ --condition=None # バケットを指定してStorageオブジェクト管理者(roles/storage.objectAdmin)のロールを付与する gcloud storage buckets add-iam-policy-binding gs://<バケット名> \ --role=roles/storage.objectAdmin \ --member=principal://iam.googleapis.com/projects/<プロジェクト番号>/locations/global/workloadIdentityPools/<プロジェクトID>.svc.id.goog/subject/ns/<名前空間名>/sa/<Kubernetes ServiceAccount名> \ --condition=None
さらにPodリソースにて、namespace
と↑で作成したserviceAccountName
を指定します。
apiVersion: v1 kind: Pod metadata: name: test-pod namespace: NAMESPACE spec: serviceAccountName: KSA_NAME containers: ...
これで権限周りは設定OKです!
PodリソースにFUSEマウント用のサイドカーコンテナを追加
Podリソースの実装例
apiVersion: v1 kind: Pod metadata: name: gcs-fuse-csi-example-ephemeral namespace: NAMESPACE annotations: gke-gcsfuse/volumes: "true" gke-gcsfuse/ephemeral-storage-limit: 1Gi spec: terminationGracePeriodSeconds: 60 containers: - image: busybox name: busybox volumeMounts: - name: gcs-fuse-csi-ephemeral mountPath: /data readOnly: true serviceAccountName: KSA_NAME volumes: - name: gcs-fuse-csi-ephemeral csi: driver: gcsfuse.csi.storage.gke.io readOnly: true volumeAttributes: bucketName: BUCKET_NAME mountOptions: "implicit-dirs" gcsfuseLoggingSeverity: warning
gke-gcsfuse/volumes: "true"
を指定する事で、CSIドライバがCloud Storageバケットをマウントできるようになります。
マウントしたいコンテナにvolumeMounts:
を記載して、マウントパスなどを指定できます。
以上で、マウントの設定は完了です。
わざわざDockerfileでマウントコマンドを記載する必要もなく、Podリソース側での定義のみで完結できているのが嬉しいポイントです!
実装にあたってのハマりポイント
実際に導入する中でハマった箇所がいくつかあるので、紹介します。
その1:Podアノテーション指定の記載位置
gke-gcsfuse/volumes: "true"
の記載位置が、Kubernetesワークロードタイプによって異なります。
-
Pod:
metadata
フィールド -
Job / Deployment / StatefulSet :
spec.template.metadata.annotations
フィールド
詳細は公式ドキュメントをご参照ください。
その2:Cloud Storageバケットのアクセス制御設定
Cloud Storageバケットのアクセス制御は「均一」にする必要があります。
「きめ細かい管理」の場合はInput/output error
が出て、アクセスできません。
その3:rootユーザー以外でのマウント
最小権限を考えるとroot以外のユーザーを作成してアクセスするのがベターかと思います。
ただroot以外のユーザーまたはグループを使用する場合は、uid
やgid
などのマウントフラグを記載する必要があります。
volumeAttributes: bucketName: BUCKET_NAME gcsfuseLoggingSeverity: warning mountOptions: "uid=999,gid=999,file-mode=666,dir-mode=766"
まとめ
Cloud Storage FUSEのCSIドライバを使用したおかげで、Podリソースの設定のみで簡単にマウントさせる事ができました。
画像だったりの容量の大きな静的ファイルはなるべくマウントしたストレージ上に置くようにする事で、コンテナサイズを縮小できます。これによりデプロイの高速化やコスト削減など良い事ずくめです!
手順も結構シンプルなので、ストレージマウントはどんどん活用していきたいですね。