为了账号安全,请及时绑定邮箱和手机立即绑定

用Terraform在30分钟内部署生成式AI应用

这篇文章基于我一个月前写的一篇文章,SQL 查询 + pgvector:PostgreSQL 中的检索增强生成。我将在 SQL 实例中使用 pgvector 存储数据和嵌入,并在 Google Kubernetes Engine (GKE) 上运行生成式 AI 应用。相似度结果将通过 SQL 查询在聊天机器人中展示。

将生成三个应用。

  • 一个 init-db,它只会运行一次,并作为一个任务连接到数据库。
  • 另一个应用 load-embeddings,它也只会运行一次,将数据加载到 Vertex AI 平台,然后使用 pgvector 将嵌入加载到数据库中(用于相似性计算)。
  • 一个 chatbot api,它会运行并接收包含自然语言查询的 curl 命令,返回符合查询条件的儿童玩具信息。

此解决方案将通过Terraform自动部署,并且您可以通过简单地修改项目中某个文件夹内的CSV文件以及包含创建表和部署向量索引的SQL查询的Python文件,将其复制到其他领域。

我们将采用以下架构:

架构设计

Terraform 是由 HashiCorp 开发的一款开源基础设施即代码(IaC)软件工具(简称 Terraform)。它允许用户使用 HashiCorp 配置语言(HCL)或可选的 JSON 来定义和管理数据中心基础设施。Terraform 声明性地描述基础设施资源,如虚拟机、网络、存储等,说明所需的最终状态,而不是到达该状态的具体步骤。

以下是一些 Terraform 的关键特性和概念:

使用Terraform: 您可以在配置文件中定义所需的基础设施架构。然后,Terraform会自动计算并执行达到该架构所需的步骤。

提供者: Terraform 使用提供者来与各种云服务提供商、基础设施平台和其他服务进行交互。提供者是插件,以扩展 Terraform 的功能以与特定 API 进行交互,例如 AWS、Azure、Google Cloud 等。Terraform 的 Google Cloud 文档可以在这里找到 此处此处,并且有很多示例可以在这两个链接中找到 这里这里

**状态管理:Terraform 使用状态文件来跟踪你的基础设施的状态,该文件存放在一个存储桶里。这个文件用于将实际资源映射到你的配置中,这样 Terraform 就能确定需要做出哪些更改来达到期望的状态,就像使用 diff 比较一样。

计划与应用: Terraform 按照三个步骤进行:首先是运行 terraform init。然后,执行 terraform plan,这会显示 Terraform 将如何更改你的基础设施,然后运行 terraform apply,这会将这些更改应用到你的基础设施。这样你就可以在实际应用更改前查看并批准这些更改。

模块化与可重用性: Terraform 配置可以组织成模块,这样你就可以在不同的项目中封装和重用基础设施组件。这有助于提高基础设施管理的模块化、一致性和可扩展性,并加快部署速度,由于这些组件可以并行部署。

基础设施即代码(IaC):Terraform 拥抱了基础设施即代码的概念,让您能够版本控制基础设施配置,更高效地协作,并自动化基础设施的部署。

总体来说,Terraform 简化了管理基础设施的过程,通过提供一种一致且高效的方式来定义、部署和管理跨不同云提供商和平台的资源。它在 DevOps 流程和云原生开发流程中被广泛使用。

例如,在 network.tf 中,通常会有一个 模块 和它的 资源

变量定义于另一个文件中,即 'variables.tf'。

一个简单易懂的地方来学习 Terraform 基础知识是 Google Cloud Skills Boost(访问 Google Cloud Skills Boost 网站)(访问链接)。

在我们开始之前,请在 Google Cloud 上创建一个新项目。这将帮助你将此次自动化的部署与其他可能的服务隔离,并能更好地控制相关费用。

其次,请注意SQL实例的费用和SSD磁盘的使用。

我们将在GitHub上克隆GoogleCloudPlatform仓库(或存储库):

要克隆此仓库,请运行以下命令:
git clone https://github.com/GoogleCloudPlatform/cloudsql-gke-demo-for-genai
这是Google Cloud Platform提供的一个示例项目,用于在GenAI环境中演示Cloud SQL与GKE的集成。

