你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

容器见解故障排除

本文讨论使用容器见解监视 Kubernetes 群集时的一些常见问题和故障排除步骤。

正在创建重复的警报

可能已启用 Prometheus 警报规则,而未禁用容器见解建议的警报。 请参阅从 Container Insights 的建议警报迁移到 Prometheus 的建议警报规则(预览版)

群集权限

如果没有群集所需的权限,可能会看到错误消息: You do not have the right cluster permissions which will restrict your access to Container Insights features. Please reach out to your cluster admin to get the right permission.

容器见解以前允许用户基于 Log Analytics 工作区的访问权限访问 Azure 门户体验。 它现在会检查群集级权限,以提供对 Azure 门户体验的访问权限。 你可能需要让你的群集管理员分配此权限。

对于基本的只读群集级别访问权限,请为以下类型的群集分配“监视读取者”角色。

  • 未启用 Kubernetes 基于角色的访问控制 (RBAC) 授权的 AKS
  • 使用基于 Microsoft Entra SAML 的单一登录启用的 AKS
  • 启用了 Kubernetes RBAC 授权的 AKS
  • 配置了群集角色绑定 clusterMonitoringUser 的 AKS
  • 已启用 Azure Arc 的 Kubernetes 群集

有关如何为 AKS 分配这些角色的详细信息,请参阅向用户或组分配角色权限;有关角色分配的详细信息,请参阅 Azure Kubernetes 服务 (AKS) 的访问和标识选项

载入和更新问题

以下部分介绍群集中启用或更新容器监控信息时可能会遇到的问题。

缺少订阅注册

如果看到错误 Missing Subscription registration,请在 Log Analytics 工作区的订阅中注册资源提供程序 Microsoft.OperationsManagement 。 请参阅 解决资源提供程序注册错误

授权错误

启用容器洞察或更新群集时,可能会收到类似以下错误的消息 The client <user's identity> with object id <user's objectId> does not have authorization to perform action Microsoft.Authorization/roleAssignments/write over scope.

在载入或更新过程中,尝试将 “监视指标发布者 ”角色分配给群集资源。 启动进程的用户必须有权访问 AKS 群集资源范围的 Microsoft.Authorization/roleAssignments/write 权限。 只有所有者和用户访问管理员内置角色的成员才被授权访问此权限。 如果安全策略要求分配粒度级别的权限,请查看 Azure 自定义角色并将权限分配给需要它的用户。 在 Azure 门户使用“通过使用 Azure 门户分配 Azure 角色”指南,将“发布者”角色分配给“监视指标”。

无法升级群集

如果在安装后无法升级 AKS 群集上的容器见解,则群集发送其数据的 Log Analytics 工作区可能已被删除。 禁用群集监控并通过另一个工作区再次启用容器洞察

安装 Azure Monitor 容器扩展失败

错误 manifests contain a resource that already exists 指示已启用 Azure Arc 的 Kubernetes 群集上已存在容器见解代理的资源,这意味着容器见解代理已安装。 通过清理容器见解代理的现有资源,然后启用 Azure Monitor 容器扩展来解决此问题。

AKS 群集

运行以下命令并查找 Azure Monitor 代理加载项配置文件,以验证是否已启用 AKS 监视加载项:

az  account set -s <clusterSubscriptionId>
az aks show -g <clusterResourceGroup> -n <clusterName>

如果输出包含具有日志分析工作区资源 ID 的 Azure Monitor 代理加载项配置文件配置,则表示已启用 AKS 监视加载项,必须使用以下命令禁用它:

az aks disable-addons -a monitoring -g <clusterResourceGroup> -n <clusterName>
非 AKS 集群

对群集运行以下命令验证 azmon-containers-release-1 Helm 图表版本是否存在。

helm list  -A

如果输出表明 azmon-containers-release-1 存在,则使用以下命令删除 Helm 图表版本:

helm del azmon-containers-release-1

缺少数据

在群集上启用容器见解后,最多可能需要 15 分钟才能显示数据。 如果在 15 分钟后未看到数据,请参阅以下部分了解潜在问题和解决方案。

检索数据的错误消息

如果群集正在发送其数据的 Log Analytics 工作区已删除,则可能会发生错误消息 Error retrieving data 。 如果是这种情况,禁用群集监视,并使用另一个工作区再次启用容器见解。

本地身份验证已禁用

使用以下 CLI 命令检查 Log Analytics 工作区是否已配置为进行本地身份验证。

