EKS 部署高可用 Dify

目录

关于 Dify

Dify 架构及核心组件

Dify on EKS 部署

一、前置条件

二、Dify on EKS 部署步骤


生成式 AI(Generative AI)和大语言模型(LLM)不仅大大提升了个人的信息获取和工作效率,也正在重塑企业应用。很多企业正在探索基于 LLM、RAG 和 Agent 的 GenAI 应用,通过与私域数据和现有的应用结合,来打造更创新、更具价值和更个性化的用户体验。

LangChain 是构建 GenAI 应用的非常流行的选择,它是一个非常流行的开源框架,提供了工具和组件,如数据加载、提示词模板、数据检索、RAG 引擎和 Agent 等,简化了构建基于 LLM 应用程序的过程。LangChain 的目标客户是开发者,使用此框架需要具有开发经验。可以把 LangChain 想象为有着锤子、钉子的工具箱。与之相比,Dify 提供了更接近生产需要的完整方案,Dify 好比是一套脚手架,并且经过了精良的工程设计和软件测试。

关于 Dify

Dify 是一款开源的大语言模型(LLM)应用开发平台。它融合了后端即服务(Backend as Service)和 LLMOps 的理念,使开发者可以快速搭建生产级的生成式 AI 应用。即使你是非技术人员,也能参与到生成式 AI 应用的定义和数据运营过程中。

Dify 由一个专业的全职团队和社区共同打造。你可以基于任何模型自部署各类 GenAI 应用,在灵活和安全的基础上,同时保持对数据的完全控制。

由于 Dify 内置了构建 LLM 应用所需的关键技术栈,包括对数百个模型的支持、直观的 Prompt 编排界面、高质量的 RAG 引擎、稳健的 Agent 框架、灵活的流程编排,并同时提供了一套易用的界面和 API。这为开发者节省了许多重复造轮子的时间,使其可以专注在创新和业务需求上。

截止本文创作时至,Dify 在 Github 有超过 4.4 万颗 Star。且看 Dify CEO 的官方介绍:

我们的社区用户对 Dify 的产品评价可以归结为简单、克制、迭代迅速。
——路宇,Dify.AI CEO

Dify 架构及核心组件

Dify 提供了三种使用模式:商业化版本 Dify Cloud(SaaS 模式),自建 Dify 社区版(免费),自建企业版。本文主要介绍如何基于 Amazon EKS 自建高可用 Dify 社区版。

下图为基于 Amazon EKS 部署 Dify 的架构。

Dify on EKS 架构图

Dify 包括 3 个业务服务组件 api / worker / web (Frontend),以及 6 个基础组件 vector db / db / redis / nginx / ssrf_proxy / sandbox。为了实现生产级高可用性,我们使用多个 Amazon 托管服务用作基础组件,包括 Amazon S3,ElastiCache for Redis,Aurora PostgreSQL,ALB 等。Dify 支持多种向量数据库产品,包括 OpenSearch,Zilliz/Milvus,Qrdrant,Weaviate 等,本文使用部署在 EKS 中的 Milvus。

Dify on EKS 部署

一、前置条件

Dify 有几个关键组件需要提前部署,包括:

本方案中的所有组件都支持使用 Graviton3 芯片的 EC2 实例,在部署时选择 Graviton3 实例可以获得更高的性价比。在 Milvus on Graviton3 博客中,测试结果显示 Graviton3 可以实现高达 31% 的性价比提升。

二、Dify on EKS 部署步骤

Dify 官方支持 Docker Composer,以及源码部署的方式:https://docs.dify.ai/v/zh-hans/getting-started/install-self-hosted,但是这两种方式未能照顾到高可用环境,更多是用于开发和测试环境的快速部署。

作为生产高可用环境,推荐以 Helm Charts 的方式部署在 EKS 上。本文使用该 Chart 进行部署:charts/charts/dify at master · douban/charts · GitHub。但在部署的时候需要做一些调整,比如使用 S3 替代 minio 用作对象存储,使用 AWS Application Load Balancer 用作 EKS Ingress,使用 Aurora PostgreSQL 替代内置 PostgreSQL 等,使用 ElastiCache for Redis 代替内置 Redis。

部署中要使用到 AWS AK/SK、数据库的账号密码等敏感信息,我们使用 K8S Secret 进行存储,并推荐使用 Amazon KMS 进行加密:Encrypt Kubernetes secrets with AWS KMS on existing clusters - Amazon EKS