你会看到我们有以下几个文件夹:

  • 为每个将要创建的 app image(共3个),包括一个 Dockerfile、Python 脚本、库依赖、一个定义了 docker 脚本和镜像名称的 .yaml 文件,以及一个包含用于聊天机器人应用的任务和部署所需 .yaml 文件的 k8s 文件夹。
  • 包含用于基础设施部署和变量定义的 .yaml 文件的 terraform 文件夹。
  • 一个用于自动在每个应用的 .yaml 文件中更新 PROJECT 名称的 _bash 脚本。

我们必须确保这些CLI命令都已准备好。

  • gcloud : 安装方法,请参见这里

  • kubectl : 用于处理 GKE (kubernetes) 部署的命令。此命令将通过 gcloud 后续自动安装。

  • terraform :请根据需要安装此工具。
    sudo apt update  # 更新软件包列表  
    sudo apt install snapd  # 安装 Snap 包管理器  
    sudo snap install terraform --classic  # 使用经典模式安装 Terraform

现在为 gcloud 命令指定项目:

    gcloud auth login,  
    gcloud config set project 你的项目名

进入 terraform-bootstrap 目录,这里将定义全局变量,比如 Google Cloud 项目、区域、存储桶策略以及 Terraform 版本。你可以创建一个新的文件,用 nanogeditvim 来创建:

在终端中输入以下命令:```
sudo nano terraform.tfvars


你可以在这个新文件里加下面的内容.
谷歌云项目        = “你的项目”  
谷歌云默认区域     = “us-central1”

接着按 _CTRL+O_,回车,然后按 _CTRL+X_ 退出。

现在我们将运行 Terraform。
terraform init (初始化 Terraform)

![](https://imgapi.imooc.com/672ad88e09f0843706600152.jpg)

然后,计划所有改动:这会显示将要创建的所有资源。

terraform 计划


![](https://imgapi.imooc.com/672ad890097a3e0c07210459.jpg)

最后,保存更改:资源将被创建好了。
terraform apply
执行 terraform 命令

![](https://imgapi.imooc.com/672ad89109eca6da08710367.jpg)

![](https://imgapi.imooc.com/672ad89209ef524706070098.jpg)

保存这个桶名以备后续步骤使用。在使用 Terraform 进行云端部署时,通常会使用一个存储桶来存放 Terraform 状态文件。Terraform 状态文件对于管理基础设施的状态、跟踪资源依赖和管理更新至关重要。

现在,在命令行中切换到包含所有打算部署的基础设施的_terraform_目录,并创建一个名为_backend.conf_的文件。

在终端中输入以下命令来编辑`backend.conf`文件:(以下是未翻译的命令)  
sudo nano backend.conf
使用`sudo`命令以超级用户权限运行`nano`文本编辑器来编辑`backend.conf`文件。

输入在上一步得到的桶的名字。
bucket = "90fedee19eb3ade1-bucket-tfstate"  # 存储桶名称
prefix = "terraform/state"                  # 前缀设置

按 Ctrl+O,回车,然后按 Ctrl+X 保存后退出。

我们现在开始使用Terraform,并用我们刚创建的后端设置进行初始化。

terraform init -backend-config=backend.conf

此命令用于初始化 Terraform 配置,并设置后端配置文件为 `backend.conf`。

![](https://imgapi.imooc.com/672ad89309c7436207270417.jpg)

现在,使用 _nano/gedit/vim_ 创建一个 _terraform.tfvars_ 文件来配置部署,如下所示。该文件应该包含以下内容:

google_cloud_db_project = "your-project" # Google云数据库项目名称
google_cloud_k8s_project = "your-project" # Google云K8S项目名称
google_cloud_default_region = "us-central1" # 默认地区设置为us-central1
create_bastion = false # 是否创建bastion,默认为false


堡垒是一种位于公共互联网和私有网络之间的网关。其主要目的是为私有网络内的资源提供安全访问,通常在VPC环境中使用。它通常位于网络边缘,并作为管理员访问私有网络内资源的唯一入口。若要测试跳板服务器并通过SSH访问内部资源,可将值设为 _true_。否则设为 _false_。

现在运行一下。

执行 terraform 计划
执行 terraform 应用


这个命令将自动创建如下基础设施:

* 一个具有一个子网的 **VPC 网络**,该子网包含一个主范围和两个次级范围。主范围是分配给子网的主要 IP 地址块,通常用于直接连接到网络的设备。而次级范围则可能用于特定目的,例如来宾访问,或者将某些类型的流量分离。
* 一个启用了 IAM 身份验证的 **Cloud SQL 数据库** 实例。
* 一个用于运行应用程序和数据库身份验证的 **IAM 用户账户**。
* 一个为应用程序服务的 **数据库**。
* 一个将运行两项任务(连接到数据库和生成嵌入)并创建聊天机器人应用的 **GKE Autopilot 集群**。
* 与 IAM 用户账户关联的 **工作负载身份**。工作负载身份是允许您安全地将工作负载(例如 Compute Engine 虚拟机或 Kubernetes 引擎集群)身份验证到 Google Cloud 服务的一项功能,无需手动管理服务账户密钥。通过使用工作负载身份,您可以遵循最小权限原则,同时通过减少服务账户密钥和其他敏感凭证的暴露来增强安全性。
* 一个用于推送三个应用镜像的 **Artifact Registry**,通过 Docker。

注意,基础设施是并行部署的。这意味着Terraform在部署一个资源的同时不会等待其完成,而是并行部署其他资源。部署速度快是其优点之一。另一个优点在于标准化。配置文件定义了基础设施,每次部署,状态都会保持一致。

在即将创建的所有资源中,你都能看到“+”符号,你需要同意部署。

![](https://imgapi.imooc.com/672ad89409fda58406760492.jpg)

在整个过程中,GKE的创建时间最长,大约需要10分钟左右。

![](https://imgapi.imooc.com/672ad895099f1f8107310448.jpg)

在基础设施部署完成后,我们会通知你:

![](https://imgapi.imooc.com/672ad89609cceff606420148.jpg)

注意,需要注意的是,在此部署中,我们在VPC内部使用了**私有服务连接(PSC)**。这意味着每个架构组件都通过内部IP进行私有连接交互,减少了恶意攻击者对解决方案的攻击面。外部用户将通过单一端点进行访问,该端点由Google Kubernetes Engine (GKE) 创建的负载均衡器提供。

现在我们将分三个步骤在Artifact Registry中部署镜像:

1. **数据库:** 切换到 \_init-db\_ 文件夹并运行命令:

你可以使用以下命令提交构建任务:

gcloud builds submit --config cloudbuild.yaml --region us-central1


2\. **嵌入:** 对“加载嵌入”文件夹也进行同样的操作。

运行以下命令提交构建配置文件:`gcloud builds submit --config cloudbuild.yaml --region us-central1`.

3\. **聊天机器人应用部分:** 同样适用于此文件夹:chatbot-api

运行这个命令可以提交构建配置文件并指定区域:``gcloud builds submit --config cloudbuild.yaml --region us-central1```

每个这样的 `_cloudbuild.yaml` 文件都会运行一个 docker 命令并定义一个镜像的名称,在 Artifact Registry 中自动创建该镜像。如果你进入 Artifact Registry,你会看到一个包含这三个 Docker 镜像的文件夹。

现在,让我们将 Kubernetes _.yaml_ 文件(每个应用程序文件夹内的 k8s 子文件夹)指向我们创建的镜像文件。Google 创建了一个 bash 脚本,可以自动替换这些文件中的 __PROJECT__ 占位符,只需运行相应的命令。

运行脚本来配置 Kubernetes (K8s):
./scripts/configure-k8s.sh your-project

我们差不多准备好了。安装 _gcloud_ 的 GKE 插件:
gcloud components install gke-gcloud-auth-plugin
安装 gke-gcloud-auth-plugin 插件(此命令无需翻译,直接使用英文命令)。