az resource show --ids "/subscriptions/[Your subscription ID]/resourcegroups/[Your resource group]/providers/microsoft.operationalinsights/workspaces/[Your workspace name]"

如果 disableLocalAuth = true,请运行以下命令。

az resource update --ids "/subscriptions/[Your subscription ID]/resourcegroups/[Your resource group]/providers/microsoft.operationalinsights/workspaces/[Your workspace name]" --api-version "2021-06-01" --set properties.features.disableLocalAuth=False |

每日上限已达

如果 Log Analytics 工作区达到每日上限,则会在重置时间之前停止收集数据。 请参阅 Log Analytics 每日上限

未使用 Terraform 部署 DCR

如果使用 Terraform 启用了容器见解,且 msi_auth_for_monitoring_enabled 设置为 true,请确保也部署了 DCR 和 DCRA 资源,以启用日志收集。 请参阅启用容器见解

容器分析不报告任何信息

如果无法查看状态信息或没有从日志查询返回结果,请使用以下步骤。

  1. 使用以下命令检查代理的状态:

    kubectl get ds ama-logs --namespace=kube-system

    Pod 数应等于群集上的 Linux 节点数。 输出应类似于以下示例,指示已正确部署:

    User@aksuser:~$ kubectl get ds ama-logs --namespace=kube-system
    NAME       DESIRED   CURRENT   READY     UP-TO-DATE   AVAILABLE   NODE SELECTOR    AGE
    ama-logs   2         2         2         2            2           <none>           1d
    
  2. 如果有 Windows Server 节点,请通过运行以下命令检查代理状态:

    kubectl get ds ama-logs-windows --namespace=kube-system

    Pod 数应等于群集上的 Windows 节点数。 输出应类似于以下示例,指示已正确部署:

    User@aksuser:~$ kubectl get ds ama-logs-windows --namespace=kube-system
    NAME                   DESIRED   CURRENT   READY     UP-TO-DATE   AVAILABLE   NODE SELECTOR    AGE
    ama-logs-windows           2         2         2         2            2           <none>       1d
    
  3. 使用以下命令检查部署状态:

    kubectl get deployment ama-logs-rs --namespace=kube-system

    输出应类似于以下示例,指示已正确部署:

    User@aksuser:~$ kubectl get deployment ama-logs-rs --namespace=kube-system
    NAME          READY   UP-TO-DATE   AVAILABLE   AGE
    ama-logs-rs   1/1     1            1           24d
    
  4. 使用命令 kubectl get pods --namespace=kube-system 检查 Pod 的状态,验证它是否正在运行。

    输出应类似于以下示例,其中 ama-logs 的状态为 Running

    User@aksuser:~$ kubectl get pods --namespace=kube-system
    NAME                                READY     STATUS    RESTARTS   AGE
    aks-ssh-139866255-5n7k5             1/1       Running   0          8d
    azure-vote-back-4149398501-7skz0    1/1       Running   0          22d
    azure-vote-front-3826909965-30n62   1/1       Running   0          22d
    ama-logs-484hw                      1/1       Running   0          1d
    ama-logs-fkq7g                      1/1       Running   0          1d
    ama-logs-windows-6drwq              1/1       Running   0          1d
    
  5. 如果 pod 处于运行状态,但 Log Analytics 中没有数据,或者数据似乎只在一天中的某一时段发送,则表明可能已达到每日上限。 如果每天都达到此限制,数据将停止引入 Log Analytics 工作区并在重置时重置。 有关详细信息,请参阅 Log Analytics 每日上限

指标未被收集

  1. 使用以下 CLI 命令验证是否存在“监视指标发布者”角色分配:

    az role assignment list --assignee "SP/UserassignedMSI for Azure Monitor Agent" --scope "/subscriptions/<subid>/resourcegroups/<RG>/providers/Microsoft.ContainerService/managedClusters/<clustername>" --role "Monitoring Metrics Publisher"
    

    对于具有 MSI 的群集,每次启用和禁用监视时,用户分配的 Azure Monitor 代理客户端 ID 都会更改,因此当前 MSI 客户端 ID 上应存在角色分配。

  2. 对于启用了 Microsoft Entra Pod 标识并使用 MSI 的群集:

    • 使用以下命令验证 Azure Monitor 代理 Pod 上是否存在所需的“kubernetes.azure.com/managedby: aks”标签:

      kubectl get pods --show-labels -n kube-system | grep ama-logs

    • 验证使用 https://github.com/Azure/aad-pod-identity#1-deploy-aad-pod-identity 上其中一种受支持的方法启用 Pod 标识时是否启用了异常。

      运行以下命令验证:

      kubectl get AzurePodIdentityException -A -o yaml

      应该会收到类似如下示例的输出:

      apiVersion: "aadpodidentity.k8s.io/v1"
      kind: AzurePodIdentityException
      metadata:
      name: mic-exception
      namespace: default
      spec:
      podLabels:
      app: mic
      component: mic
      ---
      apiVersion: "aadpodidentity.k8s.io/v1"
      kind: AzurePodIdentityException
      metadata:
      name: aks-addon-exception
      namespace: kube-system
      spec:
      podLabels:
      kubernetes.azure.com/managedby: aks
      

