kube-prometheus AlertmanagerConfig 与 Alertmanager 关系详解

内容分享1小时前发布
0 0 0

1. 概述

在 Kubernetes 环境中,Prometheus Operator 提供了一种声明式的方式来管理 Prometheus 监控栈。根据 Prometheus Operator 官方文档,AlertmanagerAlertmanagerConfig 都是由 Operator 管理的核心自定义资源定义(CRD),它们共同构成了 Kubernetes 环境中的告警管理系统。

2. Alertmanager 与 AlertmanagerConfig 的关系

根据 Prometheus Operator 官方文档,Alertmanager 和 AlertmanagerConfig 的关系可以总结为:

  • Alertmanager:定义期望的 Alertmanager 部署。作为 Prometheus Operator 的 CRD 之一,它负责实际执行告警处理逻辑,负责接收、分组、抑制和发送告警,是整个告警系统的核心组件。
  • AlertmanagerConfig:声明式地指定 Alertmanager 配置的子部分。它允许用户配置告警路由到自定义接收器,以及设置抑制规则等。
  • 工作机制:Prometheus Operator 作为核心控制器,自动监控 Kubernetes API 服务器中这两种 CRD 对象的变化,确保相关的部署和配置保持同步。
  • 关注点分离:Alertmanager 专注于部署层面,定义了 Alertmanager 实例如何运行;而 AlertmanagerConfig 专注于配置层面,定义了 Alertmanager 如何处理和路由告警。

2.2 工作流程

下图展示了 AlertmanagerConfig 和 Alertmanager 的完整工作流程:

工作流程详细说明:

  1. 用户创建或修改 AlertmanagerConfig 资源
  2. Prometheus Operator 监听到资源变化
  3. Operator 将 AlertmanagerConfig 转换为 Alertmanager 配置格式
  4. Alertmanager 加载并应用新配置
  5. 告警按照新配置的规则进行处理和发送

Alertmanager 工作流程

kube-prometheus AlertmanagerConfig 与 Alertmanager 关系详解

AlterMangerConfig

kind: AlertmanagerConfig
metadata:
  labels:
    alertmanager: main
  name: info-alert-webhook
  namespace: monitoring
spec:
  receivers:
  - name: info-http-receiver
    webhookConfigs:
    - sendResolved: true
      url: http://nginx:80
  route:
    groupBy:
    - alertname
    - instance
    groupInterval: 10s
    groupWait: 10s
    receiver: info-http-receiver
    repeatInterval: 10s
    routes:
    - continue: false
      matchers:
      - matchType: =
        name: severity
        value: critical
      receiver: info-http-receiver

每个字段的解释如下:

# AlertmanagerConfig 资源定义开始
# 资源类型,指定这是一个 AlertmanagerConfig 资源
kind: AlertmanagerConfig

# metadata 部分包含资源的元数据信息
metadata:
  # labels 用于标识和选择资源,这里指定 alertmanager: main 标签
  # Prometheus Operator 使用此标签将配置绑定到相应的 Alertmanager 实例
  labels:
    alertmanager: main
  # 资源名称,在命名空间内唯一
  name: info-alert-webhook
  # 命名空间,此配置将仅适用于该命名空间内的告警
  namespace: monitoring

# spec 部分包含实际的 Alertmanager 配置内容
spec:
  # receivers 定义告警接收器列表
  receivers:
  - # 接收器名称,在 route 配置中引用
    name: info-http-receiver
    # webhookConfigs 定义 Webhook 类型的通知配置
    webhookConfigs:
    - # sendResolved 表明是否在告警解决时发送通知
      sendResolved: true
      # url 指定 Webhook 接收地址,告警将被发送到此处
      url: http://nginx:80

  # route 定义告警路由规则
  route:
    # groupBy 指定按哪些标签对告警进行分组
    # 一样标签的告警将被合并为一组发送
    groupBy:
    - alertname  # 按告警名称分组
    - instance   # 按实例分组
    # groupInterval 指定发送同一组内新告警的等待时间
    groupInterval: 10s
    # groupWait 指定初始告警分组的等待时间,用于收集相关告警
    groupWait: 10s
    # receiver 指定默认接收器名称
    receiver: info-http-receiver
    # repeatInterval 指定重复发送一样告警的间隔时间
    repeatInterval: 10s
    # routes 定义子路由规则,用于更精细的告警路由
    routes:
    - # continue 表明匹配此路由后是否继续评估后续路由
      # false 表明匹配后不再继续
      continue: false
      # matchers 定义告警匹配条件
      matchers:
      - # matchType 定义匹配类型,"=" 表明完全匹配
        matchType: =
        # name 指定要匹配的标签名称
        name: severity
        # value 指定要匹配的标签值
        value: critical
      # 匹配条件满足时使用的接收器
      receiver: info-http-receiver

