Creación de alertas de registro a partir de Azure Monitor para contenedoresHow to create log alerts from Azure Monitor for containers

Azure Monitor para contenedores supervisa el rendimiento de las cargas de trabajo de contenedor implementadas en clústeres de Kubernetes administrados o autoadministrados.Azure Monitor for containers monitors the performance of container workloads that are deployed to managed or self-managed Kubernetes clusters. Para alertar sobre lo que importa, en este artículo se describe cómo crear alertas basadas en registro para las siguientes situaciones con los clústeres de AKS:To alert on what matters, this article describes how to create log-based alerts for the following situations with AKS clusters:

  • Cuando el uso de CPU o memoria en los nodos del clúster supera un umbralWhen CPU or memory utilization on cluster nodes exceeds a threshold
  • Cuando el uso de CPU o memoria en cualquier contenedor dentro de un controlador supera un umbral en comparación con un límite que se establece en el recurso correspondienteWhen CPU or memory utilization on any container within a controller exceeds a threshold as compared to a limit that's set on the corresponding resource
  • Recuentos del nodo de estado NotReadyNotReady status node counts
  • Recuentos de fase de pod Erróneo, Pendiente, Desconocido, Ejecución o CorrectoFailed, Pending, Unknown, Running, or Succeeded pod-phase counts
  • Cuando el espacio libre en disco de los nodos del clúster supera un umbralWhen free disk space on cluster nodes exceeds a threshold

Para generar una alerta sobre el uso elevado de CPU o de memoria o sobre poco espacio libre en disco en los nodos del clúster, use las consultas que se proporcionan para crear una alerta de métrica o una alerta de medida de métrica.To alert for high CPU or memory utilization, or low free disk space on cluster nodes, use the queries that are provided to create a metric alert or a metric measurement alert. Mientras que las alertas de métricas tienen una latencia menor que las alertas de registro, estas proporcionan consultas avanzadas y una mayor sofisticación.While metric alerts have lower latency than log alerts, log alerts provide advanced querying and greater sophistication. Las consultas de alertas de registro comparan una fecha y hora con la actual mediante el operador now y retroceden una hora.Log alert queries compare a datetime to the present by using the now operator and going back one hour. (Azure Monitor para contenedores almacena todas las fechas en formato de Hora universal coordinada [UTC]).(Azure Monitor for containers stores all dates in Coordinated Universal Time (UTC) format.)

Si no está familiarizado con las alertas en Azure Monitor, consulte Información general sobre las alertas en Microsoft Azure antes de empezar.If you're not familiar with Azure Monitor alerts, see Overview of alerts in Microsoft Azure before you start. Para más información acerca de las alertas que usan consultas de registro, consulte Alertas de registro en Azure Monitor.To learn more about alerts that use log queries, see Log alerts in Azure Monitor. Para más información acerca de las alertas de métrica consulte Comprender cómo funcionan las alertas de métricas en Azure Monitor.For more about metric alerts, see Metric alerts in Azure Monitor.

Consultas de búsqueda de registro de uso de recursosResource utilization log search queries

Las consultas de esta sección admiten todos los escenarios de alertas.The queries in this section support each alerting scenario. Se usan en el paso 7 de la sección crear alerta de este artículo.They're used in step 7 of the create alert section of this article.

En la siguiente consulta se calcula el uso medio de CPU como la media de uso de CPU de los nodos miembros, cada minuto.The following query calculates average CPU utilization as an average of member nodes' CPU utilization every minute.