性能图表不显示非 Azure 群集上节点和容器的 CPU 或内存

容器见解代理 Pod 使用节点代理上的 cAdvisor 终结点来收集性能指标。 验证节点上的容器化代理是否配置为允许在群集中的所有节点上打开 cAdvisor secure port: 10250cAdvisor unsecure port: 10255 以收集性能指标。 请参阅 混合 Kubernetes 群集的先决条件

ContainerLog 表中不填充映像和名称值

对于代理版本及更高版本 ciprod12042019 ,默认情况下不会为每个日志行填充这两个属性,以最大程度地降低收集的日志数据产生的成本。 可以启用这些属性的集合或修改查询,以包括其他表中的这些属性。

通过在 ContainerID 属性上进行联接,将查询修改为包含 ContainerInventory 表中的 ImageImageTag 属性。 通过在 ContainerID 属性上进行联接,可以包含 KubepodInventory 表的 ContainerName 字段中的 Name 属性(与以前在 ContainerLog 表中显示的相同)。

以下示例查询演示如何使用联接来检索这些值。

//Set the time window for the query
let startTime = ago(1h);
let endTime = now();
//
//Get the latest Image & ImageTag for every containerID
let ContainerInv = ContainerInventory | where TimeGenerated >= startTime and TimeGenerated < endTime | summarize arg_max(TimeGenerated, *)  by ContainerID, Image, ImageTag | project-away TimeGenerated | project ContainerID1=ContainerID, Image1=Image ,ImageTag1=ImageTag;
//
//Get the latest Name for every containerID
let KubePodInv  = KubePodInventory | where ContainerID != "" | where TimeGenerated >= startTime | where TimeGenerated < endTime | summarize arg_max(TimeGenerated, *)  by ContainerID2 = ContainerID, Name1=ContainerName | project ContainerID2 , Name1;
//
//Join the above to get a jointed table that has name, image & imagetag. Outer left is used in case there are no kubepod records or if they're latent
let ContainerData = ContainerInv | join kind=leftouter (KubePodInv) on $left.ContainerID1 == $right.ContainerID2;
//
//Join ContainerLog table with the jointed table above, project-away redundant fields/columns, and rename columns that were rewritten. Outer left is used so logs aren't lost even if no container metadata for loglines is found.
ContainerLog
| where TimeGenerated >= startTime and TimeGenerated < endTime
| join kind= leftouter (
  ContainerData
) on $left.ContainerID == $right.ContainerID2 | project-away ContainerID1, ContainerID2, Name, Image, ImageTag | project-rename Name = Name1, Image=Image1, ImageTag=ImageTag1

警告

对于具有 50 个以上的节点的大型群集,不建议启用属性。 它从群集中的每个节点生成 API 服务器调用,并增加收集的每个日志行的数据大小。

若要启用这些字段的集合,因此无需修改查询,请在代理配置映射中启用设置 log_collection_settings.enrich_container_logs ,如 数据收集配置设置中所述。

Azure Local 群集上不收集日志

如果在 2023 年 11 月之前为 Azure 本地注册了群集和/或配置了 Insights,则使用 Azure 本地 Azure Monitor 代理的功能(例如 Arc for Servers Insights、VM Insights、Container Insights、Defender for Cloud 或 Microsoft Sentinel)可能无法正确收集日志和事件数据。 请参阅修复适用于 Azure Local 的 AMA 代理,了解为 Azure Local 重新配置代理和见解的步骤。

大型群集上的数据缺失

如果下表中缺少数据,可能的问题与解析大型负载有关,因为存在大量 Pod 或节点。 Ruby 插件中存在一个已知问题,这是由于默认的 PODS_CHUNK_SIZE 为 1000,导致插件将大型 JSON 有效负载暂停。

