T-CREATOR

Dify を Kubernetes にデプロイ:Helm とスケーリング設計の実践

Dify を Kubernetes にデプロイ:Helm とスケーリング設計の実践

LLM(大規模言語モデル)を活用したアプリケーション開発が加速する中、Dify は注目を集めている AI アプリケーション開発プラットフォームです。本番環境で Dify を安定的に運用するには、Kubernetes によるコンテナオーケストレーションが不可欠となります。

本記事では、Dify を Kubernetes にデプロイする実践的な手順と、Helm チャートを活用した効率的な管理方法、さらには負荷に応じた自動スケーリング設計まで、実務で即活用できるノウハウを詳しく解説いたします。

背景

Dify とは

Dify は、LLM ベースのアプリケーションを迅速に開発・デプロイできるオープンソースプラットフォームです。ChatGPT のような対話型 AI アプリケーションやワークフロー型の AI アシスタントを、コーディングなしで構築できます。

Kubernetes で運用する理由

単一サーバーでの運用と比較して、Kubernetes には以下のメリットがあります。

スケーラビリティの向上

ユーザー数の増加や処理負荷の変動に対して、Pod の自動増減により柔軟に対応できます。

高可用性の実現

複数のレプリカを配置することで、障害時の自動フェイルオーバーが可能になります。

リソース効率の最適化

クラスター全体でリソースを効率的に分配し、コストを最適化できるでしょう。

Dify のアーキテクチャ構成

Dify を Kubernetes で運用する際には、複数のコンポーネントを理解する必要があります。

以下の図は、Dify の主要コンポーネントと依存サービスの関係性を示しています。

mermaidflowchart TB
    user["ユーザー"] -->|"HTTP/HTTPS"| proxy["Proxy<br/>(NGINX)"]

    subgraph DifyCore["Dify コアコンポーネント"]
        proxy -->|"リクエスト<br/>振り分け"| web["Web<br/>(Frontend)"]
        proxy -->|"API<br/>リクエスト"| api["API<br/>(Backend)"]
        api -->|"バックグラウンド<br/>タスク委譲"| worker["Worker"]
        api -->|"定期実行<br/>タスク"| beat["Beat<br/>(Scheduler)"]
        api -->|"隔離実行"| sandbox["Sandbox"]
    end

    subgraph DataLayer["データ層"]
        db[("PostgreSQL<br/>(メインDB)")]
        redis[("Redis<br/>(キャッシュ)")]
        vector[("Vector DB<br/>(Weaviate等)")]
    end

    api --> db
    api --> redis
    worker --> db
    worker --> redis
    api --> vector
    worker --> vector

図で理解できる要点

  • NGINX Proxy が全てのトラフィックの入り口となり、適切なコンポーネントへ振り分けます
  • API と Worker が主要な処理を担当し、データ層と連携します
  • 各コンポーネントは独立してスケール可能な設計になっています

Helm の利点

Kubernetes リソースを直接 YAML で管理する方法もありますが、Helm を使うことで以下の利点が得られます。

#項目詳細
1パッケージ管理アプリケーション全体を 1 つのチャートとして管理
2バージョン管理デプロイのロールバックが容易
3設定の抽象化values.yaml で環境ごとの設定を一元管理
4再利用性テンプレート化により複数環境への展開が簡単

これらの背景を踏まえて、実際の課題を見ていきましょう。

課題

Dify を Kubernetes で運用する際には、いくつかの技術的な課題に直面します。

複雑なコンポーネント管理

Dify は以下のような複数のコンポーネントで構成されています。

アプリケーション層

API サーバー、Worker、Web フロントエンド、Sandbox、Beat スケジューラーなど、役割の異なる複数のサービスが存在します。

データ層

PostgreSQL、Redis、Vector Database(Weaviate、Qdrant など)といった依存サービスが必要です。

これらを個別に YAML マニフェストで管理すると、設定ファイルが膨大になり、メンテナンスが困難になるでしょう。

環境ごとの設定差異

開発環境、ステージング環境、本番環境では、以下のような設定が異なります。

