privileged なしで GCS を GKE 上にマウントする


はじめに

コンテナに特権(privileged)を与えずに、 GCS を GKE 上にマウントする手順が思ったより複雑だったため紹介する。
が、 Kubernetes リポジトリにある関連 issue1が解決されるまで、 GKE 上で GCS マウントすることはあまりお勧めしない。

もしマウントする場合、下記いずれかのリスクを受け入れることになることに注意してほしい。
1. GCS をマウントするコンテナに privileged を付与する
2. GCS をマウントするコンテナの AppArmor 設定を解除する
3. AppArmor カスタム設定を読み込む privileged を付与された DaemonSet を作成する

GCS を GKE 上にマウントする上での課題

Linux システムにおける GCS のマウントは、 Cloud Storage FUSEページにあるように gcsfuse ライブラリを利用すれば簡単に実現できる。
しかし、このライブラリは /dev/fuse volume を利用してマウントを行っているが、 Kubernetes 上のコンテナにおいて /dev/fuse にアクセスするための標準的な手段は提供されていない。

仮にコンテナに privileged を付与すれば node の /dev/fuse にアクセスできるようにはなるものの、何でもできるコンテナが存在するセキュリティリスクを孕んだシステムになってしまう。これを回避するために、 /dev/fuse にアクセスできる device plugins を実装する必要がある。

smarter-device-manager

smarter-device-manager は IoT デバイスの測定結果をアプリに取り込むために作成された device plugins である。 簡単な設定を行うだけで Kubernetes 上のデバイスドライバーへアクセスできるようになる。

これをデプロイし、 GCS をマウントする Pod における拡張リソース名を「smarter-devices/<volume名>」のように指定すれば、node の /dev 配下の volume にアクセスできる。

privileged なしで GCS マウントするための構成

GKE 上で smarter-device-manager を使って MyApp コンテナ上で GCS アクセスするための構成は下記である。

詳細な構築手順・設定は github 上2で公開されている。
ただし上記の構成では AppArmor の設定を解除するため、My App Pod に下記記述を追加している。

annotations:
        container.apparmor.security.beta.kubernetes.io/<MyApp container名>: unconfined

AppArmor は GKE 上でデフォルトで有効になっているコンテナセキュリティ設定であり、これを解除しないと fuse volume にアクセスする際に permission denied エラーになってしまう。

残課題

apparmor 設定が解除されている

リポジトリ2にあるようにカスタム apparmor 設定を作成することは可能だが、設定をロードするための DaemonSet に privileged を付与する必要がある。これはこの記事のテーマに反するため適用していない。

gcsfuse ライブラリ自体が beta 品質

リポジトリのトップページに記載されているように、 gcsfuse は beta 品質なライブラリである。kubernetes 上でgcsfuse が動かなくなるトラブルのような issue が存在していることを理解した上でこのライブラリを活用する必要がある。

さいごに

「はじめに」で言ったように、 GKE 上で GCS をマウントするのは現時点ではお勧めしない。gsutil や各言語の GCS API を利用した方が、簡単に&品質的に問題のない GCS へのアクセスを実現できる。