Slide 1

Slide 1 text

Streamlitホスティング基盤を スケールさせる 2024.09.17 GO株式会社 按田 勝彦

Slide 2

Slide 2 text

© GO Inc. プロフィール写真 正方形にトリミングした写 真を「図形に合わせてトリ ミング」で円形にすると真 円になる 2 自己紹介 GO株式会社 ソフトウェアエンジニア / 按田 勝彦 ● AI技術開発部データプラットフォームグループ所属 ● タクシーアプリ『GO』における分析基盤・アルゴリズム基盤の開発 ・運用を担当 ● 所属している部活は料理技能向上部 「ていねいな暮らし」を心がけています

Slide 3

Slide 3 text

© GO Inc. 3 01|概要

Slide 4

Slide 4 text

© GO Inc. 4 概要 アプリケーションや利用者が日々増加するホスティング基盤において、 運用の効率化は避けて通れない課題です。 今回、PoC完了から本格活用段階へ至るまでに行った効率化の取り組みを 紹介します。 【キーワード】 ● GitHub Actions ○ gh, matrix strategy ● GKE(k8s) ○ kustomize, ytt, ArgoCD, ArgoCD Image Updater, Reloader ● Streamlit ○ Pythonメタプログラミング(Decorator, Monkey Patch)

Slide 5

Slide 5 text

© GO Inc. 5 02|背景と課題

Slide 6

Slide 6 text

© GO Inc. 6 背景 ● より、ニーズに叶った分析結果の共有を実現するため、Streamlitア プリケーションのホスティング基盤が構想された ● ホスティング基盤は、アナリスト毎に専用のStreamlitサイトを割り 当てる、いわゆるマルチテナントアーキテクチャを採用し、データ ソースであるBigQueryとの接続性やカスタマイズ性を鑑みて、 GKE(k8s)上に構築することとなった ● 初期リリース時はアジリティ優先で構築し、アナリストには好意的に 受け止められ、利用者が急増した ● 利用者急増にともない、マルチテナント特有の運用課題が浮上した。 また、監査ログが取れていないという問題も明らかになった。

Slide 7

Slide 7 text

© GO Inc. 7 課題1 - デプロイ マルチテナントは、同じようなアプリケーションを一つの基盤でホス ティングする。初期段階のシンプルな実装では、主にデリバリー観点で 下記が問題となっていた。 ● デプロイ工程に人手が介在しており手順が煩雑であった ○ CI/CDパイプラインやk8sマニフェストをアプリケーションごと にコピー・編集して用意しなければならない ○ k8sマニフェストの環境差分も人手で管理している このことが、アナリスト毎のStreamlit環境を払い出しする際のリードタ イムを遅延させていた。さらに、保守メンバーが固定化することも危惧 されていた。

Slide 8

Slide 8 text

© GO Inc. 8 課題2 - ロギング また、監査目的で ● 「誰が」 ● 「どのStreamlit環境に」 ● 「いつアクセスしたのか?」 というロギングについても必要となった。 確実性を求められるにもかかわらず、アナリストにロギングの実装を強 制できないので、ホスティング基盤側で対応せざるをえなくなった。

Slide 9

Slide 9 text

© GO Inc. 9 03|対策

Slide 10

Slide 10 text

© GO Inc. 10 対策 これらの課題に対して以下の取り組みを行った。 ● 課題1 - デプロイに対する対策 ○ CI/CDパイプラインの共通化 ○ GitOpsの実現 ■ k8sマニフェストのテンプレート化 ■ ArgoCDの導入 ● 課題2 - ロギングに対する対策 ○ Pythonメタプログラミングによるロギング

Slide 11

Slide 11 text

© GO Inc. 11 対策 - CI/CDパイプラインの共通化 Before ● Github Actionsでアナリストごとに個別のCI/CDパイプラインを設定 していた ● 更新したDockerイメージのデプロイまでこのパイプラインで行って いた(CIOps) After ● CI/CDパイプラインを共通化して「アナリスト名+アプリ名」をパラ メータとして渡すようにした👍 ○ パラメータはgh pr diffの結果から自動的に抽出 ■ 日本語ファイル名の取り扱いに不具合があったので、修正をコント リビュートした! https://github.com/cli/cli/pull/9115 ● Dockerイメージのレジストリ登録までを責務とした(GitOps)

Slide 12

Slide 12 text

