このブログを構築する際に、GCSにブログ記事のファイルなどをアップロードし、GKEのPodにマウントすることで記事の配信をしたいと考えていました。
その際に、公式のCloud Storage FUSE CSI ドライバを使用して Cloud Storage バケットにアクセスするを参考にマウントを実装したのですが、ガイドのボリュームが多く、また実装する上でいくつか気を付けることがあったので、こちらに残したいと思います。
主なコードはこちらにアップロードしています。PersistentVolumeにて実装しました。
おおまかに以下の手順で実装しています。
roles/storage.objectUserのロールを割り当てPersistentVolume、PersistentVolumeClaimを作成してPodに紐づけるちなみにですが、GKE Autopilotのバージョン1.24以上を使っているので、Cloud Storage FuseのCSIドライバを有効にするステップは飛ばしています。
GKEのPodでNextJSのフロントエンドアプリを動作しており、こちらのようなDockerfileの構成をしています。
nodejsをコンテナ内で実行するときに、nexjsユーザーで実行しているため、マウントしているGCSの領域についても権限変更をしないとroot扱いとなるため読み込みができなくなります。
ガイドの考慮事項にも記載がありますが、以下のようにPersistentVolumeのspec.mountOptionsにてuid, gid, file-mode, dir-modeを設定することで適切な権限に変更することができます。
apiVersion: v1 kind: PersistentVolume metadata: name: gcs-fuse-csi-pv spec: accessModes: - ReadWriteMany capacity: storage: 20Gi storageClassName: shanari-storage-class mountOptions: - uid=1001 - gid=1001 - file-mode=755 - dir-mode=755 - implicit-dirs csi: driver: gcsfuse.csi.storage.gke.io volumeHandle: shanari-blog-posts volumeAttributes: gcsfuseLoggingSeverity: warning
uidとgidについてはDockerfileで設定したidをそれぞれ設定します。
均一にする権限設定を実施しても、Error: EIO: i/o error, readのようなエラーが発生し、GCS内のファイルにアクセスできないようでした。
また、GKEのログを確認したところ、ReadFile: input/output error, fh.reader.ReadAt: startRead: NewReader: googleapi: got HTTP response code 412 with body: <?xml version='1.0' encoding='UTF-8'?><Error><Code>PreconditionFailed</Code><Message>The operation requires that Uniform Bucket Level Access be enabled.</Message><Details>The type of authentication token used for this request requires that Uniform Bucket Level Access be enabled.</Details></Error>というようなエラーも出力されていました。
こちらについては、トラブルシューティングガイドにも記載されているのですが、GCSの対象のバケットのアクセス制御がきめ細かい管理の場合に発生するようでした。
権限より均一に変更することで、対象のファイルにGKEからアクセスできるようになりました。