亚马逊AWS官方博客

基于 AWS CDK 部署 Dify 社区版的高可用方案

一、背景介绍

从趋势来看,AI Agent 工作流程正引领着人工智能的下一次革命,其潜力远超仅依赖基础模型的传统方法。AI Agentic 编排工具代表了未来人工智能应用的发展方向,通过将用户需求、业务系统和先进的 AI 技术有机结合,构建了一个全面且协调的生态系统,在业务系统和基础模型之间搭建了高效的桥梁。

Agentic AI 平台不仅具备强大的基础模型能力,还无缝集成了业务知识库、提示词工程、函数调用以及工具应用等多项关键功能。这种多层次的集成,使得 AI Agent 能够更智能地理解并响应复杂的业务需求。同时,通过引入检索增强生成(RAG)技术和安全围栏,平台确保了信息的准确性与系统的安全性。更为重要的是,AI Agent 的设计理念彰显了 AI 技术的范式转变——从单一模型应用走向更加综合、智能且安全的架构。这一转变为企业提供了更加高效、灵活且可扩展的 AI 解决方案。

二、Dify 概述

1.  Dify 社区版本功能介绍

Dify 是一款开源的 LLM 应用开发平台,为 AI 应用的快速构建与部署提供了一站式解决方案。它具备直观友好的界面,集成了 AI 工作流、RAG 管道、智能代理、模型管理以及可观测性等先进功能,使开发者能够轻松地将 AI 应用从概念原型转化为生产就绪状态。以下是 Dify 的核心功能:

  • 智能工作流:通过可视化画布设计和测试强大的 AI 流程,充分利用平台丰富的功能,简化开发流程。
  • 全方位模型支持:无缝集成“专有和开源”大语言模型,支持多种推理服务提供商和自托管方案,兼容主流模型如 Claude、Mistral、Llama 等,详细的支持列表可在官方文档中查阅。
  • Prompt IDE:提供直观的界面用于提示词编辑、模型性能对比,并为基于对话的应用增加如文本转语音等增强功能。
  • RAG 管道:提供全面的检索增强生成功能,覆盖从文档摄入到信息检索的全流程,内置对 PDF、PPT 等常见文档格式的文本提取支持。
  • 智能代理:支持基于 LLM 的函数调用或 ReAct 范式定义的 Agent,并可为 Agent 配置预置或自定义工具。Dify 内置了 50 多种工具,包括 Google 搜索、DALL·E、Stable Diffusion 和 WolframAlpha 等。
  • LLMOps:提供应用日志和性能的实时监控与分析,支持基于生产数据和标注持续优化提示词、数据集与模型性能。
  • 后端即服务:Dify 的所有功能均配备相应的 API,便于开发者将 Dify 无缝集成到自有业务逻辑中。

2.  Dify 社区版本-技术组件说明

目前 Dify 社区版本提供三种部署方式 — 本地、Docker 以及 K8S,用户可以结合自己的需求来进行选择:

  • Agent平台:API、worker、Fronted
  • 知识库:Weaviate
  • 缓存:ElastiCache For Redis,
  • 数据库 PostgreSQL
  • 资源类文件:S3

然而,Dify 的社区版本是通过 Docker Compose 进行部署的,这种方式难以满足生产环境中对高可用性的需求。为了解决这一问题,我们采用了 Dify 官方发布的 Docker 镜像,并结合亚马逊云科技的托管服务,优化了部署方案。这种改进不仅提升了系统的高可用性,还能够更好地适应生产环境的部署要求,确保应用能够在高负载和复杂场景下稳定运行。

三、方案特点

我们根据实际的使用场景设计方案,总结有以下特点:

  • 基础设施即代码(IaC)部署:通过 AWS CDK 实现极简化运维,快速构建 Dify 所需的托管服务,实现自动化部署,简化管理流程。
  • 使用托管服务:集成 AWS 托管服务,如 RDS Aurora PostgreSQL、Elasticache Redis 和 Amazon OpenSearch,确保系统的高性能和可扩展性。
  • 成本优化:为进一步降低客户的运营成本,推荐使用无服务器化的产品,如 Aurora Serverless v2 和 ElastiCache Serverless,不仅减少资源闲置,还能按需自动扩展,优化成本投入。

四、方案架构

五、方案部署指引

1. 配置仅访问 S3 的 IAM 用户权限

步骤一:登录 AWS 管理控制台,进入 IAM 服务。在左侧导航栏中选择“用户”,然后点击“添加用户”。设置用户名。在权限设置页面,选择“直接附加现有策略”,搜索并选中“AmazonS3FullAccess”策略,为该用户赋予完全访问 S3 的权限。

步骤二:用户创建完成后,您将看到访问密钥 ID 和私有访问密钥。请务必妥善保存这些凭证,因为这是您唯一一次可以查看和下载它们。凭证丢失将无法恢复,需重新生成新的密钥。

