この記事は CyberAgent Developers Advent Calendar 2016 の3日目の記事となります。
では早速本題に。
やろうと思ったわけ
思い立ったからです。
とか言う冗談はいいとして。
Cloud Storage上に対象のファイルが存在した場合、そのファイルを返す。という仕組みを作ろうと思いました。
真っ先に思いつくのはアプリでファイルの存在確認後、存在したらそれを返すというものでした。
が、少し違うアプローチで、FUSE(Filesystem in Userspace)のGCS対応しているgcsfuseを使用してコンテナに マウントしてnginxで返す、という構成をやってみようということになりました。
この仕組みでいけば
- アプリの実装がいらない
- アプリが死んでてもレスポンスが返せる
という感じで利点が見え、検証してみることに。
コンテナの作成
フロントに置くnginx兼gcsfuseでフォルダにマウントするコンテナを作ります。
Dockerfile書く。
以下が作成したDockerfile。
|
|
ベースにAlpine Linux使っています。 簡単には
- 動作に必要なライブラリとnginxのインストール
- gcsfuseのビルド
- コマンドだけパスが通っているところに移動
- 不要なファイル・パッケージの削除
- entrypointとなるシェルのコピー
という感じです。
entrypoint用のシェル
コンテナ起動時に実行されるシェルの内容です。
|
|
このシェルでは
- マウントポイントの作成&マウント
- nginxがrootとするパスにシンボリックリンクを作成
- nginxをフォアグラウンドで起動
- 終了時にアンマウント
という感じです。
でてきた問題点
ローカルでBuildしてテストしていたところ、問題点が出てきました。
Cloud Storageをマウントする際にgcsfuseがOperation not permittedといってマウントしてくれません。 Dockerはデフォルトでコンテナがあらゆるデバイスに対してのアクセスを許可していないためでした。
このため、このコンテナを起動する際には
- –privilegedオプションを使用して起動
- –cap-addで適切な権限のみを付与して起動
をする必要があるようです。 今回は–privilegedオプションを渡して起動してみます。 (–cap-addについては記事書いてる最中に知った・・)
Kubernetesの設定ファイルの作成
Secret
GCPでサービスアカウントを作成し、その秘密鍵のJSONファイルをSecretを使ってKubernetesに渡します。
|
|
ReplicaSet
ReplicaSetの設定ファイルを作ります。
|
|
このReplicaSetは次世代のReplication Controllerだそうです。 といっても違いはselectorのサポートで、matchExpressionsが使えるようになったことぐらいみたいです。
要点としてはsecretでKubernetesに渡している情報を/etc/gcs
にマウントしています。
また、このコンテナのsecurityContentのprivilegedをtrueにしてマウント操作を許可するようにしています。
Service
Serviceは普通です。
|
|
GCPのLoadBalancer機能で先程作ったReplicaSetのPodにアクセスできるようにしています。
適当に検証
コンテナ、Kubernetesの設定ができたのでabコマンドで検証してみます。 Zoneはasia-northeast1-aです。
クラスタ名 | インスタンスタイプ | ディスクサイズ |
---|---|---|
Cluster1 | n1-standard-1 | 100GB |
Cluster2 | n1-standard-1 | 300GB |
Cluster3 | n1-standard-4 | 100GB |
Cluster4 | n1-standard-4 | 300GB |
上記のクラスタにデプロイしてみて500リクエスト、並列数10でリクエストを送ってみて、 10Byteほどのテキストファイル(File1)と300KBほどの画像ファイル(File2)をレスポンスとして返してもらいます。
Requests per second
クラスタ名 | File1 | File2 |
---|---|---|
Cluster1 | 12.985 | 59.364 |
Cluster2 | 12.320 | 46.882 |
Cluster3 | 8.962 | 45.347 |
Cluster4 | 5.422 | 45.114 |
Time per request
クラスタ名 | File1 | File2 |
---|---|---|
Cluster1 | 12.985 | 59.364 |
Cluster2 | 12.320 | 46.882 |
Cluster3 | 8.962 | 45.347 |
Cluster4 | 5.422 | 45.114 |
所感
思ったよりも捌けている・・・。
ローカルで動作させていたときはlsするだけでも1秒とかかかっていて、Webのリクエストについても1,2秒ほど かかっていたのですが、GKE上で動作させたら普通に許容できるくらいには捌いていますね。
まとめ
本当にザッとですが、構築と簡単な検証をやってみました。 要点としては、
- mount操作するコンテナはprivilegedでの起動が必要
- そこそこ捌ける
という感じでした。 ただ、プロダクション環境に導入するか?という問があったとすると、privilegedで起動するコンテナがあったり、 そもそもgcsfuseはGoogleがメンテナンスを保証しておらず、ベータ版からGA版に移行するつもりがないようなので 選択肢としては無しな気がします。
ちょっと悲しい終わり方ですが、以上になります!!
明日のCyberAgent Developers Advent Calendar 2016もお楽しみください!
ちょっとだけ追記
privilegedで起動してしまうとコンテナでほとんどのことが出来てしまうようなので、 cap-addオプションとsecurity-optオプションを使って権限を絞りつつマウント操作を行えるようです。
|
|
一気にマウント処理までやっちゃってますが、エラーでなければ成功です。 selinuxなど使用している場合はsecurity-optオプションが必要です。
追記以上でした〜。