AlertManager

类似Service通过labelSelector来选择Pod,AlertManager也可以通过
alertmanagerConfigSelector来选择AlertmanagerConfig资源。

以下是AlertManager选择alertmanager: main选择上面的info-alert-webhook作为告警配置。

apiVersion: monitoring.coreos.com/v1
kind: Alertmanager
metadata:
  labels:
    app.kubernetes.io/component: alert-router
    app.kubernetes.io/instance: main
    app.kubernetes.io/name: alertmanager
    app.kubernetes.io/part-of: kube-prometheus
    app.kubernetes.io/version: 0.26.0
  name: main
  namespace: monitoring
spec:
  # alertmanagerConfigSelector 用于选择关联的 AlertmanagerConfig 资源
  # matchLabels 定义了选择器的标签匹配规则
  # 这里指定 alertmanager: main 标签,与 AlertmanagerConfig 资源的 labels 匹配
  alertmanagerConfigSelector:
    matchLabels:
      alertmanager: main
  # ... 

Alertmanager 完整定义及注释解析

# API 版本声明
apiVersion: monitoring.coreos.com/v1  # Alertmanager CRD 的 API 版本

# 资源类型
kind: Alertmanager                    # 声明这是一个 Alertmanager 类型的资源

# 元数据信息
metadata:
  # 资源标签,遵循 Kubernetes 推荐的标签约定
  labels:
    app.kubernetes.io/component: alert-router  # 组件类型:告警路由器
    app.kubernetes.io/instance: main           # 实例名称:main
    app.kubernetes.io/name: alertmanager       # 应用名称:alertmanager
    app.kubernetes.io/part-of: kube-prometheus  # 所属项目:kube-prometheus
    app.kubernetes.io/version: 0.26.0          # 应用版本:0.26.0
  name: main                        # Alertmanager 实例名称
  namespace: monitoring             # 部署在 monitoring 命名空间

# 规格配置(核心配置部分)
spec:
  # AlertmanagerConfig 选择器
  # 用于选择与此 Alertmanager 关联的 AlertmanagerConfig 资源
  alertmanagerConfigSelector:
    matchLabels:
      alertmanager: main           # 仅匹配标签为 alertmanager=main 的 AlertmanagerConfig
  
  # 容器镜像配置
  image: 'quay.io/prometheus/alertmanager:v0.26.0'  # Alertmanager 容器镜像
  
  # 节点选择器
  # 控制 Pod 调度到哪些节点上
  nodeSelector:
    kubernetes.io/os: linux        # 仅调度到 Linux 节点
  
  # Pod 元数据
  # 这些标签会被应用到创建的 Alertmanager Pod 上
  podMetadata:
    labels:
      app.kubernetes.io/component: alert-router  # 组件标签
      app.kubernetes.io/instance: main           # 实例标签
      app.kubernetes.io/name: alertmanager       # 应用名称标签
      app.kubernetes.io/part-of: kube-prometheus  # 所属项目标签
      app.kubernetes.io/version: 0.26.0          # 版本标签
  
  # 端口名称
  # 指定 Alertmanager 容器暴露的端口名称
  portName: web                    # Web 服务端口名称
  
  # 副本数量
  # 控制部署的 Alertmanager 实例数量
  replicas: 1                      # 单副本部署(生产环境提议 2-3 副本以实现高可用)
  
  # 资源限制和请求
  # 控制 Pod 的资源使用
  resources:
    limits:
      cpu: 100m                    # CPU 上限:100 毫核
      memory: 100Mi                # 内存上限:100 MiB
    requests:
      cpu: 4m                      # CPU 请求:4 毫核
      memory: 100Mi                # 内存请求:100 MiB
  
  # 数据保留时间
  # 控制 Alertmanager 保存告警数据的时间
  retention: 120h                  # 数据保留 120 小时(5 天)
  
  # 安全上下文
  # 定义 Pod 和容器的安全配置
  securityContext:
    fsGroup: 2000                  # 文件系统组 ID
    runAsNonRoot: true             # 以非 root 用户运行
    runAsUser: 1000                # 运行用户 ID
  
  # 服务账号
  # 指定用于运行 Pod 的服务账号
  serviceAccountName: alertmanager-main  # 服务账号名称
  
  # Alertmanager 版本
  # 指定使用的 Alertmanager 版本
  version: 0.26.0                  # Alertmanager 版本号