#設定項目開発環境本番環境
1レプリカ数1〜23〜10
2リソース制限緩い厳密
3データベース組み込み外部マネージドサービス
4永続化ストレージローカルクラウドストレージ

環境ごとに YAML を複製すると、設定の不整合やヒューマンエラーが発生しやすくなります。

スケーリング戦略の最適化

Dify の各コンポーネントは負荷特性が異なるため、一律のスケーリング戦略では非効率です。

API サーバー

リクエスト数に応じた水平スケーリングが必要ですが、同時接続数の増加に素早く対応する必要があります。

Worker

バックグラウンド処理のキューが溜まると処理遅延が発生するため、キューの長さに基づくスケーリングが求められます。

データベース

PostgreSQL や Redis は垂直スケーリング(リソース増強)が基本となり、水平スケーリングには特別な設定が必要でしょう。

以下の図は、各コンポーネントのスケーリング特性を示しています。

mermaidflowchart LR
    subgraph API["API サーバー"]
        direction TB
        api1["API Pod 1"]
        api2["API Pod 2"]
        api3["API Pod 3"]
        hpa_api["HPA<br/>(CPU: 70%)"]
        hpa_api -.->|"自動増減"| api1
    end

    subgraph Worker["Worker"]
        direction TB
        worker1["Worker Pod 1"]
        worker2["Worker Pod 2"]
        hpa_worker["HPA<br/>(Queue長)"]
        hpa_worker -.->|"自動増減"| worker1
    end

    subgraph DB["データベース層"]
        direction TB
        db_primary["PostgreSQL<br/>Primary"]
        db_replica["PostgreSQL<br/>Replica"]
        redis_master["Redis<br/>Master"]
        db_primary -->|"レプリケーション"| db_replica
    end

    API -->|"クエリ"| DB
    Worker -->|"データ更新"| DB

図で理解できる要点

  • API と Worker は HPA により水平スケーリングを実現
  • データベースはレプリケーションによる読み取り負荷分散が基本
  • 各層で異なるスケーリング戦略が必要

これらの課題を解決するために、Helm チャートを活用した統合的なアプローチが有効です。

解決策

Helm チャートを活用することで、Dify の複雑なデプロイとスケーリングを効率的に管理できます。

コミュニティ Helm チャートの選定

Dify の公式リポジトリには Helm チャートが含まれていないため、コミュニティが提供しているチャートを利用します。

主要な Helm チャート

現在、以下の 2 つのコミュニティチャートが活発にメンテナンスされています。

#チャート名提供元特徴
1dify-helmBorisPolonskyExternal Secrets Operator 対応、本番利用向け
2difyDoubanシンプルな設定、初心者向け

本記事では、より多機能な BorisPolonsky 版を使用して解説いたします。

Helm リポジトリの追加

まず、Helm リポジトリをローカル環境に追加しましょう。

以下のコマンドで Dify の Helm リポジトリを追加します。

bashhelm repo add dify https://borispolonsky.github.io/dify-helm

リポジトリ情報を最新化します。

bashhelm repo update

追加されたリポジトリを確認するには、次のコマンドを実行します。

bashhelm search repo dify

これで Dify チャートの最新バージョンが表示されるはずです。

基本的なインストール

最もシンプルなインストール方法は、デフォルト設定を使用する方法です。

以下のコマンドで、my-dify という名前で Dify をデプロイできます。

bashhelm install my-dify dify/dify

デフォルトでは、以下のコンポーネントが組み込みモードでデプロイされます。

  • PostgreSQL(組み込み)
  • Redis(組み込み)
  • Weaviate(Vector Database、組み込み)
  • Dify API、Worker、Web、Sandbox、Proxy

デプロイ状況を確認するには、次のコマンドを使用します。

bashkubectl get pods

すべての Pod が Running 状態になれば、デプロイは成功です。

カスタマイズ設定(values.yaml)

本番環境では、デフォルト設定ではなく、カスタマイズした設定ファイルを使用することが推奨されます。

