🐈

DifyをAzureですこしセキュアに利用する

2024/08/26に公開

この記事は

最近、流行っているDifyのCommutiy版をAzure上に「すこし」本番運用を考慮した形でデプロイしたので、自身のメモをかねた記事です。

構成

基本方針

Difyは結構たくさんのDocker Containerが動作します。
また、PostgreSQL、Redis、VectorDBなどが必要となります。

構築あたり、以下の方針としました

  1. VMは極力使わない
    コンテナがたくさん立ち上がるなら、Kubernetesだよね?程度の思いです。AzureにはContainer AppsというサーバレスのKubernetesサービス(?)があります。まぁこっちを選んだ方が楽なのは知っていますが。これは、私の趣味です(今、開発・検証環境のAKSをもっており、同居させた方が楽だった、、、が本音ですが)

データベース、VectorDB、RedisもAzureのマネージドサービスを利用する方針としました。

  1. 外部と直接通信する箇所を限定する
    L7ロードバランサー以外は直接外部から接続出来ないように、仮想ネットワークで分離する方針としました。PaaSサービスはプライベートエンドポイント経由で利用できるものを選定しています。

  2. セキュリティ情報を安全に管理する
    Kubernetesのsecretだと、キー情報をテキストに書き留める必要がありそうなのと、運用担当がポータル画面から管理できるように、キーコンテナで管理する方針としました。

概要図すると、こんなかんじです。

構成の説明

Kubernetes サービス

Docker Composeをmanifestに書き換えています。

  • env周りはConfigMapに
  • シークレットはAzure KeyVaultから取得する

Kubernetesを利用することで、FireCrawlやLangFuseなど他の外部サービスや、自作のカスタムツールも同じ環境に手軽に追加出来るのは利点だと思います。社内情報にアクセスするツールの開発がはかどります

データベース

AzureのPostgreSQLサービスには以下の二つがあります。Difyでは、チャット履歴などほぼ全てのデータをデータベスに記録するので、拡張性が優れている(と思われる)Azure Cosmos DB for PostgreSQLを採用しました。Azure Cosmos DB for PostgreSQLでDifyが動作するのか、後述のVectorDBとして動作するのかという検証の意味もあります。

  • Azure Database for PostgreSQL
  • Azure Cosmos DB for PostgreSQL

VectorDB

Difyが対応しているVectorDBのうち、Azureのサービスで使えそうなのはpgvectorだったので、Azure Cosmos DB for PostgreSQLを採用しました。。Azure Cosmos DB for PostgreSQLでDifyが動作するのか、という検証の意味合いが強いです。

(DifyのVectorDBが直接CosmosDBかAI Searchに対応してくれればなぁと言う思いもあったりします。こそこそ書いたりしてますが、、、いつになったら動くことらや)

secret情報

Azureの公式ドキュメントにもありますが、KubernetesのSecrets Store CSI Driverを用いキー情報を管理・運用することが出来ます。

ついでにといってはなんですが、SSL証明書もKeyValutで管理しています。

管理ポータルからシークレット情報が管理できるの運用コスト(と言うか、運用者の教育にかかるコスト)を削減し、誤操作による停止のリスクを減らすことができるので、おすすめです。概要図では省略していますが、Kubernetesの管理用APIは外部公開していません。なので、Kubernetesへの操作は踏み台サーバーから実行する必要があり、結構手間(実際の作業と手順書作成)だったのが楽になりました。

ネットワーク分離

Ingress ControllerにはApplication Gateway Ingress Controllerを利用し、ApplicationGateway以外は仮想ネットワーク以外からの通信を行わないようにしています。

AzureのPaaS製品には、プライベートエンドポイントという、PaaSサービスを仮想ネットワークに取り込む仕組みが用意されています。以下のサービスで利用しています。

  • Azure Cosmos DB for PostgreSQL
  • Redis
  • Storage(Blob)
  • OpenAI
  • KeyVault

Storage

Azureなので、普通にBlob Storageです。

はまったポイント

Azure Cosmos DB for PostgreSQL

作成したデータベースインスタンスが小さすぎたと言う問題もありますが、PgBouncerを利用しないと、pgvector側で接続が枯渇する問題が発生しました。とくに大きなPDFを一気に登録しようとするとエラーが頻発します。

Azure Cache for Redis

普通にRedisをデプロイするとSSL通信が必須となっています。REDIS_USE_SSL: 'true' と REDIS_PORT: '6380'を忘れずに

あと、「CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://:difyai123456@redis:6379/1}」は以下の通り変更して、KeyVaultから取得しています。

  • プロトコルが reiss(最後にs)
  • パスワードの部分に、ポータルから取得したトークン
  • ポートを6380
rediss://:<ポータルから取得したトークン:Base64です>@<デプロイしたホスト名>.redis.cache.windows.net:6380/1

今後やりたいこと

VectorDBのプロバイダ実装

Azure Cosmos DB for PostgreSQLでpgvectorを設定するでも良いのですが、Cosmos DB本体がVectorDBとして利用できるのでそちらを利用したいかなぁ。

Sandbox

現在、通常のノード(管理されたVMクラスターの上)でPodを動かしていますが、たくさんの人が使い始めるとSandBoxはリソースを食い潰しそう。仮想ノードを設定してスパイクした場合に備えておきたい。この設定は恐らくWorker Pod側にも入れておいた方が恐らく幸せになれるのだろうとおもう。

上記とあわせて、スクリプト実行時のファイル保存場所をStorageに切り替えておきたい。大きなデータセットを与えたり、図を書いたりするようになるとリソースは枯渇すると思うし。

Discussion