为方便大家理解和感受 Python 探针的功能,本文构建了一个 LLM 应用的示例:
某公司升级了其产品,新增了智能问答功能。其基本架构图如下:
基本业务流程为用户向 server 端发起一个问答请求,server 去调用 chatbot 获取回复结果,chatbot 收到请求后进行 RAG 后回复。
为观测此 LLM 应用,该公司接入了阿里云 Python 探针。下文将介绍如何接入阿里云 Python 探针。
Python 应用接入应用监控
以下为在 ACK 环境下 Python 探针的接入方式,其他接入方式见:https://help.aliyun.com/zh/arms/application-monitoring/user-guide/start-monitoring-python-applications/
前提条件
- 创建 Kubernetes 集群。您可按需选择创建 ACK 专有集群、创建 ACK 托管集群或创建 ACK Serverless 集群。
- 创建命名空间,具体操作,请参见管理命名空间与配额。本文示例中的命名空间名称为 arms-demo。
- 检查您的 Python 版本和框架版本。具体要求,请参见 Python 探针兼容性要求。
步骤一:安装 ARMS 应用监控组件
-
登录容器服务管理控制台 [ 1] 。
-
在左侧导航栏单击集群,然后在集群列表页面单击目标集群名称。
-
在左侧导航栏选择运维管理 > 组件管理,然后在右上角通过关键字搜索 ack-onepilot。 (重要:请确保 ack-onepilot 的版本在 3.2.4 及以上。)
-
在 ack-onepilot 卡片上单击安装。 (说明:ack-onepilot 组件默认支持 1000 个 pod 规模,集群 pod 每超过 1000 个,ack-onepilot 资源对应的 CPU 请增加 0.5 核、内存请增加 512M。)
-
在弹出的页面中可以配置相关的参数,建议使用默认值,单击确定。 (说明:安装完成后,您可以在组件管理页面升级、配置或卸载 ack-onepilot 组件。)
步骤二:修改 Dockerfile
- 首先从 pypi 仓库下载探针安装器
pip3 install aliyun-bootstrap
- 使用 aliyun-bootstrap 安装探针
aliyun-bootstrap -a install
- 使用阿里云 python 探针启动
aliyun-instrument python app.py
- 构建镜像,具体的 Dockerfile 示例如下:
Dockerfile 示例:
更改前的 Dockerfile:
# 使用Python 3.10基础镜像
FROM docker.m.daocloud.io/python:3.10
# 设置工作目录
WORKDIR /app
# 复制requirements.txt文件到工作目录
COPY requirements.txt .
# 使用pip安装依赖
RUN pip install --no-cache-dir -r requirements.txt
COPY ./app.py /app/app.py
# 暴露容器的8000端口
EXPOSE 8000
CMD ["python","app.py"]
更改后的 Dockerfile:
# 使用官方的Python 3.10基础镜像
FROM docker.m.daocloud.io/python:3.10
# 设置工作目录
WORKDIR /app
# 复制requirements.txt文件到工作目录
COPY requirements.txt .
# 使用pip安装依赖
RUN pip install --no-cache-dir -r requirements.txt
#########################安装aliyun python 探针###############################
RUN pip3 install aliyun-bootstrap && aliyun-bootstrap -a install
##########################################################
COPY ./app.py /app/app.py
# 暴露容器的8000端口
EXPOSE 8000
#########################################################
CMD ["aliyun-instrument","python","app.py"]
注意事项(必看)
- 有使用 unicorn 启动的应用推荐使用以下命令做替换:
例如:
unicorn -w 4 -b 0.0.0.0:8000 app:app
更改为:
gunicorn -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 app:app
- 有使用 gevent 协程的需要配置参数
程序中有使用
from gevent import monkey
monkey.patch_all()
需要设置环境变量 GEVENT_ENABLE=true
GEVENT_ENABLE=true
步骤三:授予 ARMS 资源的访问权限
- 如果需监控 ASK(容器服务 Serverless 版)或对接了 ECI 的集群应用,请在云资源访问授权 [ 2] 页面完成授权,然后重启 ack-onepilot 组件下的所有 Pod。
- 如果需监控 ACK 集群应用,但 ACK 集群中不存在 ARMS Addon Token,请执行以下操作手动为集群授予 ARMS 资源的访问权限。如果已经存在 ARMS Addon Token,请跳转至步骤四。
查看集群是否存在 ARMS Addon Token:
a. 登录容器服务管理控制台,在集群列表页面,单击目标集群名称进入集群详情页。
b. 在左侧导航栏选择配置管理 > 保密字典,然后在顶部选择命名空间为kube-system,查看addon.arms.token是否存在。
说明:集群存在 ARMS Addon Token 时,ARMS 会进行免密授权。Kubernetes 托管版集群默认存在 ARMS Addon Token,但对于部分早期创建的 Kubernetes 托管版集群,可能会存在没有 ARMS Addon Token 的情况,因此,对于 Kubernetes 托管版集群,建议首先检查 ARMS Addon Token 是否存在。若不存在,需进行手动授权。
-
登录容器服务管理控制台。
-
在左侧导航栏选择集群,然后单击目标集群名称。
-
在目标集群的集群信息页面单击集群资源页签,然后单击 Worker RAM 角色右侧的链接。
-
在角色页面的权限管理页签上,单击新增授权。
-
选择权限为 AliyunARMSFullAccess,然后单击确定。 (如果需要监控专有版集群和注册集群应用,请确认对应的阿里云账号已包含 AliyunARMSFullAccess 和 AliyunSTSAssumeRoleAccess 权限。添加权限的操作,请参见为 RAM 用户授权 [ 3] 。 )
安装 ack-onepilot 组件后,还需要在 ack-onepilot 中填写有 ARMS 权限的阿里云账号 AK/SK。
-
在左侧导航栏选择应用 > Helm 页面,单击 ack-onepilot 组件右侧的更新。
-
将 accessKey 和 accessKeySecret 替换为当前账号的 AccessKey,然后单击确定。 (说明:获取 AccessKey 的操作,请参见创建 AccessKey [ 4] 。)
-
重启应用 Deployment。
步骤四:为 Python 应用开启 ARMS 应用监控
-
在容器服务管理控制台左侧导航栏单击集群,在集群列表页面上的目标集群右侧操作列单击应用管理。
-
在无状态页面的目标应用右侧选择更多 > 查看 YAML。 (如需创建一个新应用,单击右上角的使用 YAML 创建资源。)
-
在 YAML 文件中将以下 labels 添加到 spec.template.metadata 层级下。
labels:
aliyun.com/app-language: python # Python应用必填,标明此应用是Python应用。
armsPilotAutoEnable: 'on'
armsPilotCreateAppName: "<your-deployment-name>" #应用在ARMS中的展示名称。
创建一个无状态(Deployment)应用并开启 ARMS 应用监控的完整 YAML 示例模板如下:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: arms-python-client
name: arms-python-client
namespace: arms-demo
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: arms-python-client
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: arms-python-client
aliyun.com/app-language: python # Python应用必填,标明此应用是Python应用。
armsPilotAutoEnable: 'on'
armsPilotCreateAppName: "arms-python-client" #应用在ARMS中的展示名称。
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/arms-default/python-agent:arms-python-client
imagePullPolicy: Always
name: client
resources:
requests:
cpu: 250m
memory: 300Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: arms-python-server
name: arms-python-server
namespace: arms-demo
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: arms-python-server
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: arms-python-server
aliyun.com/app-language: python # Python应用必填,标明此应用是Python应用。
armsPilotAutoEnable: 'on'
armsPilotCreateAppName: "arms-python-server" #应用在ARMS中的展示名称。
spec:
containers:
- env:
- name: CLIENT_URL
value: 'http://arms-python-client-svc:8000'
- image: registry.cn-hangzhou.aliyuncs.com/arms-default/python-agent:arms-python-server
imagePullPolicy: Always
name: server
resources:
requests:
cpu: 250m
memory: 300Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
labels:
app: arms-python-server
name: arms-python-server-svc
namespace: arms-demo
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: http
port: 8000
protocol: TCP
targetPort: 8000
selector:
app: arms-python-server
sessionAffinity: None
type: ClusterIP
apiVersion: v1
kind: Service
metadata:
name: arms-python-client-svc
namespace: arms-demo
uid: 91f94804-594e-495b-9f57-9def1fdc7c1d
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: http
port: 8000
protocol: TCP
targetPort: 8000
selector:
app: arms-python-client
sessionAffinity: None
type: ClusterIP