values.yaml の取得

まず、デフォルトの values.yaml を取得して、カスタマイズのベースとします。

bashhelm show values dify/dify > custom-values.yaml

この custom-values.yaml ファイルを編集することで、環境に合わせた設定ができます。

主要な設定項目

以下は、本番環境で最低限カスタマイズすべき項目です。

レプリカ数の設定

各コンポーネントのレプリカ数を設定します。高可用性を実現するため、最低でも 2 つ以上のレプリカを配置しましょう。

yaml# API サーバーのレプリカ数
api:
  replicaCount: 2

# Worker のレプリカ数
worker:
  replicaCount: 2

# フロントエンド(Web)のレプリカ数
web:
  replicaCount: 2

レプリカを複数配置することで、1 つの Pod が障害で停止しても、サービスが継続できます。

リソース制限の設定

CPU とメモリのリソース制限を明示的に設定することで、リソース枯渇を防ぎます。

yaml# API サーバーのリソース設定
api:
  resources:
    requests:
      cpu: 500m
      memory: 1Gi
    limits:
      cpu: 1000m
      memory: 2Gi

requests は最低限保証されるリソース、limits は最大使用可能なリソースを示します。

yaml# Worker のリソース設定
worker:
  resources:
    requests:
      cpu: 500m
      memory: 1Gi
    limits:
      cpu: 2000m
      memory: 4Gi

Worker は LLM の処理を行うため、API よりも多くのリソースを割り当てることが推奨されます。

外部データベースの設定

本番環境では、マネージドデータベースサービスを使用することが推奨されます。

yaml# PostgreSQL を外部サービスとして使用
postgresql:
  embedded: false
  external:
    host: 'your-postgres-host.example.com'
    port: 5432
    database: 'dify'
    username: 'dify_user'

パスワードは Secret として別途作成し、参照することが安全です。

yaml# Redis を外部サービスとして使用
redis:
  embedded: false
  external:
    host: 'your-redis-host.example.com'
    port: 6379

外部サービスを使用することで、データベースの管理負荷が軽減され、バックアップやスケーリングが容易になるでしょう。

永続化ストレージの設定

アップロードされたファイルやモデルデータを永続化するため、StorageClass を設定します。

yaml# オブジェクトストレージの設定(S3互換)
storage:
  type: 's3'
  s3:
    endpoint: 'https://s3.amazonaws.com'
    bucket: 'your-dify-bucket'
    region: 'ap-northeast-1'
    accessKeyId: 'your-access-key'

クラウドプロバイダーのオブジェクトストレージ(AWS S3、Google Cloud Storage、Azure Blob など)を使用することで、高い耐久性と可用性が得られます。

カスタマイズした設定でのインストール

作成した custom-values.yaml を使用してインストールします。

bashhelm install my-dify dify/dify -f custom-values.yaml

既存のデプロイをアップグレードする場合は、次のコマンドを使用します。

bashhelm upgrade my-dify dify/dify -f custom-values.yaml

アップグレードの履歴を確認するには、以下のコマンドが便利です。

bashhelm history my-dify

問題が発生した場合は、前のバージョンにロールバックできます。

bashhelm rollback my-dify 1

これで、基本的な Helm を使った Dify のデプロイが完了しました。次は、負荷に応じた自動スケーリングの設定を見ていきましょう。

具体例

実際の負荷に応じて Dify を自動的にスケールさせる方法を、具体的な設定例とともに解説いたします。

Horizontal Pod Autoscaler(HPA)の設定

Kubernetes の HPA を使用することで、CPU やメモリの使用率に基づいて Pod 数を自動調整できます。

HPA の有効化

Dify Helm チャートでは、values.yaml で HPA を有効化できます。

以下は API サーバーに対する HPA 設定の例です。

yaml# API サーバーの HPA 設定
api:
  autoscaling:
    enabled: true
    minReplicas: 2
    maxReplicas: 10
    targetCPUUtilizationPercentage: 70
    targetMemoryUtilizationPercentage: 80