附录

AlertmanagerConfig 完整定义

# AlertmanagerConfig CRD 完整定义
# 参考:https://prometheus-operator.dev/docs/api-reference/api/#monitoring.coreos.com/v1alpha1.AlertmanagerConfig

apiVersion: monitoring.coreos.com/v1alpha1  # API 版本,当前为 v1alpha1
kind: AlertmanagerConfig                     # 资源类型
metadata:
  name: example-config                       # 配置名称
  namespace: monitoring                      # 命名空间
  labels:
    alertmanager: main                       # 用于匹配 Alertmanager 的标签

# spec 包含 Alertmanager 配置的核心部分
spec:
  # route 定义告警路由树的根节点
  # 所有传入的告警都将从这个根路由开始匹配
  route:
    # groupBy 定义告警分组的标签
    # 具有一样指定标签的告警将被分组在一起
    groupBy: ['job', 'alertname']
    
    # groupWait 是等待同组新告警到达的时间
    # 在此期间收集同一组的告警,然后一起发送
    groupWait: 30s
    
    # groupInterval 是发送同一组内已分组告警的时间间隔
    groupInterval: 5m
    
    # repeatInterval 是重复发送已解决告警的时间间隔
    repeatInterval: 4h
    
    # receiver 是默认接收者的名称
    # 如果告警没有匹配到任何子路由,将发送到此接收者
    receiver: 'info-alert-webhook'
    
    # continue 控制告警匹配后续路由的行为
    # 如果为 true,告警匹配到当前路由后会继续评估后续路由
    continue: false
    
    # routes 定义子路由列表
    # 子路由按照定义的顺序评估
    routes:
    - # match 定义准确匹配条件
      # 告警必须包含所有指定的标签和值
      match:
        severity: critical
      # receiver 是此路由的接收者名称
      receiver: 'critical-alert-webhook'
      # groupWait 覆盖父路由的设置
      groupWait: 10s
      # 子路由可以继续嵌套子路由
      routes:
      - match:
          component: database
        receiver: 'database-team-webhook'
        continue: true  # 允许告警继续匹配其他路由
    
    # matchers 定义更复杂的匹配条件
    # 支持 !=、=~、!~ 等操作符
    matchers:
    - name: severity
      value: warning
      matchType: '='
    - name: env
      value: production
      matchType: '='
    - name: app
      value: '^(api|frontend)$'
      matchType: '=~'

  # receivers 定义告警接收者列表
  # 每个接收者有一个唯一名称和一组通知配置
  receivers:
  - name: 'info-alert-webhook'  # 接收者名称
    # webhookConfigs 定义 Webhook 通知配置
    webhookConfigs:
    - url: 'http://webhook-service:8080/info'
      # sendResolved 是否在告警解决时发送通知
      sendResolved: true
      # httpConfig 定义 HTTP 请求配置
      httpConfig:
        # basicAuth 配置基本认证
        basicAuth:
          username:
            name: webhook-credentials  # Secret 名称
            key: username              # Secret 中的键
          password:
            name: webhook-credentials
            key: password
        # 支持 tlsConfig、bearerToken 等其他 HTTP 配置
    
    # emailConfigs 定义邮件通知配置
    emailConfigs:
    - to: 'alerts@example.com'
      from: 'alertmanager@example.com'
      smarthost: 'smtp.example.com:587'
      authUsername:
        name: email-credentials
        key: username
      authPassword:
        name: email-credentials
        key: password
      requireTLS: true
    
    # slackConfigs 定义 Slack 通知配置
    slackConfigs:
    - apiURL:
        name: slack-credentials
        key: apiURL
      channel: '#alerts'
      sendResolved: true
      title: '{{ .GroupLabels.alertname }}'
      text: '{{ template "slack.default.text" . }}'

  # inhibitRules 定义抑制规则列表
  # 抑制规则用于防止当高级别告警触发时发送相关的低级别告警
  inhibitRules:
  - # sourceMatch 定义源告警的匹配条件
    sourceMatch:
      severity: 'critical'
    # targetMatch 定义目标告警的匹配条件
    targetMatch:
      severity: 'warning'
    # equal 定义源告警和目标告警必须相等的标签列表
    equal: ['alertname', 'job', 'instance']
  - sourceMatchers:
    - name: severity
      value: 'critical'
      matchType: '='
    targetMatchers:
    - name: severity
      value: 'info'
      matchType: '='
    equal: ['app', 'env']

  # muteTimeIntervals 引用 MuteTimeInterval 资源
  # 用于在特定时间区间内抑制告警
  muteTimeIntervals:
  - name: 'weekends'
  - name: 'maintenance-window'

  # timeIntervals 定义时间区间(内联方式)
  # 注意:此功能可能需要特定版本的支持
  timeIntervals:
  - name: 'business-hours'
    timeIntervals:
    - start: '09:00'
      end: '18:00'
      daysOfWeek:
      - 'monday'
      - 'tuesday'
      - 'wednesday'
      - 'thursday'
      - 'friday'