let endDateTime = now();
let startDateTime = ago(1h);
let trendBinSize = 1m;
let capacityCounterName = 'cpuCapacityNanoCores';
let usageCounterName = 'cpuUsageNanoCores';
KubeNodeInventory
| where TimeGenerated < endDateTime
| where TimeGenerated >= startDateTime
// cluster filter would go here if multiple clusters are reporting to the same Log Analytics workspace
| distinct ClusterName, Computer
| join hint.strategy=shuffle (
  Perf
  | where TimeGenerated < endDateTime
  | where TimeGenerated >= startDateTime
  | where ObjectName == 'K8SNode'
  | where CounterName == capacityCounterName
  | summarize LimitValue = max(CounterValue) by Computer, CounterName, bin(TimeGenerated, trendBinSize)
  | project Computer, CapacityStartTime = TimeGenerated, CapacityEndTime = TimeGenerated + trendBinSize, LimitValue
) on Computer
| join kind=inner hint.strategy=shuffle (
  Perf
  | where TimeGenerated < endDateTime + trendBinSize
  | where TimeGenerated >= startDateTime - trendBinSize
  | where ObjectName == 'K8SNode'
  | where CounterName == usageCounterName
  | project Computer, UsageValue = CounterValue, TimeGenerated
) on Computer
| where TimeGenerated >= CapacityStartTime and TimeGenerated < CapacityEndTime
| project ClusterName, Computer, TimeGenerated, UsagePercent = UsageValue * 100.0 / LimitValue
| summarize AggregatedValue = avg(UsagePercent) by bin(TimeGenerated, trendBinSize), ClusterName

En la siguiente consulta se calcula el uso medio de memoria como la media de uso de memoria de los nodos miembros, cada minuto.The following query calculates average memory utilization as an average of member nodes' memory utilization every minute.

let endDateTime = now();
let startDateTime = ago(1h);
let trendBinSize = 1m;
let capacityCounterName = 'memoryCapacityBytes';
let usageCounterName = 'memoryRssBytes';
KubeNodeInventory
| where TimeGenerated < endDateTime
| where TimeGenerated >= startDateTime
// cluster filter would go here if multiple clusters are reporting to the same Log Analytics workspace
| distinct ClusterName, Computer
| join hint.strategy=shuffle (
  Perf
  | where TimeGenerated < endDateTime
  | where TimeGenerated >= startDateTime
  | where ObjectName == 'K8SNode'
  | where CounterName == capacityCounterName
  | summarize LimitValue = max(CounterValue) by Computer, CounterName, bin(TimeGenerated, trendBinSize)
  | project Computer, CapacityStartTime = TimeGenerated, CapacityEndTime = TimeGenerated + trendBinSize, LimitValue
) on Computer
| join kind=inner hint.strategy=shuffle (
  Perf
  | where TimeGenerated < endDateTime + trendBinSize
  | where TimeGenerated >= startDateTime - trendBinSize
  | where ObjectName == 'K8SNode'
  | where CounterName == usageCounterName
  | project Computer, UsageValue = CounterValue, TimeGenerated
) on Computer
| where TimeGenerated >= CapacityStartTime and TimeGenerated < CapacityEndTime
| project ClusterName, Computer, TimeGenerated, UsagePercent = UsageValue * 100.0 / LimitValue
| summarize AggregatedValue = avg(UsagePercent) by bin(TimeGenerated, trendBinSize), ClusterName

Importante

En las consultas siguientes se usan los valores de marcador de posición <your-cluster-name> y <your-controller-name> para representar el clúster y el controlador.The following queries use the placeholder values <your-cluster-name> and <your-controller-name> to represent your cluster and controller. Reemplácelos por valores específicos del entorno al configurar las alertas.Replace them with values specific to your environment when you set up alerts.

En la siguiente consulta se calcula el uso medio de CPU de todos los contenedores en un controlador como la media de uso de CPU de cada instancia de contenedor en un controlador, cada minuto.The following query calculates the average CPU utilization of all containers in a controller as an average of CPU utilization of every container instance in a controller every minute. La medida es un porcentaje del límite configurado para un contenedor.The measurement is a percentage of the limit set up for a container.