この設定では、CPU 使用率が 70%、またはメモリ使用率が 80%を超えると、Pod が自動的に増加します。

スケーリング動作の調整

Kubernetes 1.33 以降では、スケーリングの挙動をより細かく制御できるようになりました。

急激な負荷増加に素早く対応するため、スケールアップとスケールダウンで異なるポリシーを設定できます。

yamlapi:
  autoscaling:
    enabled: true
    minReplicas: 2
    maxReplicas: 10
    behavior:
      scaleUp:
        stabilizationWindowSeconds: 0
        policies:
          - type: Percent
            value: 100
            periodSeconds: 15
      scaleDown:
        stabilizationWindowSeconds: 300
        policies:
          - type: Percent
            value: 50
            periodSeconds: 60

scaleUp では 15 秒ごとに 100%増加を許可し、急激な負荷増加に対応します。一方、scaleDown では 5 分間の安定化期間を設けることで、頻繁なスケールダウンを防ぎます。

Worker のカスタムメトリクスベースのスケーリング

Worker は、バックグラウンドタスクのキュー長に基づいてスケールすることが理想的です。

メトリクスサーバーの準備

カスタムメトリクスを使用するには、Prometheus と Prometheus Adapter が必要です。

まず、Prometheus をインストールします。

bashhelm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/kube-prometheus-stack

次に、Prometheus Adapter をインストールして、カスタムメトリクスを HPA で使用できるようにします。

bashhelm install prometheus-adapter prometheus-community/prometheus-adapter

キュー長メトリクスの設定

Dify Worker がキュー長を Prometheus に公開するよう設定します(アプリケーション側の設定が必要です)。

例として、dify_queue_length というメトリクス名でキュー長を公開するとします。

yaml# Prometheus Adapter の設定例
rules:
  - seriesQuery: 'dify_queue_length'
    resources:
      overrides:
        namespace: { resource: 'namespace' }
        pod: { resource: 'pod' }
    name:
      matches: '^(.*)$'
      as: 'dify_queue_length'
    metricsQuery: 'avg_over_time(dify_queue_length[2m])'

この設定により、過去 2 分間のキュー長の平均値をメトリクスとして使用できます。

カスタムメトリクスベースの HPA

キュー長が 100 を超えた場合にスケールするよう HPA を設定します。

yamlapiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: dify-worker-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-dify-worker
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Pods
      pods:
        metric:
          name: dify_queue_length
        target:
          type: AverageValue
          averageValue: '100'

この設定では、キュー長の平均が 100 を超えると Pod が増加し、下回ると減少します。

データベース層のスケーリング戦略

データベースは、アプリケーション層とは異なるスケーリング戦略が必要です。

PostgreSQL の読み取りレプリカ

読み取り負荷が高い場合は、読み取り専用レプリカを追加します。

Bitnami の PostgreSQL Helm チャートを使用している場合、以下のように設定できます。

yamlpostgresql:
  architecture: replication
  replication:
    enabled: true
    numReplicas: 2

この設定で、1 つのプライマリと 2 つのレプリカが作成されます。

アプリケーション側で、書き込みはプライマリに、読み取りはレプリカに振り分けるよう設定することで、負荷を分散できるでしょう。

Redis のクラスターモード

高可用性とスケーラビリティを両立するため、Redis Cluster を使用します。

yamlredis:
  architecture: cluster
  cluster:
    enabled: true
    nodes: 6
    replicas: 1

この設定では、3 つのマスターノードとそれぞれに 1 つのレプリカを持つクラスターが構成されます。

スケーリングの監視とチューニング

設定したスケーリングが適切に動作しているか、継続的に監視することが重要です。

HPA の状態確認

現在の HPA の状態を確認するには、次のコマンドを使用します。

bashkubectl get hpa

詳細な情報を確認する場合は、describe コマンドが便利です。

bashkubectl describe hpa my-dify-api

スケーリングイベントの履歴を確認することで、適切なタイミングでスケールしているかを検証できます。

メトリクスの可視化

Prometheus と Grafana を組み合わせることで、スケーリングの状況を可視化できます。

