Wodom!のデータパイプライン インフラストラクチャ
こんにちは!Wodom!というデータ基盤プロダクトのデータパイプライン周りを担当している石井です。
ブログでは初登場ですが、JDSCへのジョインは2020/10で一瞬で1年が過ぎてしまいました。振り返ってみると社会人になって以来のどの1年よりも濃い1年を送ったなぁ思っています。
今回はその濃い一年を通して関わり続けた、Wodom!のデータパイプラインアーキテクチャのいまについて解説してみようと思います。
Wodom!のデータパイプライン インフラストラクチャ
あくまで現状なので今後変わっていくだろうと前置きさせていただきますが、今回は特徴的だと思う3点について順番に解説させていただこうと思います
① Kubeflowを採用
Wodom!ではデータパイプラインを動作させる基盤としてKubeflowを採用していますので、簡単にKubeflowについて触れておきます。

Wodom!ではKubeflowをコンテナ化したコンポーネントをつなぎ合わせたパイプラインの実行基盤として利用しているので、赤枠で示しているPipelinesを中心に利用しています。
Kubeflowのコンポーネントはコンテナ化されていれば何でも利用でき、それをPythonでつなぎ合わせることでPipelineとして動作させられます。
パイプラインごとにパラメータを定義でき、それを実行時に渡すことで再利用性を高くしているというところがポイントです。
② Kubeflowのアプリケーションからの利用
Wodom!としてはアプリケーション(KubeflowのUIではない)からパイプラインの設定を作成しそれを使ってパイプラインを実行、結果をアプリケーションが見える形で返す必要があり、大きく以下のようなアーキテクチャにしています。

実行に関してはKubeflowは標準でAPIを持っているので、基本的には実行時にパイプラインごとに適切な引数を渡して実行すればよいので、当初はすべてのパラメータを実行時にアプリケーション側から引き渡すという設計にしました。
テスト時は問題なく動いていたのですが、実際の巨大なデータを使ってやってみると、渡せるパラメータのサイズが10,000byteまでかつマルチバイト文字列を受け取れないという制限に引っかかってしまいました。
こういった点があり、jsonを作成しそれをGCS上に保管し実行時パラメータとしてjsonへのパスを渡してもらうような作りにしています。
ただ、Kubeflowのパラメータを直接使うのであればパラメータにちゃんとした型定義をすることで間違ったものが渡ってきたときに弾くことが可能ではあるはずなのですが、JSONで渡してしまうとその点が標準の範疇では難しくなってしまいます。
それに関してはjson schemaを導入し、パイプライン / Application双方でスキーマチェックを行う形にして対処しています。
json schemaの生成にはこちらを利用しています。Pythonのdataclassをかけば簡単にjson_schemaを生成してくれるので実装コストはかなり低く出来ていると思います。
パイプラインの実行結果に関してはアプリケーション側に返す必要があり、その部分はgRPCを使っています。この点については、2点大変だったことがあって、
- protocとPythonの相性が絶妙に悪く当初の開発はだいぶ苦労したこと
- Kubeflow側のAPIがパイプライン実行中だとコンポーネントのアーティファクトをうまく取ってこれず、結局内部で持っている型情報すらないJSONをパースして取り出すことになった
と、だいぶ開発チームの血と涙の上に成り立っていたように思います。
この点は、とあるチームメンバーが全力で改善してくださり、現在では前半はほぼ解消されこれだけでもかなり開発しやすくなり個人的にはとてもよかったのですが、さらにこれからの改善も見込めるところまで進んできました。
③ Workload Identityを用いた安全なマルチユーザの分離
Wodom!はマルチテナント型のパイプラインです。扱うものの特性がお客様の大事なデータということもあり何かが間違っても他のお客さまのデータが見えてしまう・・・なんていう事態は避けなくてはいけません。
今回基盤がGCPということもあり、Workload Identityを利用した権限分離を行っており、これにより何らかの設定をミスったとしても「ここさえ間違えなければ」安全な状態を担保しています。

Workload identityは簡単に言うとGCPのサービスアカウント(GSA)とKubernetes(GKE)のサービスアカウント(KSA)を紐付けられる機能でインフラレベルで設定ができます。Kubeflowで実行されるパイプラインのPodは未指定であればdefault-editorというKSAで動くわけですが、これにインフラレベルで顧客単位のGSAを紐付けておくことにより、この安全性を実現しています。
マルチテナント型と言っていますが、扱うデータの種類やプロジェクトの都合によっては、Kubeflow(GKE)自体はマルチテナントとしつつも、BigQueryやGCSなどの実際のデータを置くGCP Projectは分けても使えるような構成をとっております。
その場合にも上記のGSAを適切なGCPプロジェクトでIAMにより権限を付与することでプロジェクト側の与える権限で安全に動作する、という仕組みを作れています。
終わりに
Wodom!のデータパイプラインを支えるインフラストラクチャについて浅い感じではありますが解説させて頂きました。
個人的にも新たな挑戦をさせて頂き非常に楽しい一年だったとともに、最高の開発チームと一緒にv1リリースというゴールまで走りきれたということは非常に感慨深いものがありました。
もちろんこれで終わりではなく、ここからがdevopsの始まりだと思っていますのでこれから先も改善を繰り返しより良いプロダクトになっていくところに寄与できると嬉しいなと思います。
また、JDSCでは一緒に働く仲間を募集しています!興味のある方は以下をご確認頂き、ぜひエントリーしてください!
データ活用支援ソリューション Wodom!
サービス紹介ページはこちら https://wodom.jp/consultant