HN 日本語サマリー

← 一覧へ戻る
インフラ・DevOps

VM上でKafkaを運用して学んだシステム思考のこと

What Running Kafka on VMs Taught Us About Systems Thinking (engineering.moniepoint.com)

5 pointsby yeame4 コメント

要約

Moniepointのインフラチームは、VM上で手動管理されていたKafkaの運用に限界を感じ、StrimziとKubernetesを導入しました。この移行により、運用の自動化、一貫性の向上、スケーラビリティの改善が実現し、インシデント発生前の問題予測と proactive な対応の重要性を学びました。

全文翻訳

backInfrastructureJuly 10, 202610 mins readVM上でKafkaを運用して学んだシステム思考のことby Celestina Amadiほとんどのインフラストーリは、何かが壊れた後に書かれます。この記事は違います。Celestina AmadiのチームはKafkaのことで午前3時に呼び出されることはありませんでした。VMは動作していましたが、問題になる前に状況がどうなるかが見えていたため、彼女は再構築を決断しました。Celestina Amadiは、Moniepointの決済および貯蓄プロダクトを支えるインフラストラクチャの背後にあるクラウドエンジニアリングチームを率いており、毎日何百万人もの顧客のためにトランザクションおよび貯蓄データを確実に移動させるシステムを構築しています。彼女はまた、Grafana Champion、HashiCorp Ambassador、そしてIBM Champion 2026でもあります。 ━━━━━━━━━━ なぜStrimziに移行したのか 危機ではなく、決断でした。 私たちは、Kafkaをどのように運用しているかを正直に見つめ、明確な決断を下したため、Strimziに移行しました。この決断は、「これはスケールしない、もっとうまくやれる」というものでした。 このような決断は、危機に対応するよりも actually 困難です。インシデントは明白です。何かが壊れ、それを修正します。プロアクティブなアーキテクチャ変更には、災害になる前に不快感に対して行動できるほど明確に見る必要があります。それは、「これは機能しているが、十分ではない」と言い、それを真剣に受け止めることを要求します。 これは、私たちが何を見て、何を構築し、そしてシステム思考について何を学んだかの物語です。 以前のKafkaの運用方法 私たちのKafkaセットアップは、多くのことがそうであるように、急速に進化するエンジニアリングチームの中で、実用的に始まりました。 CDCパイプラインが必要でした。データベースAからKafkaへ、そしてデータベースBへ、データベースCからKafkaへ、そしてデータベースDへとデータを移動させる必要がありました。複数のパイプラインがあり、それぞれが異なるビジネスフローを phục vụ していました。私たちはVM上にKafkaインスタンスを起動し、必要に応じてDocker Composeで管理しました。それらは機能しました。私たちは次に進みました。 時間が経つにつれて、ほころびが見え始めました。 すべての変更にはSSHとポートフォワーディングが必要でした。私たちのKafkaインスタンスにはURLがありませんでした。localhost経由でアクセスしていました。ソースコネクタの追加、シンクの追加、設定の更新など、どのような変更を行うにも、サーバーにSSHで接続し、ローカルアクセスを取得するためにポートフォワーディングを行い、手動で変更する必要がありました。毎回。すべてのインスタンスで。 Docker Composeでは、ダウンタイムは常に1つのコマンドの先にありました。Docker ComposeでKafkaを管理することは、機能しなくなるまで機能します。スタックの再起動が必要な更新または修正は、`docker compose restart`を実行し、再起動がクリーンに行われることを願うことを意味しました。データパイプラインにとって、それは快適な状況ではありません。 バージョンが古くなり、インスタンスごとの更新が必要でした。Kafkaは進化します。新しいバージョンがリリースされました。しかし、各インスタンスは個別のVMとして独立して管理されていたため、アップグレードするには各インスタンスに個別にアクセスする必要がありました。さらに悪いことに、私たちのインスタンスは一貫性さえありませんでした。一部はZooKeeper上で実行され、一部はKafkaの進化とともにRaftを採用していました。異なるコンセンサスモデル、異なる運用動作、何かを触る前に知っておくべき異なること。 新しいパイプラインのプロビジョニングは、車輪の再発明を意味しました。標準的なプロセスはありませんでした。共有設定もありませんでした。新しいCDCパイプラインは、決定の新しいセットでした。どのバージョン、どのコンセンサスモデル、どの設定か。各クラスターがどのように機能したかの知識は、それを設定した人にありました。 監視は手動でした。JMX Exporterを使用してメトリクスを取得し、最終的にLokiにログを送信しました。これらは役立ちました。しかし、実際に問題を診断するために適切なインスタンスにSSHで接続する必要がある運用モデルの上にレイヤーがありました。フリートの統一されたビューはありませんでした。 これらのどれもアラームをトリガーするほど壊れていませんでした。それはただ遅く、手動で、そしてフリートが成長するにつれてますます一貫性がなくなっていました。自動化されるべき運用にエンジニアリング時間を費やしていました。 Strimziとは何か? 実装方法に入る前に、コアアイデアを理解することが役立ちます。 Strimziは、Kubernetesオペレーターによって管理されるKubernetesクラスター上で実行されるKafkaです。オペレーターは、クラスター内で実行され、あなたの代わりに別のアプリケーションを継続的に管理するソフトウェアの一部です。それは一連の設定ファイルを監視し、Kafkaデプロイメントの実際の状態が常に宣言された状態と一致することを保証します。何かがずれた場合、オペレーターはそれを修正します。ブローカーがダウンした場合、オペレーターはそれを復旧させます。 重要なシフト:あなたはオペレーターであることをやめます。ソフトウェアがオペレーターになります。 Strimziはオープンソースであり、CNCFの一部です。ライセンス費用もベンダーロックインもありません。すべてがKubernetesカスタムリソース(CRD)を通じて表現されるため、Kafkaセットアップ全体がGitに存在するコードになります。 実装方法 既存のクラスターにStrimziをドロップして完了とはしませんでした。構造化方法について、意図的な決定を下しました。 専用Kubernetesクラスター:GCP/GKE上にKafkaワークロード専用のクラスターを作成しました。Kafkaを独自のクラスターに分離することで、クリーンなリソース境界が得られ、アプリケーションワークロードから独立して容量を管理しやすくなりました。 パイプラインごとの名前空間分離:そのクラスター内で、各Kafkaデプロイメントは独自の名前空間に存在します。DB AからDB Bへのパイプラインは独自の名前空間を取得します。DB CからDB Dは別の名前空間を取得します。「パイプラインごとに1つのVM」の代わりに、現在は「パイプラインごとに1つの名前空間」となり、それらの間に実際の分離があります。ある名前空間での設定ミスは、別の名前空間のリソースを消費したり、可用性に影響を与えたりすることはできません。 標準としてのYAMLテンプレート:標準化されたStrimziクラスターテンプレートを作成しました。新しいパイプラインがKafkaインスタンスを必要とする場合、テンプレートを取得し、関連フィールドに記入して適用します。各テンプレートは、Kafkaクラスター定義、Kafka Connect、ノードプール、およびメトリクス設定を含む完全なスタックをカバーします。同じ開始点から来るため、各新しいインスタンスは一貫して作成されます。 ソース、シンク、および設定のためのArgoCD:各コネクタ(ソース、シンク、設定)はYAMLファイルで定義され、Gitリポジトリに存在します。新しいソースまたはシンクを追加するには、YAMLファイルを作成してマージリクエストを開きます。それがマージされると、ArgoCDはその変更を検出し、クラスターに自動的に同期します。そこからオペレーターがそれを適用します。 単一のソースオブトゥルースとしてのカスタムKafka Connectイメージ:公式Strimzi Kafkaイメージを拡張し、使用するすべてのコネクタを組み込みました。これには、CDC(PostgreSQL、MySQL、Spanner)用のDebeziumコネクタ、ClickHouse、MongoDB、S3、および関連するJDBCドライバを備えたConfluent JDBCコネクタが含まれます。すべてのコネクタバージョンはDockerfileで明示的にピン留めされています。コネクタのアップグレードが必要な場合は、Dockerfileの1行を更新して新しいイメージをビルドします。新しいKafkaバージョンがリリースされたら、更新されたStrimziイメージにリベースします。1つの場所。1つのPR。オペレーターがすべてのクラスターにロールアウトします。 日々の運用で何が変わったか 日々の運用での違いは即座に現れました。 SSHは不要になりました:ポートフォワーディングは不要になりました。ソースまたはシンクを追加するには、YAMLを作成してプッシュします。オペレーターがそれを適用します。VMへのターミナルアクセスを必要とした作業は、レビューおよびマージされるプルリクエストになりました。 Docker Composeの再起動は不要になりました:Strimziがブローカーのライフサイクルを管理します。もう本番データパイプラインを`docker compose down`することはありません。 スケーリングはファイル内の数字です:追加のブローカーが必要ですか?YAMLの値を1つ変更します。オペレーターが配置を処理し、クラスターの状態が一貫していることを保証します。スケールダウンが必要ですか?同じです。グレースフルな廃止を処理します。 考古学なしのロギング:各ブローカーのログは、標準的なKubernetesツールで利用できます。ターミナルからの`kubectl logs`、またはUIを好む場合はLensやk9sで直接利用できます。保持とクロスクラスタークエリのためにLokiにログを送信し続けています。 すべてを一度に表示する単一のUI:内部的にKafbatを使用しており、ブローカーの健全性、コネクタの状態、コンシューマーラグ、トピックメタデータを含むすべてのクラスターの統一されたビューを提供します。コネクタが失敗した場合、その理由を確認し、設定を検査し、ブラウザから問題を理解できます。ターミナルは不要です。 ダウンタイムなしのローリングアップデート:Kafkaのアップグレードは一度に1つのブローカーずつ行われ、オペレーターがクォーラムを確保します