为 Azure API 管理自承载网关配置本地指标和日志

可用性

重要

此功能在 API 管理的“高级”和“开发人员”层中可用。

本文详细介绍如何为 Kubernetes 群集上部署的自承载网关配置本地指标和日志。 若要配置云指标和日志,请参阅本文

指标

自承载网关支持 StatsD,它已成为指标收集和聚合的统一协议。 本部分介绍将 StatsD 部署到 Kubernetes 的完整步骤,包含配置网关以通过 StatsD 发出指标,以及使用 Prometheus 监视指标。

将 StatsD 和 Prometheus 部署到群集

下面的示例 YAML 配置用于将 StatsD 和 Prometheus 部署到已部署了自承载网关的 Kubernetes 群集。 它还会为每个群集创建一个服务。 然后,自承载网关将指标发布到 StatsD 服务。 我们将通过 Prometheus 的服务访问其仪表板。

注意

以下示例从 Docker Hub 拉取公共容器映像。 建议设置一个拉取密钥,以使用 Docker Hub 帐户进行身份验证,而不是发出匿名拉取请求。 若要在使用公共内容时提高可靠性,请在专用 Azure 容器注册表中导入和管理映像。 详细了解如何使用公共映像

apiVersion: v1
kind: ConfigMap
metadata:
  name: sputnik-metrics-config
data:
  statsd.yaml: ""
  prometheus.yaml: |
    global:
      scrape_interval:     3s
      evaluation_interval: 3s
    scrape_configs:
      - job_name: 'prometheus'
        static_configs:
          - targets: ['localhost:9090']
      - job_name: 'test_metrics'
        static_configs:
          - targets: ['localhost:9102']
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sputnik-metrics
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sputnik-metrics
  template:
    metadata:
      labels:
        app: sputnik-metrics
    spec:
      containers:
      - name: sputnik-metrics-statsd
        image: prom/statsd-exporter
        ports:
        - name: tcp
          containerPort: 9102
        - name: udp
          containerPort: 8125
          protocol: UDP
        args:
          - --statsd.mapping-config=/tmp/statsd.yaml
          - --statsd.listen-udp=:8125
          - --web.listen-address=:9102
        volumeMounts:
          - mountPath: /tmp
            name: sputnik-metrics-config-files
      - name: sputnik-metrics-prometheus
        image: prom/prometheus
        ports:
        - name: tcp
          containerPort: 9090
        args:
          - --config.file=/tmp/prometheus.yaml
        volumeMounts:
          - mountPath: /tmp
            name: sputnik-metrics-config-files
      volumes:
        - name: sputnik-metrics-config-files
          configMap:
            name: sputnik-metrics-config
---
apiVersion: v1
kind: Service
metadata:
  name: sputnik-metrics-statsd
spec:
  type: NodePort
  ports:
  - name: udp
    port: 8125
    targetPort: 8125
    protocol: UDP
  selector:
    app: sputnik-metrics
---
apiVersion: v1
kind: Service
metadata:
  name: sputnik-metrics-prometheus
spec:
  type: LoadBalancer
  ports:
  - name: http
    port: 9090
    targetPort: 9090
  selector:
    app: sputnik-metrics

将配置保存到名为 metrics.yaml 的文件。 使用以下命令将所有项部署到群集:

kubectl apply -f metrics.yaml

部署完成后,运行以下命令来检查 Pod 是否正在运行。 Pod 名称将有所不同。

kubectl get pods
NAME                                   READY   STATUS    RESTARTS   AGE
sputnik-metrics-f6d97548f-4xnb7        2/2     Running   0          1m

运行以下命令来检查 services 是否正在运行。 记下 StatsD 服务的 CLUSTER-IPPORT,稍后需要使用它们。 可以使用 Prometheus 的 EXTERNAL-IPPORT 访问其仪表板。

kubectl get services
NAME                         TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)                      AGE
sputnik-metrics-prometheus   LoadBalancer   10.0.252.72   13.89.141.90    9090:32663/TCP               18h
sputnik-metrics-statsd       NodePort       10.0.41.179   <none>          8125:32733/UDP               18h