2. 环境准备&下载 Dify 源码

+AMI 要求

# 安装 AWS CDK
sudo -i 
sudo yum install nodejs git -y
sudo npm install -g aws-cdk 
sudo npm install -g typescript ts-node
#npm install

# 下载 Dify on EKS 源码包
git clone https://github.com/KevinZhao/dify_helm.git
cd dify_helm/dify-cdk
npm install

3. 修改并运行 CDK

在 CDK 部署过程中,建议使用 --concurrency 5 参数来启用并行部署,这将大大缩短部署时间,整个过程大约需要 20 分钟左右。如果不使用并行部署,可能会额外增加时间。

vi cdk.json 

    "dbPassword": "Your.dbPassword.0910",  #请修改
    "opensearchPassword": "Your.aosPassword.0910", #请修改
    "S3AccessKey": "Your.S3.AccessKey", #请修改
    "S3SecretKey": "Your.S3.SecretKey", #请修改

cdk bootstrap
cdk deploy --all --concurrency 5 --require-approval never

4. 修改 ALB Host 环境变量地址

CDK 部署完成后,请前往 AWS 管理控制台,导航至 EC2 服务中的 负载均衡器(Load Balancers)。在此页面找到由 AWS Load Balancer Controller 创建的 应用型负载均衡器(ALB)。点击 ALB 名称以查看其详细信息,并在 描述(Description)部分中找到并记录 DNS 名称(DNS Name)。

改域名的原因和如果有域名的操作步骤

