『Kubernetesパターン (第2版)』 メモ
2024年9月に第2版が出た 『Kubernetesパターン』。プログラミングにおけるデザインパターンのように、Kubernetesの実践的な使い方をユースケースに応じて紹介している。あくまで使い方の紹介であり、Kubernetesを内部から理解するための本ではないので、本書冒頭でも運用者よりは開発者向けとある。とはいえ運用者が読んでも、公式ドキュメントよりも現場に沿ったノウハウを得ることができるので、Kubernetesにdeep diveするトピック探しにちょうど良い一冊だと思う。
ということで、読みながら章ごとに気づきや学びを将来の自分に向けたインデックスとして残しておく。
第I部 基本パターン
2. Predicatable Demand
- memoryはrequestのみの指定がよい
- Pod強制停止について、Kubeletとスケジューラは別々の機能として動く。前者はreq/lim -> PriorityClassで、後者はPCのみ考慮する
3. Declarative Deployment
特に新しい情報はなし。
4. Health Probe
- livenessが落ちたらコンテナ再起動、readinessが落ちたらトラフィックを遮断
- 起動に時間のかかるコンテナにはStartup Probeが適切
5. Managed Lifecycle
- postStartはエントリポイントと同時、Initコンテナはエントリポイントの前
- PreStopは失敗してもPodの停止をブロックしない
6. Automated Placement
- まずはlabelによる配置の制御をしよう
- Taint/Trarationはオプトイン、Affinityはオプトアウト
第II部 振る舞いパターン
7. Batch Job
completionMode: Indexedで、Podごとに番号が振られるので、それに応じたタスクの実行ができる。
8. Periodic Job
前のぶんが終わってないときの実行制御は使うときに見ておくとよさそう。startingDeadlineSeconds, concurrencyPolicy
9. Daemonset Service
Daemonsetコントローラと、スケジューラのPodのスケジューリングロジックは別々だったけど、v1.17以降はスケジューラの管理下になってシンプルになった。
10. Singleton Service
ReplicaSetは一貫性よりも可用性を重視するので、強い一貫性を求めるならStatefulSetを使うべき。また複数のアプリケーションが動くコンテナで、一部のアプリケーションにだけシングルトンを適用させたい場合は、アプリケーション内ロックの仕組みを使うと良い。(etcdのような分散ロック)
11. Stateless Service
ステートレスなサービス つまりシンプルなReplicaSetにPVCを付ける場合はPod同士が同じPVCを共有するので、accessModeに注意する。
12. Stateful Service
StatefulSetが管理するPodには、個別にPVCやヘッドレスなServiceを割り当てることができる。また.spec.updateStrategy.rollingUpdate.partitionに数字を指定すると、その数字以上のインデックスを持つPodだけ更新させることができる。
13. Service Discovery
Serviceの使い分け。
- type: ClusterIP 内部通信
- type: NodePort 外部通信
- type: Ingress 外部通信。HTTP向けのルータとして機能する
14. Self Awareness
Dowmward APIを介して、環境変数またはファイル経由でPodのメタデータをコンテナに渡すことができる。後者の場合は値の動的な変化を追従してくれる。前者だと再起動が必要。
第Ⅲ部 構造化パターン
15. Init Container
前後関係をはっきりさせる、正常終了したことを保証するためにも、初期化スクリプトはInit Containerを使おう。Pod起動時に適用されるInit Containerに対して、すでに動作しているPodを制御するためにはAdmission webhookが使える。
16. Sidecar
パターンとしてIstioのような透過的サイドカーと、アプリケーションとAPIでやりとりする明示的サイドカーに分けられる。Daprとか
17. Adapter
Sidecarの一種。異なる実装の複数のコンテナから固有の形式でメトリクスを取りたい場合、アダプタを立てて、メトリクスを取るエンドポイントにする。
18. Ambassador
構成はSidecarだけど、立てるコンテナはメインアプリケーションからの外部リクエスト(キャッシュの取得など)を隠蔽することが目的。
第Ⅳ部 設定パターン
19. EnvVar Configration
containers.envに直接環境変数を埋める方法。$変数名 ですでに定義済みのenvを参照できる。設定がバラバラになるのと、Podの起動後に変更できないので大規模なアプリケーションには不向き。
20. Comfiguration Resource
ConfigMap/Secretsを使う場合でも、更新の反映にはアプリケーションの再起動が必要になる。v1.21からimmutable: trueを指定することで、更新できなくすることができる。明示的に作り変える方が、直接更新するより差分が追いやすくなりそう。
21. Immutable Configuration
immutable: trueを使えばCMでも十分だが、サイズの大きなConfigをイミュータブルに扱いたいとき。Init Container x emptyDir でConfigを用意、マウントさせる方法。管理するimageが増えるのと、環境ごとにinit用のimageを差し替える必要があるのが面倒。
22. Configuration Template
- 環境ごとに変わる値をパラメータ化したテンプレートを用意 (Go templateとか)
- Init Containerでそれを処理して、設定ファイル本体を生成。emptyDirに置く
- アプリケーションでemptyDirを読んで、設定を読み込む
という手順を踏めば、環境ごとの差分だけ管理しつつimageは全環境で同じものを使えるという話。
第Ⅴ部 セキュリティパターン
23. Process Containment
アプリケーションのコンテナがrootユーザーで動いてないかまず確認する。Podにsecurity contextを設定することで、プロセスに関してユーザーや権限に対する制御ができる。v1.25からはPod Security Admission(PSA)として、Namespace全体でその制御をかけることができる。
24. Network Segmentation
NetworkPolicyリソースによって、Label指定でPodへのingress, egressを制御できる。制御はL3, L4のもので、HTTPなどL7レベルで制御したい場合や、NetworkPolicyが複雑になる場合はIstioなどサービスメッシュの導入が効果的である。
こうした制御のために、一貫性のあるLabelの付け方には注意したい。
25. Secure Configuration
Secretsのまま定義を置いておくのはセキュアとはいえないので、以下のような対策を取れる。
- sopsを使ったクライアントサイドでの暗号化
- クラウドプロバイダのSecrets Manager Service(SMS), KMSを使って、生の値をクラスタに置かないようにする (Secrets Storage CSI Provider)
- Vault Sidecar Agent Injectorというサイドカーによる実現方法もある
26. Access Control
Role, RoleBinding, ClusterRole, ...Bindingの話。既存のClusterRole Aを拡張したいときは、それを参照するaggregationRuleフィールドを持つ統合用のClusterRole Xを作ると良い。Xのruleは空にして、拡張したいruleを新しいClusterRole Bとして、Aと同じlabelをつけて作成する。
第Ⅵ部 高度なパターン
27. Controller
ControllerはAPIサーバー経由でリソースの状態を監視し、現場と希望の状態差分を分析、必要ならAPIサーバーを使って行動して、希望の状態に移行させる。
Labelにはインデックスされるので一意に特定するもの、Annontationはインデックスされないので任意のメタデータをそれぞれ入れるとよい。
28. Operator
Controllerの対象は標準リソースだけど、Kubernetes外のドメインロジックをKubernetes上で管理したい場合の選択肢。CRDで独自の型を定義して、必要なRoleを割り当てたコントローラで管理させる。オペレータを実装するためのツールとしてKubebuilderなどがある。
CRDの登録はcluster-adminが必要。
29. Elastic Scale
wedサーバー向けのHPA、0台を許容できるサーバレス向けのKnative、非同期ジョブワーカー向けのKEDA。Podの水平スケールの手段はいつかあるが、アプリケーションコンテナのリソース効率がある程度チューニングされている前提である。
30. Image Builder
OpenShift Buildを使うと、クラスタ内のリソースでimageのビルド&プッシュ、それに応じたPodの更新まで行うことができる。同じビルドオーケストレーションの仕組みはArgo CDなど色々あるし、OpenShift Buildが利用できるコンテナイメージビルダも様々で、これから成長していく領域である。
Discussion