下記勉強会のメモ
- Kubernetesで実現する高可用性システム -- cndjp第3回
Kubernetes x 可用性 4箇条
1.レイヤ分けして考える
2.マイクロサービスアーキテクチャとKubernetesは好相性
3.リリースの安定はサービスの安定
4.インフラの選定はクラウドで
1.レイヤ分けして考える
マイクロサービスエコシステム
- Susan J. Fowlerの「マイクロサービス・エコシステム」
|マイクロサービス|
|アプリケーションプラットフォーム|<--CI/CD
|通信|<--サービス間の通信:RPC,APIエンドポイント、サービスディスカバリ、サービスレジストリ
|ハードウェア|
CI/CDや監視系の部分もk8sに絡んでいる部分がある
マイクロサービスの部分も同様、k8sの機能を組み合わせて高可用性を実現
レイヤごとに障害対策を考える
横で層を分けてそれぞれの項目について優先度を決めて処置を講じる
2.マイクロサービス・アーキテクチャとk8sは好相性
マイクロサービス・アーキテクチャって
- 大規模なシステムを小規模なサービスの組み合わせて実現するアーキテクチャ
- 複数のサービス群をHTTP(s)、RPC、非同期メッセージングなどにより疎結合に連携
- 変更の影響範囲をサービスにとどめることで、頻繁なアップデートを実現する
- 一個のバグ直すのにリリースなかなかできないことを避けるとか
- モバイルアプリのようにどんどん新しい機能入れたりとか
参考)マイクロサービス・アーキテクチャのトレードオフ
言葉とメリットが先行していたが、トレードオフがあるのはだいぶ定着してきたイメージ
MSA on k8sで可用性を考える時のポイント
- 各サービス単体としての可用性にフォーカスする
- 小規模に分かれている分だけやりやすい
- 例えば古典的な3総アプリの鯉宇正なら、従来と同じプラクティスが使える
- k8sの機能をうまく活用する
- サービスの境界(サービス同士の連携個所)に対策を施す
- MSAならではの考慮点
- サービスメッシュをうまく使う
サービス境界で起きる障害の例
- 例)サービス障害の連鎖
- シナリオ
- サービスAから依存されるサービスBで障害が発生
- サービスAでサービスBの応答町のスレッドが累積
- スレッドが枯渇し、サービスAがリクエストに応答できない状態に(障害連鎖)
- サービスBへのアクセス集中が解消しないため、サービスBが復旧困難に
- 対策
- ヘルスチェック
- サーキットブレーカー
- シナリオ
ヘルスチェックとサーキットブレーカー
- サーキットブレーカー
- リクエストに対する応答状態が一定の条件を満たした場合に、障害が発生したものとみなして、そのサービスへのリクエストを遮断する機構
- ヘルスチェック
- サービスの稼働状態を他サービスから確認するためのI/F
- ヘルスチェック応答の結果を見てサーキットブレーカーを開くなどの判定を行う
境界に適用する障害対策の例
- その他の例(代表的なもの)
- バルクヘッドパターン
- 補正トランザクションパターン
- いくつかのサービスをまたがってサービスの更新をしてそれぞれの更新が一貫性を保たなければいけない場合にどこかでこけたらロールバックする仕組み
- 参考資料
- Building Fault Tolerant Microservices:
- Azureアーキテクチャセンター >クラウドの設計パターン >回復性のパターン:
サービス・メッシュを使ったサービス境界の障害対策
- サービスメッシュを利用するとサービス境界の障害対策を簡単に導入できる
- k8s+ Istio/Linkerd
- Istioの定義では明確にサービスブレーカやリトライやカナリアをやることが述べられている。
- 次回kwskやる
各サービスの可用性にフォーカスする
- 小規模な分だけやりやすくなっているはず
- 従来型の障害対策を実装する
- SPOFがないか
- 障害時の回復性が十分か
- k8sの機能をうまく利用する
- スケールアウト型/分散型アーキテクチャのMWを積極利用
- Cassandra/Kafka...
- Podのスケーリングを活用して可用性構成を容易に実装
- スケールアウト型/分散型アーキテクチャのMWを積極利用
Web3層アーキテクチャの場合
- セッションステートの分離
- アプリケーションがセッションを持つことがありうまくスケールできないのでRedisのようなインメモリストレージに保存してスケールできるようにする
- こういうことは古くから、クラウドがはやる前からやられている
- Redis, GemFire...
- これをやるとB/G Deployができるというメリットも出てくる
- あとはMaster/SlaveがたのクラスタでDBを動かす
- k8sのPodの拡張やStatefulSetを使うと簡単に作成可能
- 余談)1.9でGAになったばかりでまだ使われはじめ
- R/Wのマスタが落ち、どれかがMasterに昇格したあとにマスタが復旧しても大丈夫
- k8sのPodの拡張やStatefulSetを使うと簡単に作成可能
StatefulSet
k8sの一つのオブジェクト
- Podに連番の名前が与えられる
- 永続領域、ネットワーク上の名前がPodに紐づけて管理される
- 障害復旧時、永続領域とNWの構成を保持したまま復旧する
SMKACKスタックの場合
- Kafkaクラスタの例
- Queueを分散して持っていてそれぞれがレプリカを持つ
- k8sの機能により自動的に再起動
- 永続性やNW構成を維持したまま復帰する(Stateful)
Podの一部が落ちた程度では問題ない程度の可用性が高い基盤を作れる
SMKACKスタックの場合
- SMACK
- Spark
-
Mesosk8s - Akka
- Cassandra
- Kafka
水平分散型アーキテクチャが基本
ハンズオン(1)
- Apache Kafkaを利用したチャットアプリケーションを、Kubernetes上にデプロイ
3.リリースの安定はサービスの安定
アプリケーションプラットフォームの話
なぜリリースと可用性が関係するか
- リリース->可用性に対するリスク
- リリースは本番環境に変更を加えること
- 変更は傷害のリスク
- MSAは頻繁にリリースされる
- よいリリース
- リリースするものがバグを含まない = 十分なテスト
- lint、単体テスト、結合テスト、e2e
- ステージング(負荷、カオステスト含む)、カナリー
- テスト、リリース作業でミスをしない = 自動化
- デプロイメント・パイプライン
- リリースするものがバグを含まない = 十分なテスト
デプロイメント・パイプラインの定義
Oracle/worker
Istioを使ったカナリーデプロイメント
- Istioを使うとリクエストの流量を細かく設定可能
- カナリーのコンテナを増やさずに、流量だけを徐々に増やすなど
4.インフラ選定はクラウドで
Kubernetsの可用性構成
- マスターノードの冗長構成をとることで、コントロールプレーンをすべて冗長化
- etcdのクラスタリング
- 自分で組むのはやめたほうが良い(と思う)
- apiserverのクラスタリング
- etcdのクラスタリング
Multi Zone構成
- 主要クラウドベンダーが提供するマネージドk8sサービスは、Multi Master構成をサポート
- AKS
- GKE
- OpenShift Online
- Zoneにまたがってマスター/ワーカーノードを配置してくれるものも
- GKE
- OpenShift Online
Orcaleもk8sのマネージドサービスをリリース予定
障害時を忘れずにサイジング
- Kafkaなどノード障害後にデータリバランスを行う場合は、その時の負荷を考慮したサイジングが必要
- CPUリソース、NW待機、ストレージ速度
- 障害復旧時間に影響するケースもある
- クラウドサービスでは、性能が不安定なケースもあるので注意
- VM同士の帯域の保証がない
ハンズオン(2)
- Kubernetes上にデプロイしたチャットアプリケーションに対して、カオステストを実施
次回予告
- Kubernetes Network Deep Dive!
お知らせ
- Slackチャネルにぜひご参加ください