let endDateTime = now();
let startDateTime = ago(1h);
let trendBinSize = 1m;
let capacityCounterName = 'cpuLimitNanoCores';
let usageCounterName = 'cpuUsageNanoCores';
let clusterName = '<your-cluster-name>';
let controllerName = '<your-controller-name>';
KubePodInventory
| where TimeGenerated < endDateTime
| where TimeGenerated >= startDateTime
| where ClusterName == clusterName
| where ControllerName == controllerName
| extend InstanceName = strcat(ClusterId, '/', ContainerName),
         ContainerName = strcat(controllerName, '/', tostring(split(ContainerName, '/')[1]))
| distinct Computer, InstanceName, ContainerName
| join hint.strategy=shuffle (
    Perf
    | where TimeGenerated < endDateTime
    | where TimeGenerated >= startDateTime
    | where ObjectName == 'K8SContainer'
    | where CounterName == capacityCounterName
    | summarize LimitValue = max(CounterValue) by Computer, InstanceName, bin(TimeGenerated, trendBinSize)
    | project Computer, InstanceName, LimitStartTime = TimeGenerated, LimitEndTime = TimeGenerated + trendBinSize, LimitValue
) on Computer, InstanceName
| join kind=inner hint.strategy=shuffle (
    Perf
    | where TimeGenerated < endDateTime + trendBinSize
    | where TimeGenerated >= startDateTime - trendBinSize
    | where ObjectName == 'K8SContainer'
    | where CounterName == usageCounterName
    | project Computer, InstanceName, UsageValue = CounterValue, TimeGenerated
) on Computer, InstanceName
| where TimeGenerated >= LimitStartTime and TimeGenerated < LimitEndTime
| project Computer, ContainerName, TimeGenerated, UsagePercent = UsageValue * 100.0 / LimitValue
| summarize AggregatedValue = avg(UsagePercent) by bin(TimeGenerated, trendBinSize) , ContainerName

En la siguiente consulta se calcula el uso medio de memoria de todos los contenedores en un controlador como la media de uso de memoria de cada instancia de contenedor en un controlador, cada minuto.The following query calculates the average memory utilization of all containers in a controller as an average of memory utilization of every container instance in a controller every minute. La medida es un porcentaje del límite configurado para un contenedor.The measurement is a percentage of the limit set up for a container.

let endDateTime = now();
let startDateTime = ago(1h);
let trendBinSize = 1m;
let capacityCounterName = 'memoryLimitBytes';
let usageCounterName = 'memoryRssBytes';
let clusterName = '<your-cluster-name>';
let controllerName = '<your-controller-name>';
KubePodInventory
| where TimeGenerated < endDateTime
| where TimeGenerated >= startDateTime
| where ClusterName == clusterName
| where ControllerName == controllerName
| extend InstanceName = strcat(ClusterId, '/', ContainerName),
         ContainerName = strcat(controllerName, '/', tostring(split(ContainerName, '/')[1]))
| distinct Computer, InstanceName, ContainerName
| join hint.strategy=shuffle (
    Perf
    | where TimeGenerated < endDateTime
    | where TimeGenerated >= startDateTime
    | where ObjectName == 'K8SContainer'
    | where CounterName == capacityCounterName
    | summarize LimitValue = max(CounterValue) by Computer, InstanceName, bin(TimeGenerated, trendBinSize)
    | project Computer, InstanceName, LimitStartTime = TimeGenerated, LimitEndTime = TimeGenerated + trendBinSize, LimitValue
) on Computer, InstanceName
| join kind=inner hint.strategy=shuffle (
    Perf
    | where TimeGenerated < endDateTime + trendBinSize
    | where TimeGenerated >= startDateTime - trendBinSize
    | where ObjectName == 'K8SContainer'
    | where CounterName == usageCounterName
    | project Computer, InstanceName, UsageValue = CounterValue, TimeGenerated
) on Computer, InstanceName
| where TimeGenerated >= LimitStartTime and TimeGenerated < LimitEndTime
| project Computer, ContainerName, TimeGenerated, UsagePercent = UsageValue * 100.0 / LimitValue
| summarize AggregatedValue = avg(UsagePercent) by bin(TimeGenerated, trendBinSize) , ContainerName

