GKEコンテナにCloud Storageをマウントしてみた
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リソースの設定のみで簡単にマウントさせる事ができました。
画像だったりの容量の大きな静的ファイルはなるべくマウントしたストレージ上に置くようにする事で、コンテナサイズを縮小できます。これによりデプロイの高速化やコスト削減など良い事ずくめです!
手順も結構シンプルなので、ストレージマウントはどんどん活用していきたいですね。
AUTHOR

朝日放送テレビ株式会社 技術局 技術開発部
動画・広告配信を主に取り組んでおり、その傍らでシステムのモダナイズの提案・支援や開発も担当。アプリケーションからネットワーク・セキュリティ・インフラまで幅広く励んでます!