配置自承载网关以发出指标

部署了 StatsD 和 Prometheus 后,便可以更新自承载网关的配置,以开始通过 StatsD 发出指标。 可以通过其他选项使用自承载网关部署的 ConfigMap 中的 telemetry.metrics.local 密钥来启用或禁用此功能。 下面是可用的选项:

字段 默认 说明
telemetry.metrics.local none 通过 StatsD 启用日志记录。 值可以是 nonestatsd
telemetry.metrics.local.statsd.endpoint 不适用 指定 StatsD 终结点。
telemetry.metrics.local.statsd.sampling 不适用 指定指标采样率。 值可以介于 0 和 1。 示例: 0.5
telemetry.metrics.local.statsd.tag-format 不适用 StatsD 导出程序标记格式。 值可以是 nonelibratodogStatsDinfluxDB

下面是一个示例配置:

apiVersion: v1
kind: ConfigMap
metadata:
    name: contoso-gateway-environment
data:
    config.service.endpoint: "<self-hosted-gateway-management-endpoint>"
    telemetry.metrics.local: "statsd"
    telemetry.metrics.local.statsd.endpoint: "10.0.41.179:8125"
    telemetry.metrics.local.statsd.sampling: "1"
    telemetry.metrics.local.statsd.tag-format: "dogStatsD"

通过上述配置更新自承载网关部署的 YAML 文件,并使用以下命令应用更改:

kubectl apply -f <file-name>.yaml

若要选取最新的配置更改,请使用以下命令重启网关部署:

kubectl rollout restart deployment/<deployment-name>

查看指标

现在,我们已部署并配置了所有内容,自承载网关应通过 StatsD 报告指标。 然后,Prometheus 从 StatsD 中选取指标。 使用 Prometheus 服务的 EXTERNAL-IPPORT 转到 Prometheus 仪表板。

通过自承载网关进行一些 API 调用,如果所有内容都已正确配置,则应该能够查看以下指标:

指标 说明
requests_total 期间内的 API 请求数
request_duration_seconds 从网关收到请求到响应全部发送出去经过的时间(毫秒)
request_backend_duration_seconds 花在整个后端 IO(连接、发送和接收字节)上的时间(毫秒)
request_client_duration_seconds 花在整个客户端 IO(连接、发送和接收字节)上的时间(毫秒)

日志

默认情况下,自承载网关会将日志输出到 stdoutstderr。 可以使用以下命令轻松查看日志:

kubectl logs <pod-name>

如果自承载网关部署在 Azure Kubernetes 服务中,则可以启用适用于容器的 Azure Monitor,以便从工作负载收集 stdoutstderr 并查看 Log Analytics 中的日志。

自承载网关还支持许多协议,包括 localsyslogrfc5424journal。 下表汇总了所有支持的选项。

字段 默认 说明
telemetry.logs.std text 启用到标准流的日志记录。 值可以是 nonetextjson
telemetry.logs.local auto 启用本地日志记录。 值可以是 noneautolocalsyslogrfc5424journaljson
telemetry.logs.local.localsyslog.endpoint 不适用 指定本地 syslog 终结点。 有关详细信息,请参阅使用本地 syslog 日志
telemetry.logs.local.localsyslog.facility 不适用 指定 localsyslog 设备代码。 例如,7
telemetry.logs.local.rfc5424.endpoint 不适用 指定 rfc5424 终结点。
telemetry.logs.local.rfc5424.facility 不适用 指定每个 rfc5424 的设备代码。 示例: 7
telemetry.logs.local.journal.endpoint 不适用 指定日志终结点。
telemetry.logs.local.json.endpoint 127.0.0.1:8888 指定接受 JSON 数据的 UDP 终结点:文件路径、IP:端口或主机名:端口。

下面是本地日志记录的示例配置:

    apiVersion: v1
    kind: ConfigMap
    metadata:
        name: contoso-gateway-environment
    data:
        config.service.endpoint: "<self-hosted-gateway-management-endpoint>"
        telemetry.logs.std: "text"
        telemetry.logs.local.localsyslog.endpoint: "/dev/log"
        telemetry.logs.local.localsyslog.facility: "7"