![](https://imgapi.imooc.com/672ad8970992e83b05500440.jpg)

另外,我们还需要_kubectl_命令来操作GKE:

在终端中运行以下命令以安装kubectl:

    gcloud components install kubectl

请注意,此处的命令是英文。
kubectl是用于管理Kubernetes集群的命令行工具。```

输入集群名称(prod-toy-store-semantic-search),然后获取与Kubernetes集群交互所需的凭证。

gcloud container clusters get-credentials prod-toy-store-semantic-search --region=us-central1
# 运行此命令以获取生产玩具店语义搜索集群的凭证,集群位于us-central1区域。

现在我们可以部署连接到数据库、创建数据库并获取IAM权限的K8作业了。名为 job.yaml 的文件将使用我们刚刚制作的 init-db 镜像来连接到数据库,作为Kubernetes作业。

在仓库根目录下运行“init-db”命令:

运行以下命令来应用初始化数据库的作业配置文件,然后列出所有的作业:

    kubectl apply -f init-db/k8s/job.yaml  
    kubectl get jobs

对于 load-embeddings 文件夹,也执行相同的操作,以执行创建 embeddingsvector index 的任务:

    kubectl apply -f load-embeddings/k8s/job.yaml  
    kubectl get jobs

这会使用在 load-embeddings 文件夹中的 CSV 文件,连接到数据库,使用 RecursiveCharacterTextSplitter 进行分块,生成嵌入,然后创建并加载一个包含产品名称和嵌入向量的向量索引表。

CSV 文件项目

你将会看到每个工作各运行一次,然后显示为完成。

kubectl get jobs

这里有趣的一点是,你可以用我们正在搭建的相同项目和基础设施,只要用不同的 CSV 文件就行,只要你的 CSV 文件的列和我们的一样,或者稍微修改一下 load-embeddings 文件夹里的 main.py 文件以适应你的需求,因为这个文件会用 SQL 语法来操作 CSV 列的数据。

一旦这两项工作完成后,我们就可以部署聊天机器人应用了。

    kubectl apply -f chatbot-api/k8s/deployment.yaml
    # 在终端中执行此命令以应用部署配置

命令如下:kubectl get jobs (查看作业列表)

接着我们创建负载均衡器,让API可以通过公网访问。

运行以下命令来应用 YAML 文件:kubectl apply -f chatbot-api/k8s/service.yaml

kubectl get services  # 获取服务列表

等待外部IP创建。这里应用将不使用Flask,而是使用FastAPI。查询响应将通过嵌入相似性给出,这是通过chatbot-api文件夹下_app_文件中的_main.py_文件里的_pgvector_查询实现的,并通过_LangChain_整合到对话中。

一旦你对数据集应用了嵌入和分块,你还可以选择使用像Gemini或Gemma这样的大型语言模型 (LLM),将此上下文用于RAG解决方案中。基础设施已经准备好了,你只需要在 main.py 文件中添加这个LLM即可。

如你所见,创建外部IP需要几分钟。一旦创建完成,使用_curl_检查它的状态是否为200。

现在我们可以通过curl向GKE端点提交查询了。你也可以用Python的requests库。只需获取端点的URL,然后将查询POST请求到该端点。

curl 35.223.23.44/chatbot --get --data-urlencode "q=雨天有什么好玩的玩具?"

curl 35.223.23.44/chatbot --get --data-urlencode \
"q=海滩上玩的好玩具是什么?"

要删除所有已部署的基础架构,首先需要删除Google Kubernetes Engine(GKE)部署。然后在项目的根目录下执行相应的命令。

运行以下命令来删除部署文件:

kubectl delete -f chatbot-api/k8s/deployment.yaml

接着,删除负载均衡器:

# 运行以下命令来删除服务配置文件:kubectl delete -f chatbot-api/k8s/service.yaml

然后,删除基础设施。如果你看到错误,例如在删除SQL实例时,如果创建了私有服务连接,你可能会看到错误。不要删除任何组件不用Terraform,否则会破坏它,使其无法再工作。如果这样做,你将不得不手动删除资源。提到“运行两次destroy”时,需要执行两次terraform destroy命令。

cd terraform  
terraform destroy

切换到terraform目录并执行销毁命令

感谢

✨ Google 机器学习开发者团队通过提供 Google Cloud 积分支持了这项工作 ✨

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消