En la siguiente consulta se devuelven todos los nodos y recuentos que tienen un estado de Ready y NotReady.The following query returns all nodes and counts that have a status of Ready and NotReady.

let endDateTime = now();
let startDateTime = ago(1h);
let trendBinSize = 1m;
let clusterName = '<your-cluster-name>';
KubeNodeInventory
| where TimeGenerated < endDateTime
| where TimeGenerated >= startDateTime
| distinct ClusterName, Computer, TimeGenerated
| summarize ClusterSnapshotCount = count() by bin(TimeGenerated, trendBinSize), ClusterName, Computer
| join hint.strategy=broadcast kind=inner (
    KubeNodeInventory
    | where TimeGenerated < endDateTime
    | where TimeGenerated >= startDateTime
    | summarize TotalCount = count(), ReadyCount = sumif(1, Status contains ('Ready'))
                by ClusterName, Computer,  bin(TimeGenerated, trendBinSize)
    | extend NotReadyCount = TotalCount - ReadyCount
) on ClusterName, Computer, TimeGenerated
| project   TimeGenerated,
            ClusterName,
            Computer,
            ReadyCount = todouble(ReadyCount) / ClusterSnapshotCount,
            NotReadyCount = todouble(NotReadyCount) / ClusterSnapshotCount
| order by ClusterName asc, Computer asc, TimeGenerated desc

En la siguiente consulta se devuelven recuentos de fase de pod basados en todas las fases: Erróneo, Pendiente, Desconocido, Ejecución o Correcto.The following query returns pod phase counts based on all phases: Failed, Pending, Unknown, Running, or Succeeded.

let endDateTime = now(); 
let startDateTime = ago(1h);
let trendBinSize = 1m;
let clusterName = '<your-cluster-name>';
KubePodInventory
    | where TimeGenerated < endDateTime
    | where TimeGenerated >= startDateTime
    | where ClusterName == clusterName
    | distinct ClusterName, TimeGenerated
    | summarize ClusterSnapshotCount = count() by bin(TimeGenerated, trendBinSize), ClusterName
    | join hint.strategy=broadcast (
        KubePodInventory
        | where TimeGenerated < endDateTime
        | where TimeGenerated >= startDateTime
        | summarize PodStatus=any(PodStatus) by TimeGenerated, PodUid, ClusterId
        | summarize TotalCount = count(),
                    PendingCount = sumif(1, PodStatus =~ 'Pending'),
                    RunningCount = sumif(1, PodStatus =~ 'Running'),
                    SucceededCount = sumif(1, PodStatus =~ 'Succeeded'),
                    FailedCount = sumif(1, PodStatus =~ 'Failed')
                by ClusterName, bin(TimeGenerated, trendBinSize)
    ) on ClusterName, TimeGenerated
    | extend UnknownCount = TotalCount - PendingCount - RunningCount - SucceededCount - FailedCount
    | project TimeGenerated,
              TotalCount = todouble(TotalCount) / ClusterSnapshotCount,
              PendingCount = todouble(PendingCount) / ClusterSnapshotCount,
              RunningCount = todouble(RunningCount) / ClusterSnapshotCount,
              SucceededCount = todouble(SucceededCount) / ClusterSnapshotCount,
              FailedCount = todouble(FailedCount) / ClusterSnapshotCount,
              UnknownCount = todouble(UnknownCount) / ClusterSnapshotCount
| summarize AggregatedValue = avg(PendingCount) by bin(TimeGenerated, trendBinSize)

Nota

Para generar una alerta en ciertas fases de pod, tales como Pendiente, Erróneo o Desconocido, modifique la última línea de la consulta.To alert on certain pod phases, such as Pending, Failed, or Unknown, modify the last line of the query. Por ejemplo, para generar alertas sobre FailedCount, use:For example, to alert on FailedCount use:
| summarize AggregatedValue = avg(FailedCount) by bin(TimeGenerated, trendBinSize)