使用本地 JSON 终结点

已知限制

  • 对于本地诊断,我们最多只支持 3072 字节的请求/响应有效负载。 超过此限制可能会因分块而破坏 JSON 格式。

使用本地 syslog 日志

配置网关以流式传输日志

将本地 syslog 用作日志的目标时,运行时需要允许将日志流式传输到目标。 对于 Kubernetes,需要装载与目标匹配的卷。

假设使用以下配置:

apiVersion: v1
kind: ConfigMap
metadata:
    name: contoso-gateway-environment
data:
    config.service.endpoint: "<self-hosted-gateway-management-endpoint>"
    telemetry.logs.local: localsyslog
    telemetry.logs.local.localsyslog.endpoint: /dev/log

可以轻松地开始将日志流式传输到该本地 syslog 终结点:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: contoso-deployment
  labels:
    app: contoso
spec:
  replicas: 1
  selector:
    matchLabels:
      app: contoso
  template:
    metadata:
      labels:
        app: contoso
    spec:
      containers:
        name: azure-api-management-gateway
        image: mcr.microsoft.com/azure-api-management/gateway:2.5.0
        imagePullPolicy: IfNotPresent
        envFrom:
        - configMapRef:
            name: contoso-gateway-environment
        # ... redacted ...
+       volumeMounts:
+       - mountPath: /dev/log
+         name: logs
+     volumes:
+     - hostPath:
+         path: /dev/log
+         type: Socket
+       name: logs

在 Azure Kubernetes 服务 (AKS) 上使用本地 syslog 日志

当配置为在 Azure Kubernetes 服务上使用本地 syslog 时,可以选择两种方法来浏览日志:

  • 连接和浏览工作器节点上的日志

从工作器节点使用日志

可以通过获取对工作器节点的访问权限来轻松使用它们:

  1. 创建与节点的 SSH 连接(文档
  2. 可在 host/var/log/syslog 下找到日志

例如,可以将所有 syslog 筛选为仅保留来自自承载网关的 syslog:

$ cat host/var/log/syslog | grep "apimuser"
May 15 05:54:20 aks-agentpool-43853532-vmss000000 apimuser[8]: Timestamp=2023-05-15T05:54:20.0445178Z, isRequestSuccess=True, totalTime=290, category=GatewayLogs, callerIpAddress=141.134.132.243, timeGenerated=2023-05-15T05:54:20.0445178Z, region=Repro, correlationId=b28565ec-73e0-41e6-9312-efcdd6841846, method=GET, url="http://20.126.242.200/echo/resource?param1\=sample", backendResponseCode=200, responseCode=200, responseSize=628, cache=none, backendTime=287, apiId=echo-api, operationId=retrieve-resource, apimSubscriptionId=master, clientProtocol=HTTP/1.1, backendProtocol=HTTP/1.1, apiRevision=1, backendMethod=GET, backendUrl="http://echoapi.chinacloudapp.cn/api/resource?param1\=sample"
May 15 05:54:21 aks-agentpool-43853532-vmss000000 apimuser[8]: Timestamp=2023-05-15T05:54:21.1189171Z, isRequestSuccess=True, totalTime=150, category=GatewayLogs, callerIpAddress=141.134.132.243, timeGenerated=2023-05-15T05:54:21.1189171Z, region=Repro, correlationId=ab4d7464-acee-40ae-af95-a521cc57c759, method=GET, url="http://20.126.242.200/echo/resource?param1\=sample", backendResponseCode=200, responseCode=200, responseSize=628, cache=none, backendTime=148, apiId=echo-api, operationId=retrieve-resource, apimSubscriptionId=master, clientProtocol=HTTP/1.1, backendProtocol=HTTP/1.1, apiRevision=1, backendMethod=GET, backendUrl="http://echoapi.chinacloudapp.cn/api/resource?param1\=sample"

注意

如果使用 chroot 更改了根(例如 chroot /host),则上述路径需要反映该更改。

后续步骤