Grafana ダッシュボードでは、以下のメトリクスを監視することが推奨されます。

#メトリクス目的
1Pod 数の推移スケーリングの頻度を確認
2CPU/メモリ使用率リソース使用状況を把握
3レスポンスタイムユーザー体験への影響を測定
4キュー長Worker のバックグラウンド処理状況

チューニングのポイント

実際の負荷パターンに基づいて、以下のパラメータを調整しましょう。

CPU/メモリ閾値の調整

初期設定の 70%が適切でない場合、実際の使用パターンに基づいて調整します。頻繁にスケールアップが発生する場合は閾値を下げ、あまりスケールしない場合は上げることを検討してください。

スケーリング速度の調整

急激な負荷変動がある場合は、stabilizationWindowSeconds を短くします。安定した負荷の場合は、長めに設定してコスト効率を優先できるでしょう。

レプリカ数の範囲調整

minReplicas はベースライン負荷に、maxReplicas はピーク時の負荷に基づいて設定します。コスト効率とパフォーマンスのバランスを考慮することが大切です。

以下の図は、スケーリング設計の全体像を示しています。

mermaidflowchart TB
    subgraph Monitoring["監視・メトリクス収集"]
        prometheus["Prometheus"]
        grafana["Grafana"]
        prometheus -->|"可視化"| grafana
    end

    subgraph Scaling["スケーリング制御"]
        hpa_api["API HPA<br/>(CPU/Memory)"]
        hpa_worker["Worker HPA<br/>(Queue長)"]
        prometheus -->|"メトリクス提供"| hpa_api
        prometheus -->|"カスタムメトリクス"| hpa_worker
    end

    subgraph AppLayer["アプリケーション層"]
        api["API Pods<br/>(2-10個)"]
        worker["Worker Pods<br/>(2-20個)"]
        hpa_api -.->|"自動調整"| api
        hpa_worker -.->|"自動調整"| worker
    end

    subgraph DataLayer["データ層"]
        db_primary["PostgreSQL<br/>Primary"]
        db_replicas["PostgreSQL<br/>Replicas"]
        redis_cluster["Redis Cluster<br/>(6 nodes)"]
        db_primary -->|"レプリケーション"| db_replicas
    end

    api --> db_primary
    api --> db_replicas
    api --> redis_cluster
    worker --> db_primary
    worker --> redis_cluster

図で理解できる要点

  • Prometheus がすべてのメトリクスを収集し、HPA とダッシュボードに提供
  • API と Worker はそれぞれ異なるメトリクスでスケーリング
  • データ層はレプリケーションとクラスタリングで高可用性を実現

これらの設定により、Dify を本番環境で安定的かつ効率的に運用できるようになります。

まとめ

本記事では、Dify を Kubernetes にデプロイし、Helm チャートで管理する実践的な方法を解説いたしました。

Helm を活用することで、複雑なコンポーネント管理が簡素化され、環境ごとの設定差異も values.yaml で一元管理できるようになります。さらに、HPA を用いた自動スケーリング設計により、負荷変動に柔軟に対応できる本番環境が構築できるでしょう。

特に重要なポイントは以下の通りです。

#ポイント内容
1コミュニティチャートの活用BorisPolonsky 版や Douban 版を用途に応じて選択
2コンポーネント別のスケーリングAPI は CPU、Worker はキュー長に基づく設計
3データ層の高可用性PostgreSQL レプリカと Redis Cluster の導入
4継続的な監視とチューニングPrometheus/Grafana による可視化と調整

実際の運用では、まず小規模な環境でデプロイを試し、負荷テストを通じてスケーリングパラメータを調整することが推奨されます。そして、本番環境では外部マネージドサービスを活用し、バックアップやセキュリティ対策も忘れずに実施してください。

Dify の Kubernetes デプロイは、適切な設計と設定により、スケーラブルで信頼性の高い AI アプリケーション基盤を実現できます。本記事が、皆様の Dify 運用の一助となれば幸いです。

関連リンク