En la consulta siguiente se devuelven los discos de los nodos de clúster que superan el 90 % del espacio libre utilizado.The following query returns cluster nodes disks which exceed 90% free space used. Para obtener el id. de clúster, primero ejecute la siguiente consulta y copie el valor de la propiedad ClusterId:To get the cluster ID, first run the following query and copy the value from the ClusterId property:

InsightsMetrics
| extend Tags = todynamic(Tags)            
| project ClusterId = Tags['container.azm.ms/clusterId']   
| distinct tostring(ClusterId)   
let clusterId = '<cluster-id>';
let endDateTime = now();
let startDateTime = ago(1h);
let trendBinSize = 1m;
InsightsMetrics
| where TimeGenerated < endDateTime
| where TimeGenerated >= startDateTime
| where Origin == 'container.azm.ms/telegraf'            
| where Namespace == 'container.azm.ms/disk'            
| extend Tags = todynamic(Tags)            
| project TimeGenerated, ClusterId = Tags['container.azm.ms/clusterId'], Computer = tostring(Tags.hostName), Device = tostring(Tags.device), Path = tostring(Tags.path), DiskMetricName = Name, DiskMetricValue = Val   
| where ClusterId =~ clusterId       
| where DiskMetricName == 'used_percent'
| summarize AggregatedValue = max(DiskMetricValue) by bin(TimeGenerated, trendBinSize)
| where AggregatedValue >= 90

Crear una regla de alertaCreate an alert rule

Esta sección le guía a través de la creación de una regla de alerta de medición de métricas mediante datos de rendimiento de Azure Monitor para contenedores.This section walks through the creation of a metric measurement alert rule using performance data from Azure Monitor for containers. Puede usar este proceso básico con diversas consultas de registro para alertar sobre diferentes contadores de rendimiento.You can use this basic process with a variety of log queries to alert on different performance counters. Use una de las consultas de búsqueda de registros proporcionadas anteriormente para comenzar.Use one of the log search queries provided earlier to start with. Para crearla mediante una plantilla de Resource Manager, consulte Ejemplos de creación de una alerta de registro mediante la plantilla de Azure Resource Manager.To create using an ARM template, see Samples of Log alert creation using Azure Resource Template.

Nota

