‫これまでKubernetesでは､ ストレージやボリュームについてあまり議論してきませんでした｡
‫Dockerで対応し､ Composeで対応し､ Swarmで対応し､
‫ある程度はKubernetesでも同じような対応をしていますね｡
‫コンテナを持っていますが､ コンテナはステートレス､
‫つまりコンテナを捨てると中のものがすべて消えてしまうと仮定します｡
‫コンテナをアップデートで置き換えたり､ 何かを変更してkubectlのapplyで適用すると､
‫コンテナが失われ､ その中にあるものすべてが失われるのです｡
‫もちろん､ Kubernetesも他のオーケストレーターと同様に､
‫永続的なデータを保持する方法を持たなければなりません｡
‫巻数そのものよりも､ もっと多いんです｡
‫コンテナやデプロイメントも､ KubernetesではStatefulSetsと呼ばれるものを使って､
‫異なるものにすることができます｡
‫これらは､ デプロイメントとは異なるリソースです｡
‫基本的には､ データベースや､ 同じ名前､ 同じIPなど､ より多くの永続性を必要とするものを対象として設計されています｡
‫SwarmやDockerでは､ 必ずしもそのようなことはありませんでした｡
‫コンテナ間で異なる属性を保持する方法がなかったんです｡
‫StatefulSetsはKubernetesの新機能で､
‫ここに来てまだ少ししか出ていない｡
‫データベースや､ 名前､ IPアドレス､ ボリューム､
‫永続的なデータなど､ 変更に非常に敏感なものを検討する場合に見るべきものです｡
‫ここでひとこと｡
‫その詳細をあまり説明しないのは､ Kubernetesの最初のデプロイでStatefulSetを大量に入れるのはお勧めできないからです｡
‫実際､
‫理想的には､ オーケストレーターの最初のデプロイは､ それがSwarmであれKubernetesであれ､
‫ステートレスにしか関わらない､ つまりシンプルに保つことです｡
‫WebフロントエンドやAPI､
‫ワーカー機能など､ データベースを介さないものだけでいいかもしれませんね｡
‫実際､
‫クラウドデータベースが使えるのであれば､ そうしてください｡
‫私は､ 自社で運用する上でどうしても避けられない特別な要件がない限り､
‫データベースのアウトソーシングを常に推奨しています｡
‫オーケストレーションは当初､
‫コンテナが不変であり､ 分散され､ 交換可能であることを前提に設計されました｡
‫このステートフルネスのためのスティッキネスという考え方は､ より多くの作業と複雑さ､
‫そして多くのテストを追加することになるでしょう｡
‫理想を言えば､
‫アウトオブゲートでは､ このような心配をする必要はありません｡
‫その後､ Kubernetesを取り巻く他のすべてのことに慣れてきたら､
‫今度はデータベースのことを考えたいと言ってください｡
‫データベースをクラスターで運用してはいけないということではありません｡
‫仕事が増えるだけです｡ もっと大変だ｡
‫データベースや永続的ストレージは､ 常に難しく､ 細部にまでこだわります｡
‫これが私のプロとしてのアドバイスです｡
‫どのコンテナでも､ SwarmやDocker､ Docker Composeで行ったのと非常によく似た方法で､
‫ボリュームを追加することができます｡
‫spec内部のテンプレートにvolume文を追加すればいい｡
‫YAMLファイルを思い浮かべれば､
‫そこに期待通りのボリュームを入れればいいわけで､
‫正確なフォーマットや詳細はリソースに書いてあります｡
‫DockerやSwarmのようにボリュームがコンテナと一緒なのとは違い､
‫今回は厳密にはポッドと一緒です｡ ポッド内の各コンテナ､ または1つのコンテナに接続するように指示すれば､
‫そのコンテナに接続することができます｡
‫つまり､ コンテナレベルで制御しているのに､ ポッドレベルで永続化されているわけです｡
‫新しい機能として､
‫パーシステントボリュームというものがあります｡
‫それはクレームと呼ばれる別のもので機能します｡
‫これの面白いところは､ ポッドの外でそれを使っている､
‫あるいは定義しているところです｡
‫基本的には､
‫そのリソースを独自に作成し､ ポッド仕様の中でそのリソースに対してクレームをつけることになるのです｡
‫Kubernetesがエンタープライズを支配するようになると､
‫ストレージを担当する人が出てきますが､ 多くの場合サードパーティのストレージで､
‫Kubernetesを実行しているチームとは別の人が担当することになります｡
‫このような永続的なボリュームの管理と作成に携わるのは､
‫彼らなのです｡
‫そして､ アプリケーションデプロイヤーが､ このタイプのボリュームが必要だと言うのです｡
‫だから､
‫SSDの主張をするのか､ RAMストレージが必要かもしれない､ NFSが必要かもしれない､
‫とかね｡ そのストレージは､ ストレージチームがすでにKubernetesで設定しているため､
‫自動的に提供されます｡
‫それがパーシステントボリュームにまつわる考え方です｡
‫もし､ ポッドのために一時的に1台のサーバーに簡単なストレージが必要なだけなら､
‫標準のボリューム属性を使用すればよいのです｡
‫ここで最後にもう一つ､ CSIプラグインの作成についてです｡
‫Kubernetesの歴史では､
‫クラウドストレージであれ､ サードパーティベンダーのストレージであれ､ カスタムであれ､ そういうものはすべてツリーで追加していました｡
‫つまり､ Kubernetesのバイナリに追加され､ Kubernetesと一緒に出荷されたのです｡
‫つまり､ KubernetesにはAmazonとAzureのストレージが最初から組み込まれていたのです｡
‫それはとても便利なのですが､ その分､ 課題もたくさん増えました｡
‫そのほとんどは､ ストレージベンダーがシステムのコアにコードを提供するようになったという事実に関連するものでした｡
‫なぜなら､ あなたはたった1社のストレージベンダーしか使っていないのに､ なぜすべてのベンダーを使う必要があるのでしょうか？
‫また､ その場合､ ストレージベンダーはKubernetesのリリースサイクルに合わせてリリースサイクルをコントロールしなければならず､
‫あまり柔軟なモデルとは言えませんでした｡
‫そこで､ 業界が一丸となって､ ネットワークやDockerfile､
‫イメージそのもののように､ 標準を作り上げたのです｡
‫その基準がCSIなのです｡
‫Container Storage Interfaceの略です｡
‫プラグインを提供することで､ ストレージベンダーがプラグインを作成し､
‫すべてのノードにインストールすることができます｡
‫そして､ CSIが提供する標準的なAPIで操作することで､ どのコンテナもそのプラグインを使用してストレージにアクセスできるようになります｡
‫その方がずっといいし､ 柔軟なモデルだと思います｡
‫これはKubernetesの未来の姿のようなものですが､
‫まだかなり新しいものです｡ そのため､ 例ではよく､ ストレージベンダーも､
‫CSIの成熟度によっては､ Kubernetesに組み込まれていて､
‫すぐに使える従来のプラグインを使うよう勧めることがあります｡