有计划将默认PODS_CHUNK_SIZE值调整为较小的值以解决此问题。

  • KubePodInventory (KubePod清单)
  • KubeNodeInventory
  • KubeEvents
  • KubePV库存
  • KubeServices
  1. 使用以下命令验证是否已在群集上配置较小的 PODS_CHUNK_SIZE 值。

    # verify if kube context being set for right cluster
    kubectl cluster-info
    
    # check if the configmap configured with smaller PODS_CHUNK_SIZE chunksize already
    kubectl logs <ama-logs-rs pod name> -n kube-system -c ama-logs | grep PODS_CHUNK_SIZE
    
    # If it's configured, the output will be similar to "Using config map value: PODS_CHUNK_SIZE = 10"
    
  2. 如果该群集已经配置为较小的 PODS_CHUNK_SIZE 值,则需要为大型群集启用该群集。

  3. 如果群集使用默认值 PODS_CHUNK_SIZE=1000,请检查群集是否具有大量 Pod 或节点。

    # check the total number of PODS
    kubectl get pods -A -o wide | wc -l
    
    # check the total number of NODES
    kubectl get nodes -o wide | wc -l
    
  4. 在确认 Pod 和节点数相当高,而且群集使用的是默认值 PODS_CHUNK_SIZE=1000 后,使用以下命令来配置配置映射。

    # Check if the cluster has container-azm-ms-agentconfig configmap in kube-system namespace
    kubectl get cm -n kube-system | grep container-azm-ms-agentconfig
    
    # If there is no existing container-azm-ms-agentconfig configmap, then configmap needs to be downloaded  and applied
    curl -L https://raw.githubusercontent.com/microsoft/Docker-Provider/refs/heads/ci_prod/kubernetes/container-azm-ms-agentconfig.yaml -o container-azm-ms-agentconfig
    kubectl apply -f container-azm-ms-agentconfig
    
    # Edit the configmap and uncomment agent_settings.chunk_config and PODS_CHUNK_SIZE lines under agent-settings: |- in the configmap
    kubectl edit cm -n kube-system  container-azm-ms-agentconfig -o yaml
    

代理 OOM 已终止

Daemonset 容器被 OOM 终止

  1. 首先,使用以下命令确定哪个容器被 OOM 终止。 这将标识ama-logsama-logs-prometheus,或同时标识这两者。

    # verify if kube context being set for right cluster
    kubectl cluster-info
    
    # get the ama-logs pods and status
    kubectl get pods -n kube-system -o custom-columns=NAME:.metadata.name | grep -E ama-logs-[a-z0-9]{5}
    
    # from the result of above command, find out which ama-logs pod instance getting OOM killed
    kubectl describe pod <ama-logs-pod> -n kube-system
    
    # review the output of the above command to findout which ama-logs container is getting OOM killed
    
  2. 使用以下命令检查日志文件中 mdsd.err 是否存在网络错误。

    mkdir log
    # for ama-logs-prometheus container use -c ama-logs-prometheus instead of -c ama-logs
    kubectl cp -c ama-logs kube-system/<ama-logs pod name>:/var/opt/microsoft/linuxmonagent/log log
    cd log
    cat mdsd.err
    
  3. 如果错误是由于出站终结点被阻止所致,请参阅监视 Kubernetes 群集的网络防火墙要求,了解终结点要求。

  4. 如果错误是由于缺少数据收集终结点 (DCE) 或数据收集规则 (DCR) 所致,则使用为 Kubernetes 群集启用监视指南重新启用容器见解。

  5. 如果没有错误,则可能与日志缩放相关。 请参阅 Container Insights 中的大规模日志收集(预览版)。