请注意,进行以下步骤前,请确保已经完成前置条件。

  1. 安装 Helm,参考 Helm | Installing Helm
  2. 添加 Helm repo
    helm repo add douban https://douban.github.io/charts/
    helm update
    
  3. 确保 kubectl 可以连接到您的 EKS 集群。使用如下命令创建 Secret 对象,用于存储 AWS AK/SK 及 PostgreSQL,Milvus 和 Redis 的密码。这些密码需要转换为 base64 编码,可以使用 echo -n "<password>" | base64 命令快速获取 base64 编码。SECRET_KEY 是 Dify 用来安全地签名会话 cookie 并加密数据库中的敏感信息的密钥,可以使用 openssl rand -base64 42 命令生成强密钥。MILVUS_PASSWORD 可以在 Milvus 向量数据库中进行设置,默认为 Milvus。ElastiCache for Redis 除了用作缓存,也被用作 Celery 的消息队列,CELERY_BROKER_URL 就是用来配置 Celery 的 Broker,格式为 redis://<redis_username>:<redis_password>@<redis_host>:<redis_port>/<redis_database>,因为这个 URL 中涉及到 Redis 的密码,所以我们将其放在 Secret 中。
    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Secret
    metadata:
      name: dify
    type: Opaque
    data:
      SECRET_KEY: <Replace your SECRET KEY here>
      S3_ACCESS_KEY: <Replace your S3 ACCESS KEY here>
      S3_SECRET_KEY: <Replace your S3 SECRET KEY here>
      DB_PASSWORD: <Replace your PostgreSQL PASSWORD here>
      MILVUS_PASSWORD: <Replace your MILVUS PASSWORD here>
      REDIS_PASSWORD: <Replace your REDIS PASSWORD here>
      CELERY_BROKER_URL: <Replace your CELERY BROKER URL here>
    EOF
    
  4. 创建 values.yaml。需要替换 <>中的内容,包括 hostimage tagvector storeMILVUS_HOSTS3_ENDPOINTS3_REGIONS3_BUCKET_NAMEDB_USERNAMEDB_HOSTREDIS_HOST 和 ingress 等。我们禁用了 Dify 自带的对象存储 minio, Redis 和 PostgreSQL,使用 S3, ElastiCache for Redis 和 Amazon Aurora 替代。
  • host: ALB 对应的自定义域名,建议开启 TLS,host 需要保持和 DNS 提供商注册的自定义域名一致。
  • image tag:查看 Releases · langgenius/dify · GitHub,建议选择最新版本的 Dify。
  • vector store 和 MILVUS_HOST:向量数据库配置。可选的配置有如下选项,本次案例使用的是 Milvus。
    • weaviate
    • qdrant
    • milvus
    • zilliz,与 milvus 一致
    • OpenSearch
    • tidb_vector
  • S3_ENDPOINTS3_REGION 和 S3_BUCKET_NAME:修改为您自己的 S3 endpoint, region, bucket name。
  • DB_HOSTDB_USERNAME 和 DB_DATABASE:修改为您自己的 PostgreSQL 数据库的信息,本例子中使用的是 Aurora PostgreSQL。
  • REDIS_HOST 和 REDIS_USERNAME:修改为您自己的 ElastiCache for Redis 的信息,建议开启密码认证,同时设置 REDIS_USE_SSL 为 true
  • ingress:您的 EKS 的 Ingress 配置,我们使用 AWS Load Balancer Controller 来创建 Ingress。强烈建议开启 HTTPS,并进行对应的设置,详见:Route internet traffic with AWS Load Balancer Controller - Amazon EKS。开启 HTTPS 同时需要设置 enableTLS 为 true,并将 alb.ingress.kubernetes.io/certificate-arn 替换为域名的 ACM 证书 ARN。请确保您的 EKS Ingress 是正常工作的。
    global:
      host: "<your domain name>"
      enableTLS: true
    
      image:
        # Set to the latest version of dify
        # Check the version here: https://github.com/langgenius/dify/releases
        # If not set, Using the default value in Chart.yaml
        tag: "0.7.2"
      extraBackendEnvs:
      # The log output level. Default is INFO. For production environments, it's recommended to set this to ERROR
      - name: LOG_LEVEL
        value: "ERROR"
      - name: SECRET_KEY
        valueFrom:
          secretKeyRef:
            name: dify
            key: SECRET_KEY
      # milvus
      - name: VECTOR_STORE
        value: "milvus"
      - name: MILVUS_HOST
        value: "<your Milvus endpoint>"
      - name: MILVUS_PORT
        value: "19530"
      - name: MILVUS_USER
        value: "root"
      - name: MILVUS_PASSWORD
        valueFrom:
          secretKeyRef:
            name: dify
            key: MILVUS_PASSWORD
      - name: MILVUS_SECURE
        value: "false"
      # External S3 bucket
      - name: S3_ENDPOINT
        value: "https://s3.<your region code>.amazonaws.com"
      - name: S3_REGION
        value: "<your region code>"
      - name: S3_BUCKET_NAME
        value: "<your bucket name>"
      - name: S3_ACCESS_KEY
        valueFrom:
          secretKeyRef:
            name: dify
            key: S3_ACCESS_KEY
      - name: S3_SECRET_KEY
        valueFrom:
          secretKeyRef:
            name: dify
            key: S3_SECRET_KEY
      # External postgresql
      - name: DB_USERNAME
        value: "<your postgres username>"
      - name: DB_PASSWORD
        valueFrom:
          secretKeyRef:
            name: dify
            key: DB_PASSWORD
      - name: DB_HOST
        value: "<your postgres endpoint>"
      - name: DB_PORT
        value: "5432"
      - name: DB_DATABASE
        value: "<your postgres database>"
      # External Redis
      - name: REDIS_HOST
        value: "<your redis endpoint>"
      - name: REDIS_PORT
        value: "6379"
      - name: REDIS_DB
        value: "0"
      - name: REDIS_USE_SSL
        value: "true"
      - name: REDIS_USERNAME
        value: "<your redis username>"
      # it is adviced to use secret to manage you sensitive info including password
      - name: REDIS_PASSWORD
        valueFrom:
         secretKeyRef:
           name: dify
           key: REDIS_PASSWORD
      # CELERY_BROKER_URL, format: "redis://<redis_username>:<redis_password>@<redis_host>:<redis_port>/<redis_database>"
      - name: CELERY_BROKER_URL
        valueFrom:
          secretKeyRef:
            name: dify
            key: CELERY_BROKER_URL
      - name: BROKER_USE_SSL
        value: "true"
    
    ingress:
      enabled: true
      className: "alb"
      annotations:
        kubernetes.io/ingress.class: "alb" # Annotation: set ALB ingress type
        alb.ingress.kubernetes.io/scheme: "internet-facing" #Places the load balancer on public subnets
        alb.ingress.kubernetes.io/target-type: "ip" #The Pod IPs should be used as the target IPs (rather than the node IPs)
        alb.ingress.kubernetes.io/certificate-arn: "<your domain URL certificate ARN>"
        alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
        alb.ingress.kubernetes.io/ssl-redirect: '443'
    
    minio:
      embedded: false
    
    postgresql:
      embedded: false
    
    redis:
      embedded: false
    
  1. 执行如下命令进行安装。
    helm install dify douban/dify -f values.yaml
  2. Dify 的核心服务如 apiworkerfrontendsandbox 默认配置为一个副本,为了提高高可性,需要增加副本数量。使用以下配置创建 new_values.yaml,并运行 helm upgrade dify douban/dify --reuse-values -f new_values.yaml 命令进行更新。
    frontend:
      replicaCount: 2
    
    api:
      replicaCount: 2
    
    worker:
      replicaCount: 2
    
    sandbox:
      replicaCount: 2
    
  1. 验证安装。使用 kubectl get ingress 命令获取 endpoint,如果能正确获取,浏览器打开 HOSTS 即可访问。
    NAME   CLASS   HOSTS                  ADDRESS                                 PORTS   AGE
    dify   alb     dify.yourcompany.com   dify-xxxx.us-west-2.elb.amazonaws.com   80, 443 10d
    