在修改 bin 目录下的 dify-helm-stack.ts 文件时,您需要将 global.hostingress.hosts.host 的值替换为 ALB 的 DNS 名称。具体步骤如下:

  1. 打开 dify-helm-stack.ts 文件
  2. 找到以下代码片段,并将 host 和 ingress.hosts.host 的值修改为 ALB 的 DNS 名称
  3. YOUR_ALB_DNS_NAME 替换为从 AWS 管理控制台中获取到的实际 ALB DNS 名称
    # 修改Dify Helm中ALB的DNS地址
    cd bin/
    vi dify-helm-stack.ts
    
    // Here comes dify helm configuration  
        const difyHelm = new eks.HelmChart(this, 'DifyHelmChart', {
          cluster: props.cluster,
          chart: 'dify',
          repository: 'https://douban.github.io/charts/',
          release: 'dify',
          namespace: 'dify',
          values: {
            global: {
              //Specify your host on ALB DNS name
              host: 'k8s-dify-dify-XXXXXX.us-west-2.elb.amazonaws.com', #需要修改
              port: '',
              enableTLS: false,
              image: {
                tag: '0.8.3',
              },
              edition: 'SELF_HOSTED',
              storageType: 's3',
              extraEnvs: [],
              ....
              }
            }
          }  
          
          
        ingress: {
              enabled: true,
              className: 'alb',
              annotations: {
                'kubernetes.io/ingress.class': 'alb',
                'alb.ingress.kubernetes.io/scheme': 'internet-facing',
                'alb.ingress.kubernetes.io/target-type': 'ip',
                'alb.ingress.kubernetes.io/listen-ports': '[{"HTTP": 80}]',
                //'alb.ingress.kubernetes.io/listen-ports': '[{"HTTPS": 443}]',
                //'alb.ingress.kubernetes.io/certificate-arn': 'arn:aws:acm:us-west-2:788668107894:certificate/ef51825b-4626-48af-a05e-4147ae485caf',
              },
              hosts: [{
                host: 'k8s-dify-dify-XXXX.us-west-2.elb.amazonaws.com',  #需要修改
                paths: [
                  {
                    path: '/api',
                    pathType: 'Prefix',
                    backend: {
                      serviceName: 'dify-api-svc',
                      servicePort: 80
                    },
                    annotations: {
                      'alb.ingress.kubernetes.io/healthcheck-path': '/health',
                      'alb.ingress.kubernetes.io/healthcheck-port': '80'
                    }
                  }
                }   
            }    
    # 重新执行CDK更新脚本
     cdk bootstrapcdk deploy --all --concurrency 5  --require-approval never
    

5. 注册登陆 EKS 集群

创建一台能够连接到 EKS 的虚拟机,并通过 aws configure 配置 AWS 凭证后使用 aws sts get-caller-identity 获取 IAM 用户访问身份。

aws sts get-caller-identity
{
    "UserId": "AROAW4PMWBUPX5H6ICQ53:i-0d04c84c17a103bfc",
    "Account": "XXXX",
    "Arn": "arn:aws:sts::XXXXX:assumed-role/PVRE-SSMOnboardingRole-11S3ONW27H3O3/i-0d04c84c17a103bfc"
}

在 EKS 控制台的“访问”标签页,创建一个新的访问条目,并添加之前获取的 IAM 用户身份。附加 AmazonEKSAdminPolicy 策略,确保点击“添加策略”按钮以完成操作,否则策略将无法成功添加。

配置好 EKS 服务器后,在虚拟机上安装 kubectl,并配置连接到 EKS 集群。

curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.30.2/2024-07-12/bin/linux/amd64/kubectl
chmod +x ./kubectl
mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$HOME/bin:$PATH
echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc
kubectl version --client

aws eks update-kubeconfig --region us-west-2 --name dify-eks
kubectl get pod -A

NAMESPACE     NAME                                            READY   STATUS    RESTARTS   AGE
dify          dify-api-7df4d646b8-sqw2w                       1/1     Running   0          15m
dify          dify-frontend-5f9667ddc5-cq5fp                  1/1     Running   0          15m
dify          dify-sandbox-7dcc455bc8-hc84l                   1/1     Running   0          30m
dify          dify-worker-95dc655b4-pq7rm                     1/1     Running   0          15m
kube-system   aws-load-balancer-controller-66b5c85fd5-dw6dt   1/1     Running   0          34m
kube-system   aws-load-balancer-controller-66b5c85fd5-kl24w   1/1     Running   0          34m
kube-system   aws-node-c6tvf                                  2/2     Running   0          36m
kube-system   aws-node-tnmfr                                  2/2     Running   0          36m
kube-system   coredns-787cb67946-6qqlr                        1/1     Running   0          40m
kube-system   coredns-787cb67946-hkz7b                        1/1     Running   0          40m
kube-system   kube-proxy-qlhnj                                1/1     Running   0          36m
kube-system   kube-proxy-tzm55                                1/1     Running   0          36m

6. Dify 数据库初始化

在 Dify 平台的首次安装过程中,需要进行数据库初始化。可以参考以下命令来执行数据库升级:

#dify数据库初始化过程
kubectl exec -it $(kubectl get pods -n dify -l app.kubernetes.io/component=api -o jsonpath='{.items[0].metadata.name}') -n dify -- flask db upgrade

首次运行系统时,还需要设置管理员账户。如果数据库未成功初始化,设置管理员账户的界面可能会出现错误。因此,请确保在系统首次启动前已正确完成数据库的初始化操作,以避免不必要的问题。

六、总结

在本文中,我们详细探讨了如何利用 AWS CloudFormation 基于 Amazon EKS 构建 Dify 平台。该解决方案充分展示了云原生架构的优势,巧妙结合了容器技术和无服务器架构(Serverless),通过 EKS 集群实现了高可用性和可扩展性。Dify 平台的引入则为我们带来了 AI 能力的无缝集成,大幅提升了应用的智能化水平。

Dify 平台不仅提供了租户管理、鉴权机制和安全围栏等关键功能,还通过 AI-Platform Proxy 实现了与各种 AI 服务的灵活对接。这个精心设计的架构使系统能够灵活应对不同的业务需求,同时确保了高水平的安全性和可管理性。

展望未来,我们将继续探索 Dify 工作流的更多可能性,研究更多节点和功能,以进一步拓展 AI 应用的边界。我们期待在后续的文章中,能够与读者一起深入学习和探索这个充满潜力的平台,共同推动 AI 技术在实际应用中的创新与突破。通过持续的实践与优化,我们相信能够为 AI 驱动的解决方案开辟新天地,并为各行各业带来更多价值。

希望本文对您有所帮助,如果您有任何疑问或需要进一步的信息,请随时联系我们!

本篇作者

赵克鸣

亚马逊云科技解决方案架构师,负责云计算解决方案的咨询和设计。热爱 AI/ML 领域的技术研究,并通过可实施的解决方案,帮助客户取得业务价值。

于涛

亚马逊云科技解决方案架构师,负责亚马逊云科技云计算方案咨询和设计。目前主要专注在现代化应用改造和机器学习领域的技术研究和实践。加入 AWS 之前曾服务于大型运营商及 IT 解决方案供应商,积累了丰富的跨境电商/快消行业项目经验。

原媛

亚马逊云科技解决方案架构师,负责基于 AWS 云计算方案的架构咨询和设计实现,具有丰富的解决客户实际问题的经验,同时热衷于时间序列数据分析的相关研究与应用。

刘佳鑫

西云数据解决方案架构师,目前为西云客户提供架构设计、解决方案、云原生及 GenAI 应用原型开发,加入西云数据前,主要面向运营商、零售等行业客户提供移动无线网络、5G MEC、虚拟化、容器化及应用持续交付等产品及解决方案。

Chenlong Hu

亚马逊云科技客户技术经理,拥有丰富的跨国国际项目经验及海内外工作经验。在职业生涯中担任过产品经理,开发,架构师,运维工程师等多种角色。AWS/Azure 云解决方案架构师及 DevOps 专家,致力于通过云计算服务助力客户的成功。