Replicaset 容器被 OOM 终止

  1. 使用以下命令确定 ama-logs-rs Pod 被 OOM 终止的频率:

    # verify if kube context being set for right cluster
    kubectl cluster-info
    
    # get the ama-logs pods and status
    kubectl get pods -n kube-system -o wide | grep ama-logs-rs
    
    # from the result of above command, find out which ama-logs pod instance getting OOM killed
    kubectl describe pod <ama-logs-rs-pod> -n kube-system
    
    # review the output of the above command to confirm the OOM kill
    
  2. 如果 ama-logs-rs 被 OOM 终止,请使用以下命令检查是否有网络错误。

     mkdir log
     kubectl cp -c ama-logs kube-system/<ama-logs-rs pod name>:/var/opt/microsoft/linuxmonagent/log log
     cd log
     cat mdsd.err
    
  3. 如果由于出站终结点被阻止而出错,请参阅 用于监视 Kubernetes 群集的网络防火墙要求 以了解终结点要求。

  4. 如果错误是由于缺少数据收集终结点(DCE)或数据收集规则(DCR),则可以使用启用 Kubernetes 群集监视指南重新启用容器洞察。

  5. 如果没有网络错误,请通过查看 configmap 中的 [prometheus_data_collection_settings.cluster] 设置,检查是否启用了集群级别的 prometheus 抓取。

    # Check if the cluster has container-azm-ms-agentconfig configmap in kube-system namespace
    kubectl get cm -n kube-system | grep container-azm-ms-agentconfig
    # If there is no existing container-azm-ms-agentconfig configmap, then means cluster level prometheus data collection not enabled
    
  6. 根据节点和 Pod 计数检查群集大小。

    # Check if the cluster has container-azm-ms-agentconfig configmap in kube-system namespace
    NodeCount=$(kubectl get nodes | wc -l)
    echo "Total number of nodes: ${NodeCount}"
    PodCount=$(kubectl get pods -A -o wide | wc -l)
    echo "Total number of pods: ${PodCount}"
    
    # If there is no existing container-azm-ms-agentconfig configmap, then means cluster level prometheus data collection is not enabled.
    
  7. 如果确定问题与群集的规模相关,则需要增加 ama-logs-rs 内存限制。 向 Microsoft 提交支持案例进行请求。

延迟问题

默认情况下,容器洞察每隔 60 秒收集一次监控数据,除非配置数据收集设置或添加 转换。 有关 Log Analytics 工作区中延迟和预期引入时间的详细信息,请参阅 Azure Monitor 中的日志数据 引入时间。

使用以下查询检查与群集关联的 Log Analytics 工作区中报告表和时间窗口的延迟。

let clusterResourceId = "/subscriptions/<subscriptionId>/resourceGroups/<rgName>/providers/Microsoft.ContainerService/managedClusters/<clusterName>";
let startTime = todatetime('2024-11-20T20:34:11.9117523Z');
let endTime = todatetime('2024-11-21T20:34:11.9117523Z');
KubePodInventory #Update this table name to the one you want to check
| where _ResourceId =~ clusterResourceId
| where TimeGenerated >= startTime and TimeGenerated <= endTime
| extend E2EIngestionLatency = ingestion_time() - TimeGenerated
| extend AgentLatency = _TimeReceived - TimeGenerated
| summarize max(E2EIngestionLatency), max(AgentLatency) by Computer
| project Computer, max_AgentLatency, max_ingestionLatency = (max_E2EIngestionLatency -  max_AgentLatency),max_E2EIngestionLatency

如果看到代理延迟较高,请检查是否在 Container Insights DCR 中配置了与默认 60 秒不同的日志收集间隔。

# set the subscriptionId of the cluster
az account set -s "<subscriptionId>"
# check if ContainerInsightsExtension  data collection rule association exists
az monitor data-collection rule association list --resource <clusterResourceId>
# get the data collection rule resource id associated to ContainerInsightsExtension from above step
az monitor data-collection rule show  --ids  <dataCollectionRuleResourceIdFromAboveStep>
# check if there are any data collection settings related to interval from the output of the above step

日志记录出现多行问题

可以使用 configmap 启用多行日志功能,并支持以下方案。

  • 支持最多 64KB 的日志消息,而不是默认限制为 16KB。
  • 拼接支持的语言(.NET、Go、Python 和 Java)的异常调用堆栈跟踪。

使用以下命令验证是否启用了多行功能和 ContainerLogV2 架构。

    # get the list of ama-logs and these pods should be in Running state
    # If these are not in Running state, then this needs to be investigated
    kubectl get po -n kube-system | grep ama-logs

    # exec into any one of the ama-logs daemonset pod and check for the environment variables
    kubectl exec -it  ama-logs-xxxxx -n kube-system -c ama-logs -- bash

    # after exec into the container run this command
    env | grep AZMON_MULTILINE

    # result should have environment variables which indicates the multiline and languages enabled
    AZMON_MULTILINE_LANGUAGES=java,go
    AZMON_MULTILINE_ENABLED=true

    # check if the containerlog v2 schema enabled or not
    env | grep AZMON_CONTAINER_LOG_SCHEMA_VERSION

    # output should be v2. If not v2, then check whether this is being enabled through DCR
    AZMON_CONTAINER_LOG_SCHEMA_VERSION=v2