Alertmanager CRD 完整定义

# Alertmanager CRD 完整定义
# 参考:https://prometheus-operator.dev/docs/api-reference/api/#monitoring.coreos.com/v1.Alertmanager

apiVersion: monitoring.coreos.com/v1  # API 版本
kind: Alertmanager                    # 资源类型
metadata:
  name: example-alertmanager         # Alertmanager 实例名称
  namespace: monitoring              # 部署命名空间
  labels:
    app: prometheus-operator         # 可选标签,用于选择器匹配

spec:
  # podMetadata 定义了传播到 Alertmanager Pod 的标签和注释
  # 以下项目是保留的,不能被覆盖:
  # - "alertmanager" 标签,设置为 Alertmanager 实例的名称
  # - "app.kubernetes.io/instance" 标签,设置为 Alertmanager 实例的名称
  # - "app.kubernetes.io/managed-by" 标签,设置为 "prometheus-operator"
  # - "app.kubernetes.io/name" 标签,设置为 "alertmanager"
  # - "app.kubernetes.io/version" 标签,设置为 Alertmanager 版本
  # - "kubectl.kubernetes.io/default-container" 注释,设置为 "alertmanager"
  podMetadata:
    annotations:
      prometheus.io/scrape: "true"   # 示例自定义注释
    labels:
      custom-label: "value"          # 示例自定义标签

  # image 如果指定,优先于 baseImage、tag 和 sha 的组合
  # 即使指定了 image,仍需指定 version 以确保 Prometheus Operator 知道正在配置的 Alertmanager 版本
  image: "quay.io/prometheus/alertmanager:v0.25.0"  # 完整镜像路径

  # imagePullPolicy 定义了 'alertmanager'、'init-config-reloader' 和 'config-reloader' 容器的镜像拉取策略
  # 请参阅 https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy 了解更多详情
  imagePullPolicy: IfNotPresent      # 镜像拉取策略(Always、IfNotPresent、Never)

  # version 指定集群应使用的版本
  version: "v0.25.0"                 # Alertmanager 版本

  # tag 指定要部署的 Alertmanager 容器镜像的标签
  # 如果设置了 Tag,则忽略 Version
  # 已弃用:请改用 'image'。镜像标签可以作为 image URL 的一部分指定
  # tag: "v0.25.0"

  # sha 指定要部署的 Alertmanager 容器镜像的 SHA
  # 类似于标签,但 SHA 明确部署了不可变的容器镜像
  # 如果设置了 SHA,则忽略 Version 和 Tag
  # 已弃用:请改用 'image'。镜像摘要可以作为 image URL 的一部分指定
  # sha: "sha256:..."

  # baseImage 用于部署 Pod 的基础镜像,不带标签
  # 已弃用:请改用 'image'
  # baseImage: "quay.io/prometheus/alertmanager"

  # imagePullSecrets 是对同一命名空间中用于从注册表拉取 prometheus 和 alertmanager 镜像的密钥的可选引用列表
  # 请参阅 https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
  imagePullSecrets:
  - name: private-registry-secret     # 私有镜像仓库密钥名称

  # replicas 指定 Alertmanager 实例的数量
  # 当配置了两个或更多副本时,Operator 以高可用模式运行 Alertmanager 实例
  replicas: 3                         # 副本数量,提议生产环境设置为 2 或更多以实现高可用

  # baseImage 指定用于部署 Pod 的基础镜像,不带标签
  # 已弃用:请改用 'image'
  # baseImage: "quay.io/prometheus/alertmanager"

  # secrets 是与 Alertmanager 对象位于同一命名空间中的 Secrets 列表,它们将被挂载到 Alertmanager Pods 中
  # 每个 Secret 都作为名为 secret-<secret-name> 的卷添加到 StatefulSet 定义中
  # 这些 Secrets 被挂载到 'alertmanager' 容器的 /etc/alertmanager/secrets/<secret-name> 目录中
  secrets:
  - alertmanager-tls                  # TLS 证书密钥
  - alertmanager-webhook-credentials  # Webhook 凭据密钥

  # configMaps 定义了与 Alertmanager 对象位于同一命名空间中的 ConfigMaps 列表,它们将被挂载到 Alertmanager Pods 中
  # 每个 ConfigMap 都作为名为 configmap-<configmap-name> 的卷添加到 StatefulSet 定义中
  # 这些 ConfigMaps 被挂载到 'alertmanager' 容器的 /etc/alertmanager/configmaps/<configmap-name> 目录中
  configMaps:
  - alertmanager-templates            # 告警通知模板

  # configSecret 定义了与 Alertmanager 对象位于同一命名空间中的 Kubernetes Secret 的名称,其中包含此 Alertmanager 实例的配置
  # 如果为空,默认为 alertmanager-<alertmanager-name>
  # Alertmanager 配置应在 alertmanager.yaml 密钥下可用
  # 原始密钥中的其他密钥会被复制到生成的密钥中,并挂载到 alertmanager 容器的 /etc/alertmanager/config 目录中
  # 如果缺少密钥或 alertmanager.yaml 密钥,operator 会提供一个最小配置
  # 注意:使用 AlertmanagerConfig 资源时,一般不需要手动配置此 Secret
  # configSecret: "alertmanager-example-alertmanager"

  # storage 定义 Alertmanager 实例的持久存储配置
  storage:
    volumeClaimTemplate:
      spec:
        storageClassName: "standard"   # 存储类名称
        resources:
          requests:
            storage: 10Gi              # 请求的存储大小

  # nodeSelector 定义了用于选择节点的标签选择器
  # 只有具有匹配标签的节点才会被思考用于调度 Alertmanager Pods
  nodeSelector:
    kubernetes.io/os: linux           # 仅在 Linux 节点上运行

  # tolerations 定义了 Pod 可以容忍的污点列表
  # 允许 Pod 被调度到具有匹配污点的节点上
  tolerations:
  - key: "monitoring"                 # 污点键
    operator: "Equal"                 # 操作符
    value: "true"                     # 污点值
    effect: "NoSchedule"              # 污点效果

  # affinity 定义了 Pod 的亲和性和反亲和性规则
  # 用于控制 Pod 在集群中的分布
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - alertmanager
          topologyKey: kubernetes.io/hostname

  # serviceAccountName 指定用于运行 Alertmanager Pods 的 ServiceAccount 的名称
  # 如果为空,默认为 alertmanager-<alertmanager-name>
  serviceAccountName: "alertmanager"   # 服务账号名称

  # resources 定义了 Alertmanager Pods 的资源请求和限制
  resources:
    requests:
      memory: "256Mi"                 # 内存请求
      cpu: "100m"                     # CPU 请求
    limits:
      memory: "1Gi"                   # 内存限制
      cpu: "500m"                     # CPU 限制

  # retention 定义了 Alertmanager 应保留数据的时间
  retention: "120h"                   # 数据保留时间

  # serviceMonitorSelector 定义了选择 ServiceMonitor 资源的标签选择器
  # 这些 ServiceMonitor 将用于监控 Alertmanager 实例
  # 已弃用:请改用 PodMonitor
  # serviceMonitorSelector:
  #   matchLabels:
  #     app: alertmanager

  # serviceMonitorNamespaceSelector 定义了选择 ServiceMonitor 资源所在命名空间的标签选择器
  # 已弃用:请改用 PodMonitor
  # serviceMonitorNamespaceSelector: {}

  # podMonitorSelector 定义了选择 PodMonitor 资源的标签选择器
  # 这些 PodMonitor 将用于监控 Alertmanager 实例
  podMonitorSelector:
    matchLabels:
      app: alertmanager

  # podMonitorNamespaceSelector 定义了选择 PodMonitor 资源所在命名空间的标签选择器
  podMonitorNamespaceSelector: {}

  # alertmanagerConfigSelector 定义了选择 AlertmanagerConfig 资源的标签选择器
  # 这些 AlertmanagerConfig 将与部署的 Alertmanager 实例相关联
  alertmanagerConfigSelector:
    matchLabels:
      alertmanager: example-alertmanager

  # alertmanagerConfigNamespaceSelector 定义了选择 AlertmanagerConfig 资源所在命名空间的标签选择器
  # 如果为空,将仅思考 Alertmanager 实例所在命名空间中的 AlertmanagerConfig
  # 如果设置为空对象 {},将思考所有命名空间中的 AlertmanagerConfig
  alertmanagerConfigNamespaceSelector: {}

  # externalUrl 定义了用于访问 Alertmanager 实例的外部 URL
  # 这会影响生成的告警通知中的链接
  externalUrl: "https://alertmanager.example.com"  # 外部访问 URL

  # routePrefix 定义了 Alertmanager Web UI 的路由前缀
  routePrefix: "/"                    # 路由前缀

  # listenLocal 启用本地监听(127.0.0.1)而非绑定到所有接口
  listenLocal: false                  # 是否仅本地监听

  # portName 定义了 Alertmanager 容器暴露的端口名称
  portName: "web"                    # 端口名称

  # priorityClassName 定义了 Alertmanager Pod 的优先级类名称
  priorityClassName: "high-priority"  # 优先级类名称

  # securityContext 定义了 Pod 的安全上下文
  securityContext:
    fsGroup: 2000                     # 文件系统组 ID
    runAsNonRoot: true                # 以非 root 用户运行
    runAsUser: 1000                   # 用户 ID

  # containers 允许添加额外的容器到 Alertmanager Pods 中
  # 或者覆盖 operator 提供的默认容器的某些字段
  containers:
  - name: alertmanager                # 容器名称
    args:                             # 容器参数
    - "--storage.tsdb.path=/alertmanager"  # 存储路径
    - "--storage.tsdb.retention.time=120h"  # 数据保留时间
    - "--config.file=/etc/alertmanager/config/alertmanager.yaml"  # 配置文件路径

  # initContainers 允许添加初始化容器到 Alertmanager Pods 中
  initContainers:
  - name: init-templates              # 初始化容器名称
    image: busybox:latest             # 初始化容器镜像
    command: ["sh", "-c", "cp -r /templates/* /etc/alertmanager/templates/"]  # 命令
    volumeMounts:
    - name: configmap-alertmanager-templates  # 卷名称
      mountPath: /templates                   # 挂载路径
    - name: alertmanager-config               # 卷名称
      mountPath: /etc/alertmanager/templates/ # 挂载路径

# 注意事项:
# 1. 当创建 Alertmanager 资源时,Prometheus Operator 会在同一命名空间中部署一个 StatefulSet
# 2. 当配置两个或更多副本时,Operator 会以高可用模式运行 Alertmanager 实例
# 3. 资源通过标签和命名空间选择器定义应该与部署的 Alertmanager 实例关联的 AlertmanagerConfig 对象
# 4. 对于生产环境,提议配置持久存储和适当的资源限制
# 5. 可以通过 alertmanagerConfigSelector 和 alertmanagerConfigNamespaceSelector 控制哪些命名空间的 AlertmanagerConfig 可以被应用
© 版权声明

相关文章

暂无评论

none
暂无评论...