En el siguiente procedimiento para crear una regla de alerta para el uso de recursos de contenedor, deberá cambiar a una nueva API de alertas de registro, tal como se describe en Cambio de la preferencia de API para las alertas de registro.The following procedure to create an alert rule for container resource utilization requires you to switch to a new log alerts API as described in Switch API preference for log alerts.

  1. Inicie sesión en Azure Portal.Sign in to the Azure portal.

  2. En Azure Portal, busque y seleccione Áreas de trabajo de Log Analytics.In the Azure portal, search for and select Log Analytics workspaces.

  3. En la lista de áreas de trabajo de Log Analytics, seleccione el área de trabajo que admite Azure Monitor para contenedores.In your list of Log Analytics workspaces, select the workspace supporting Azure Monitor for containers.

  4. En el panel de la izquierda, seleccione Registros para abrir la página de registros de Azure Monitor.In the pane on the left side, select Logs to open the Azure Monitor logs page. Utilice esta página para escribir y ejecutar consultas de registro de Azure.You use this page to write and execute Azure log queries.

  5. En la página Registros, pegue una de las consultas proporcionadas anteriormente en el campo Consulta de búsqueda y luego seleccione Ejecutar para validar los resultados.On the Logs page, paste one of the queries provided earlier into the Search query field and then select Run to validate the results. Si no realiza este paso, la opción Nueva alerta no está disponible para la selección.If you do not perform this step, the +New alert option is not available to select.

  6. Seleccione Nueva alerta para crear una alerta de registro.Select +New alert to create a log alert.

  7. En la sección Condición, seleccione la condición de registro personalizada predefinida Cada vez que la búsqueda de registros personalizada sea <logic undefined> .In the Condition section, select the Whenever the Custom log search is <logic undefined> pre-defined custom log condition. El tipo de señal de búsqueda de registros personalizada se selecciona automáticamente porque estamos creando una regla de alertas directamente desde la página de registros de Azure Monitor.The custom log search signal type is automatically selected because we're creating an alert rule directly from the Azure Monitor logs page.

  8. Pegue cualquiera de las consultas proporcionadas con anterioridad en el campo Consulta de búsqueda.Paste one of the queries provided earlier into the Search query field.

  9. Configure la alerta de la manera siguiente:Configure the alert as follows:

    1. En la lista desplegable Basado en, seleccione Unidades métricas.From the Based on drop-down list, select Metric measurement. Una medida de métrica crea una alerta por cada objeto de la consulta con un valor por encima del umbral especificado.A metric measurement creates an alert for each object in the query that has a value above our specified threshold.
    2. En Condición, seleccione Mayor que y escriba 75 como un umbral de línea de base inicial para las alertas de uso de CPU y memoria.For Condition, select Greater than, and enter 75 as an initial baseline Threshold for the CPU and memory utilization alerts. Para la alerta de poco espacio en disco, escriba 90.For the low disk space alert, enter 90. O escriba un valor diferente que satisfaga sus criterios.Or enter a different value that meets your criteria.
    3. En la sección Desencadenar alerta según, seleccione Infracciones consecutivas.In the Trigger Alert Based On section, select Consecutive breaches. En la lista desplegable, seleccione Mayor que y escriba 2.From the drop-down list, select Greater than, and enter 2.
    4. Para configurar una alerta de uso de CPU o de memoria de contenedor, en Agregado en, seleccione ContainerName.To configure an alert for container CPU or memory utilization, under Aggregate on, select ContainerName. Para configurar la alerta de poco espacio en disco de nodo de clúster, seleccione ClusterId.To configure for cluster node low disk alert, select ClusterId.
    5. En la sección Se evaluó basándose en, establezca el valor de Período en 60 minutos.In the Evaluated based on section, set the Period value to 60 minutes. La regla se ejecutará cada cinco minutos y devolverá los registros que se crearon dentro de la última hora a partir del momento actual.The rule will run every 5 minutes and return records that were created within the last hour from the current time. El establecimiento del período de tiempo en una ventana amplia considera la latencia de datos potencial.Setting the time period to a wide window accounts for potential data latency. También garantiza que la consulta vaya a devolver datos para evitar un falso negativo en el que la alerta nunca se active.It also ensures that the query returns data to avoid a false negative in which the alert never fires.
  10. Seleccione Listo para completar la regla de alertas.Select Done to complete the alert rule.

  11. Escriba un nombre en el campo Nombre de la regla de alertas.Enter a name in the Alert rule name field. Especifique una Descripción que proporcione los detalles sobre la alerta.Specify a Description that provides details about the alert. Y seleccione un nivel de gravedad adecuado en las opciones proporcionadas.And select an appropriate severity level from the options provided.

  12. Para activar inmediatamente la regla de alertas, acepte el valor predeterminado de Habilitar regla tras la creación.To immediately activate the alert rule, accept the default value for Enable rule upon creation.

  13. Seleccione un Grupo de acciones existente o cree uno nuevo.Select an existing Action Group or create a new group. Este paso garantiza que se realizan las mismas acciones cada vez que se desencadena una alerta.This step ensures that the same actions are taken every time that an alert is triggered. Configure en función de cómo el equipo de operaciones de TI o DevOps administra los incidentes.Configure based on how your IT or DevOps operations team manages incidents.

  14. Seleccione Crear regla de alertas para finalizar la regla de alertas.Select Create alert rule to complete the alert rule. Se iniciará la ejecución de inmediato.It starts running immediately.

Pasos siguientesNext steps