既存アプリをK8sなどのコンテナにして動かすには、どこを注意すればいいか..ちょっと調べたときの注意事項をメモにした。
1. The Twelve Factors
- コードベース
バージョン管理されている1つのコードベースと複数のデプロイ
- 依存関係
依存関係を明示的に宣言し分離する
- 設定
設定を環境変数に格納する
- バックエンドサービス
バックエンドサービスをアタッチされたリソースとして扱う
- ビルド、リリース、実行
ビルド、リリース、実行の3つのステージを厳密に分離する
- プロセス
アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する
- ポートバインディング
ポートバインディングを通してサービスを公開する
- 並行性
プロセスモデルによってスケールアウトする
- 廃棄容易性
高速な起動とグレースフルシャットダウンで堅牢性を最大化する
- 開発/本番一致
開発、ステージング、本番環境をできるだけ一致させた状態を保つ
- ログ
ログをイベントストリームとして扱う
- 管理プロセス
管理タスクを1回限りのプロセスとして実行する
2. ソフトウェアデザイン2023年3月号p39-
(原則的な書きっぷりではなく、もうすこし具体性のある書き方をしている記事の要約)
- アプリケーションをステートレスなプロセスとして実行する
- セルフヒーリングなどのK8s機能が使えなくなる場合があるため
- コンテナではないステートフルなバックエンドサービスに保存する
- パブリッククラウドの場合、マネージドなデータストアで永続化する
- 再起動時のコンテナでもファイル利用する場合は、永続化ボリュームをコンテナでマウントする
- グレースフル(優雅)なシャットダウンできるようにする
- シグナルSIGTERMの送信、HTTP GETリクエスト、任意コマンドをkubectl execなど
- コンテナ内で独自プロセスをrunさせる場合はSIGTERMでもシャットダウンできるようにする
- ログは標準出力・標準エラー出力に出力する
- K8sでは永続的にログが保管できないため
- マネージドなモニタリングサービスや、外部のGrafana Lokiなどを使ってログ集約システムを作って送信する
- 環境変数や実行コマンド引数を用意する
- AWS認証系ファイルの指定など環境変数は実行コマンド引数で渡せるようにしておく
- docker run や crictl run の --env などで指定できるようにする
-----
まず市販のRDBMSとかはコンテナであまり挙げないほうがいいのだろう。うごかしてもMySQLなどで済むようなサービスレベルであればいいのだろうけど、そうでない場合はK8sサーバ外にしておくのが無難か。
あとファイルへ書き込む場合はボリュームをつかうこと、これはいわれなくてもわかる。
グレースフルなシャットダウン..Cなどで作ったプロセスだとsignalを実装しておかないと..ファビュラスでないのか..
ログはkubectl logs で見れるようにするには標準出力・エラー出力でないと見れないものなあ..ログ集約システムもコンテナ外で用意しておかないとまずそうだ..
引数やコマンドラインは..これもいわれなくてもやってそうな設計か..
なんにせよコンテナなので1コンテナ1プロセス(RUN)で基本設計して、通常のアプリはprevalegeモードを使わないで動くようにしておかないと..
昔ながらのJavaWebアプリなら、Tomcatをコンテナにして、バックエンドのDBはコンテナにしないで外だし、ラウンドロビンはK8sまかせ..かなにかコンテナをまえにかませる..とかかな..
がっつりDBを外だしにするなら、Kubernetesクラスタの各ノードもサービス系、運用系の2系統のLANをくんだほうがいい。Raspberry Piは幸いにしてWiFiとEthernet2つ同時に使えるので、これは簡単にできる。
ビジネスでKubernetesを本気に使う人たとはRedHatのOpenShiftでつかったりするのだろうけど、ネットワーク構成は結局シビアになるなあ..TakeOverできるように2口×2のNICを刺すんだろうか..