© GO Inc. 12 対策 - (GitOps) k8sマニフェストのテンプレート化 Before ● 各アプリケーションごとに個別のマニフェストを用意していた ● それぞれのアプリケーションに特化した設定は個別に編集していた After ● リストに「アナリスト名+アプリ名」を登録するだけでマニフェスト を用意できるようにした👍 ○ 「アナリスト名+アプリ名」を引数として受け取る共通のテンプ レートを作成した ○ kustomizeとyttを用いて、リストとテンプレートからマニフェ ストをレンダリングするようにした ■ それぞれのアプリケーションに特化した設定はオーバーレイ で実現した

Slide 13

Slide 13 text

© GO Inc. 13 対策 - (GitOps) ArgoCDの導入 Before ● k8sマニフェストの環境差分を人手で管理していた ○ マニフェストをGitで管理はしているが適用はkubectl applyで手 動実行 After ● ArgoCDを導入し、マニフェストの環境差分を自律的に解決できるよ うにした👍 ● あわせて、ArgoCD Image updatorを導入し、イメージ更新をトリ ガーとして自動でデプロイされるようにした👍 ● さらに、Reloaderを導入し、ConfigMap変更時にPodが自動的に再起 動されるようにした👍

Slide 14

Slide 14 text

© GO Inc. 14 対策 - Pythonメタプログラミングによるロギング BigQuery 分析 データ ・ ・ ・ コンテナ実行環境 ロード バランサー Cloud Load Balancing 認証 Identity-Aware Proxy IP制限 Cloud Armor 閲覧者1 閲覧者2 閲覧者n ・ ・ ・ GCP分析環境 サイト1 サイトn リバース プロキシ イメージ リポジトリ 開発者 Before① ● リバースプロキシでロギ ング ○ WebSocket通信の ためコネクション確 立時しかイベントを 記録できない Before② ● CI時に各アプリケーショ ンを強制的に書き換えて ロギングコードを注入 ○ テキスト置換なので ちょっとした構造の 変化で破綻する ○ エラーで報告される 行番号がずれる

Slide 15

Slide 15 text

© GO Inc. 15 Appendix - そもそもメタプログラミングとは? メタプログラミング (英語: metaprogramming) [注釈 1]とはプログラミ ング技法の一種で、一般に「プログラムを記述するプログラム」を書く こと、またはそのプログラムを指す[1]。対象言語に埋め込まれたマクロ 言語によって行われることもある。 出典: フリー百科事典『ウィキペディア(Wikipedia)』 ↓ 今回の文脈では実行時にプログラムを書き換える手法という理解でOK👌

Slide 16

Slide 16 text

© GO Inc. 16 Appendix - Pythonメタプログラミングの手法 ▪ Ghost Method ▪ Singular Method ▪ Monkey Patch ▪ Metaclass ▪ Decorator ▪ Descriptor ▪ Operator Overload ▪ eval/exec ▪ Dynamic Module ▪ ast ▪ Import Hook ▪ …etc 参考)https://tell-k.github.io/pyconjp2016/#1

Slide 17

Slide 17 text

© GO Inc. 17 対策 - Pythonメタプログラミングによるロギング After ● メタプログラミングの技法を用いてロギングコードを注入した👍 ○ Pythonインタープリタが起動する際に自動的に読み込まれるスクリプトでロギン グコードを注入(sitecustomize.py) ■ Streamlitのページ表示イベントにロギング用デコレータを適用し、モン キーパッチで差し替え show() def show(): ... def trace(func): inner(): func() logger.info(log) return inner trace() show() 元の実装と 差し替え ページ表示 イベント ロギング機能 付加 show()

Slide 18

Slide 18 text

© GO Inc. 18 04|結果と振り返り

Slide 19

Slide 19 text

© GO Inc. 19 結果 ● デプロイ作業の属人性が解消された!🎉 ● デリバリーのリードタイムが大幅に減少した!🎉 ● 透過的かつ網羅的なロギングを実現した!🎉

Slide 20

Slide 20 text

© GO Inc. 20 振り返り ● 🌞 Good / ⛅ Motto ○ 🌞 k8sのエコシステム活用により、ベストプラクティスに則った デリバリーの仕組みをローコストで導入することができた! ○ 🌞 取り組みを通じてOSSコントリビュートができた! ○ 🌞 解決策の共有を通じて、チームの問題解決能力が一段上がっ た! ○ ⛅ ホスティング基盤の選定において、k8sだけでなく、よりシン プルなDokku(HerokuコンパチブルのPaaS OSS)なども、検討 対象にいれるべきだった…

Slide 21

Slide 21 text

© GO Inc. 文章・画像等の内容の無断転載及び複製等の行為はご遠慮ください