监控ACK集群下的Python应用

通过本教程,您将学习如何将ACK集群下的Python应用接入ARMS应用监控,体验应用性能分析和调用链分析等功能,并配置告警。

说明

如需将其他环境下的应用接入应用监控,请参见应用接入

使用流程

  1. 为应用安装探针。

    1. 安装ack-onepilot组件:ack-onepilot是阿里云容器服务Kubernetes提供的系统组件,可以让部署在容器服务Kubernetes中的Java、GolangPython应用接入ARMS。

    2. 更新Dockerfile:下载aliyun-bootstrap探针安装器,安装探针后使用探针启动Python应用。

    3. 更新YAML:通过在应用的YAML中添加labels,开启监控并配置应用在ARMS中的展示名称。

  2. 查看监控数据。

  3. 为监控数据配置告警。

准备环境和资源

  • ACK:

    • 创建Kubernetes集群。具体操作,请参见创建ACK托管集群

    • 创建Python应用。

      • Python版本要求,请参见Python探针兼容性要求

      • Python应用需使用Gunicorn启动,例如:

        gunicorn -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 app:app
      • 如果有使用gevent协程,则需要设置环境变量GEVENT_ENABLE=true

      如果您没有可以使用的Python应用,可以参考以下示例YAML创建。具体操作,请参见创建无状态工作负载Deployment

      说明

      示例YAML创建了以下资源:

      • 空间名称:arms-demo。以下所有资源均创建在arms-demo命名空间下。

      • 无状态应用:arms-python-clientarms-python-server。

      • 服务:arms-python-client-svcarms-python-server-svc。

      展开查看完整示例YAML文件(Python)

      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
          spec:
            containers:
              - image: registry.cn-hangzhou.aliyuncs.com/private-mesh/arms-python-demo: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
          spec:
            containers:
              - env:
                - name: CLIENT_URL
                  value: 'http://arms-python-client-svc:8000'
              - image: registry.cn-hangzhou.aliyuncs.com/private-mesh/arms-python-demo: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
      

      其中,arms-python-serverarms-python-client的应用代码分别为:

      arms-python-client

      from fastapi import FastAPI
      from langchain.llms.fake import FakeListLLM
      import uvicorn
      from langchain.chains import LLMChain
      from langchain.prompts import PromptTemplate
      
      app = FastAPI()
      llm = FakeListLLM(responses=["I'll callback later.", "You 'console' them!"])
      
      template = """Question: {question}
      
      Answer: Let's think step by step."""
      
      prompt = PromptTemplate(template=template, input_variables=["question"])
      
      llm_chain = LLMChain(prompt=prompt, llm=llm)
      
      question = "What NFL team won the Super Bowl in the year Justin Beiber was born?"
      
      @app.get("/")
      def call_langchain():
          res = llm_chain.run(question)
          return {"data": res}
      
      if __name__ == "__main__":
          uvicorn.run(app, host="0.0.0.0", port=8000)

      arms-python-server

      import uvicorn
      from fastapi import FastAPI, HTTPException
      from logging import getLogger
      _logger = getLogger(__name__)
      import requests
      import os
      app = FastAPI()
      
      def call_client():
          url = 'https://www.aliyun.com'  # 替换为你的实际地址
          call_url = os.environ.get("CLIENT_URL")
          if call_url is None or call_url == "":
              call_url = url
          response = requests.get(call_url)
          print(f"response code: {response.status_code} - {response.text}")
          return response.text
      
      @app.get("/")
      async def call():
          call_client()
          return {"data": f"call"}
      
      
      if __name__ == "__main__":
          uvicorn.run(app, host="0.0.0.0", port=8000)
      
  • ARMS:

    已开通应用监控计费版本。

    应用监控每月提供50 GB的免费额度,当月未使用完的试用额度不会结转至次月,当月超出免费额度的部分,按照写入的数据量进行收费。收费详情,请参见计费说明

为应用安装探针

1. 安装ack-onepilot组件

  1. 容器服务管理控制台集群列表页面单击目标集群名称。

  2. 在左侧导航栏选择运维管理 > 组件管理,然后在右侧页面通过关键字搜索ack-onepilot

  3. ack-onepilot卡片上单击安装,然后在弹出的对话框单击确定

    说明

    确保ack-onepilot版本在3.2.4及以上。

    image

2. 更新Dockerfile

  1. PyPI仓库下载探针安装器。

    pip3 install aliyun-bootstrap
  2. 使用aliyun-bootstrap安装探针。

    aliyun-bootstrap -a install
  3. 通过ARMS Python探针启动应用。

    aliyun-instrument python app.py
  4. 构建镜像。

完整的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"]

3. 更新YAML

  1. 工作负载 > 无状态页面选择应用所在的命名空间,然后在目标应用右侧选择更多 > 查看Yaml

    image

  2. 编辑YAML中将以下labels添加到spec.template.metadata层级下,然后单击更新

    labels:
      aliyun.com/app-language: python # Python应用必填,标明此应用是Python应用。
      armsPilotAutoEnable: 'on'
      armsPilotCreateAppName: "<your-deployment-name>"    #应用在ARMS中的展示名称。

    例如,在arms-python-clientarms-python-server应用的YAML中添加配置,开启监控并配置在ARMS中的展示名称分别为arms-python-clientarms-python-server

    arms-python-client应用

    image

    arms-python-server应用

    image

  3. 待容器完成自动重新部署后,等待1~2分钟,在ARMS控制台应用监控 > 应用列表页面单击应用名称,查看应用的监控指标。更多信息,请参见查看监控详情(新版)

    2024-09-25_10-36-51

查看监控详情

调用链分析

  • 微服务场景:

    调用链分析功能可以通过自由组合筛选条件与聚合维度进行实时分析,并支持通过错/慢Trace分析功能,定位系统或应用产生错、慢调用的原因。

    image

    调用链详情:

    image

  • 大模型场景

    针对大模型场景,您可以查看LLM领域的新版TraceView,更直观地分析不同操作类型的输入输出、Token消耗等信息。

    切换为大模型视图:

    image

    大模型调用信息:

    image

监控指标

  • 应用概览

    image

  • 应用拓扑

    image

配置告警

通过配置告警,您可以制定针对特定应用的告警规则。当告警规则被触发时,系统会以您指定的通知方式向告警联系人或钉群发送告警信息,以提醒您采取必要的解决措施。具体操作,请参见应用监控告警规则

image

释放资源

完成教程后:

  • 如果仍需要继续监控当前应用,请确保账户不要欠费。

  • 如果无需继续监控当前应用,请卸载探针。具体操作,请参见卸载Python探针

相关文档

  • ARMS应用监控支持在应用的业务日志中关联调用链的TraceId信息,从而在应用出现问题时,能够通过调用链的TraceId快速关联到业务日志,及时定位、分析并解决问题。更多信息,请参见业务日志关联调用链的TraceId信息

  • 阿里云可观测监控 Prometheus 版默认集成了ARMS应用监控数据源,您可以直接在可观测监控 Prometheus 版下获取应用监控相关数据、查看应用监控预置大盘,并根据需求进行二次开发。更多信息,请参见通过Prometheus监控获取ARMS应用监控数据