Dify 登陆界面,部署成功

### Dify Kubernetes 部署教程 对于希望在 Kubernetes 上实现高可用性的用户来说,可以利用社区贡献的 Helm Charts 来部署 Dify[^2]。具体而言,通过使用 `dify-helm` 这一 Helm Chart 可以方便地将基于大语言模型的应用程序部署到 Kubernetes 中[^3]。 #### 准备工作 确保已安装并配置好以下工具: - **kubectl**: 用于命令行管理 Kubernetes 集群。 - **helm**: 安装和管理 Kubernetes 应用程序的包管理器。 - **AWS CLI (如果选择Amazon EKS)**: 如果打算在 AWS 的弹性容器服务上运行,则需准备此客户端来操作云资源。 #### 获取 Helm Chart 可以通过 GitCode 平台获取由社区维护的 `langgenious/dify` Helm Chart: ```bash git clone https://gitcode.com/gh_mirrors/di/dify-helm.git cd dify-helm ``` #### 修改配置文件 进入克隆下来的仓库目录后,会发现有一个名为 `values.yaml` 的文件,在这里可以根据实际需求调整应用的各项参数设置,比如镜像标签、副本数量等。 #### 执行安装命令 完成上述准备工作之后,就可以执行如下命令来进行应用程序的实际部署了: ```bash helm install my-dify ./dify-helm -f values.yaml ``` 这将会把定义好的服务发布至指定的目标环境中去,并按照预先设定的方式启动各个组件实例。 #### 访问应用 一旦成功部署完毕,便可通过浏览器或其他 HTTP 工具访问新创建的服务端点,默认情况下它会被映射为集群内部的一个 Service 对象;若要从外部网络连接,则可能还需要额外配置 Ingress 或 LoadBalancer 类型的服务暴露机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值