إنشاء تنبيهات بحث السجل من نتائج تحليلات الحاوية

تراقب نتيجة تحليلات الحاوية أداء أحمال عمل الحاوية التي يتم نشرها على نظم مجموعات Kubernetes المدارة أو المدارة ذاتيا. للتنبيه بشأن ما يهم، توضح هذه المقالة كيفية إنشاء تنبيهات مستندة إلى السجل للحالات التالية باستخدام مجموعات Azure Kubernetes Service (AKS):

  • عندما يتجاوز استخدام CPU أو الذاكرة على عقد نظام المجموعة عتبة
  • عندما يتجاوز استخدام وحدة المعالجة المركزية أو الذاكرة على أي حاوية داخل وحدة تحكم عتبة بالمقارنة مع حد معين في المورد المقابل
  • NotReady عدد عقدة الحالة
  • FailedSucceededUnknownRunningأو Pendingعدد مراحل الجراب
  • عندما تتجاوز مساحة القرص الحرة على عقد نظام المجموعة عتبة

للتنبيه لاستخدام وحدة المعالجة المركزية أو الذاكرة عالية أو مساحة القرص الحرة المنخفضة على عقد نظام المجموعة، استخدم الاستعلامات التي يتم توفيرها لإنشاء تنبيه متري أو تنبيه قياس متري. تتمتع التنبيهات القياسية لزمن انتقال أقل من تنبيهات بحث السجل، ولكن توفر تنبيهات بحث السجل استعلاما متقدما وتطورا أكبر. تقارن استعلامات تنبيه بحث السجل التاريخ والوقت الحالي باستخدام now عامل التشغيل والعودة ساعة واحدة. (تخزن نتائج تحليلات الحاوية جميع التواريخ بتنسيق التوقيت العالمي المتفق عليه [UTC].)

هام

تعتمد الاستعلامات في هذه المقالة على البيانات التي تم جمعها بواسطة نتائج تحليلات الحاوية وتخزينها في مساحة عمل Log Analytics. إذا قمت بتعديل إعدادات جمع البيانات الافتراضية، فقد لا ترجع الاستعلامات النتائج المتوقعة. على وجه الخصوص، إذا قمت بتعطيل جمع بيانات الأداء منذ تمكين مقاييس Prometheus لنظام المجموعة، فلن ترجع أي استعلامات تستخدم Perf الجدول النتائج.

راجع تكوين جمع البيانات في نتائج تحليلات الحاوية باستخدام قاعدة جمع البيانات للتكوينات المعينة مسبقا بما في ذلك تعطيل جمع بيانات الأداء. راجع تكوين جمع البيانات في نتائج تحليلات الحاوية باستخدام ConfigMap لمزيد من خيارات جمع البيانات.

إذا لم تكن على دراية بتنبيهات Azure Monitor، فشاهد نظرة عامة على التنبيهات في Microsoft Azure قبل البدء. لمعرفة المزيد حول التنبيهات التي تستخدم استعلامات السجل، راجع تسجيل تنبيهات البحث في Azure Monitor. لمعرفة المزيد حول تنبيهات القياس راجع تنبيهات القياس في Azure Monitor.

قياسات استعلام السجل

يمكن لتنبيهات بحث السجل قياس أمرين مختلفين، والتي يمكن استخدامها لمراقبة الأجهزة الظاهرية في سيناريوهات مختلفة:

  • عدد النتائج: حساب عدد الصفوف التي تم إرجاعها بواسطة الاستعلام ويمكن استخدامها للعمل مع أحداث مثل سجلات أحداث Windows وSyslog واستثناءات التطبيق.
  • حساب قيمة: إجراء عملية حسابية استنادا إلى عمود رقمي ويمكن استخدامها لتضمين أي عدد من الموارد. مثال على ذلك هو النسبة المئوية لوحدة المعالجة المركزية.

الموارد والأبعاد المستهدفة

يمكنك استخدام قاعدة واحدة لمراقبة قيم مثيلات متعددة باستخدام الأبعاد. على سبيل المثال، يمكنك استخدام الأبعاد إذا كنت تريد مراقبة استخدام وحدة المعالجة المركزية على مثيلات متعددة تقوم بتشغيل موقع الويب أو التطبيق الخاص بك، وإنشاء تنبيه لاستخدام وحدة المعالجة المركزية لأكثر من 80٪.

لإنشاء تنبيهات تركز على الموارد على نطاق واسع لاشتراك أو مجموعة موارد، يمكنك تقسيمها حسب الأبعاد. عندما تريد مراقبة نفس الشرط على موارد Azure متعددة، يؤدي التقسيم حسب الأبعاد إلى تقسيم التنبيهات إلى تنبيهات منفصلة عن طريق تجميع مجموعات فريدة باستخدام أعمدة رقمية أو أعمدة سلسلة. يؤدي تقسيم عمود معرف مورد Azure إلى جعل المورد المحدد في هدف التنبيه.

قد تقرر أيضا عدم التقسيم عندما تريد شرطا على موارد متعددة في النطاق. على سبيل المثال، قد تحتاج إلى إنشاء تنبيه إذا كان خمسة أجهزة على الأقل في نطاق مجموعة الموارد لديها استخدام وحدة المعالجة المركزية أكثر من 80٪.

لقطة شاشة تعرض قاعدة تنبيه بحث سجل جديدة مع تقسيم حسب الأبعاد.

قد ترغب في رؤية قائمة بالتنبيهات مع أجهزة الكمبيوتر المتأثرة. يمكنك استخدام مصنف مخصص يستخدم رسما بيانيا لمورد مخصص لتوفير طريقة العرض هذه. استخدم الاستعلام التالي لعرض التنبيهات، واستخدم مصدر البيانات Azure Resource Graph في المصنف.

إنشاء قاعدة تنبيه بحث السجل

لإنشاء قاعدة تنبيه بحث في السجل باستخدام المدخل، راجع هذا المثال لتنبيه بحث السجل، والذي يوفر معاينة كاملة. يمكنك استخدام هذه العمليات نفسها لإنشاء قواعد تنبيه لمجموعات AKS باستخدام استعلامات مشابهة للاستعلامات الواردة في هذه المقالة.

لإنشاء قاعدة تنبيه استعلام باستخدام قالب Azure Resource Manager (ARM)، راجع نماذج قالب Resource Manager لقواعد تنبيه بحث السجل في Azure Monitor. يمكنك استخدام هذه العمليات نفسها لإنشاء قوالب ARM لاستعلامات السجل في هذه المقالة.

استخدام المورد

متوسط استخدام وحدة المعالجة المركزية كمتوسط استخدام وحدة المعالجة المركزية للعقد الأعضاء كل دقيقة (قياس متري):

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 AggValue = avg(UsagePercent) by bin(TimeGenerated, trendBinSize), ClusterName

متوسط استخدام الذاكرة كمتوسط استخدام ذاكرة العقد الأعضاء كل دقيقة (قياس متري):

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 AggValue = avg(UsagePercent) by bin(TimeGenerated, trendBinSize), ClusterName

هام

تستخدم الاستعلامات التالية قيم العناصر النائبة <your-cluster-name> و<your-controller-name> لتمثيل المجموعة ووحدة التحكم الخاصة بك. استبدلها بقيم خاصة بالبيئة الخاصة بك عند إعداد التنبيهات.

متوسط استخدام وحدة المعالجة المركزية لجميع الحاويات في وحدة تحكم كمتوسط استخدام وحدة المعالجة المركزية لكل مثيل حاوية في وحدة تحكم كل دقيقة (قياس متري):

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 AggValue = avg(UsagePercent) by bin(TimeGenerated, trendBinSize) , ContainerName

متوسط استخدام الذاكرة لجميع الحاويات في وحدة تحكم كمتوسط استخدام الذاكرة لكل مثيل حاوية في وحدة تحكم كل دقيقة (قياس متري):

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 AggValue = avg(UsagePercent) by bin(TimeGenerated, trendBinSize) , ContainerName

توفر الموارد

العقد والأعداد التي لها حالة Ready و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

يقوم الاستعلام التالي بإرجاع عدد مراحل الجراب استنادا إلى جميع المراحل: Failedأو PendingUnknownRunning.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, ClusterName
        | 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 AggValue = avg(PendingCount) by bin(TimeGenerated, trendBinSize)

إشعار

للتنبيه على مراحل معينة من الجراب، مثل Pending، Failedأو Unknown، قم بتعديل السطر الأخير من الاستعلام. على سبيل المثال، للتنبيه على FailedCount، استخدم | summarize AggValue = avg(FailedCount) by bin(TimeGenerated, trendBinSize).

يرجع الاستعلام التالي أقراص عقد نظام المجموعة التي تتجاوز 90٪ من المساحة الحرة المستخدمة. للحصول على معرف نظام مجموعة، قم اولًا بتشغيل الاستعلام التالي ونسخ القيمة من الخاصية ClusterId :

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 AggValue = max(DiskMetricValue) by bin(TimeGenerated, trendBinSize)
| where AggValue >= 90

تنبيه إعادة تشغيل الحاوية الفردية (عدد النتائج) عندما يتجاوز عدد إعادة تشغيل حاوية النظام الفردية حد آخر 10 دقائق:

let _threshold = 10m; 
let _alertThreshold = 2;
let Timenow = (datetime(now) - _threshold); 
let starttime = ago(5m); 
KubePodInventory
| where TimeGenerated >= starttime
| where Namespace in ('default', 'kube-system') // the namespace filter goes here
| where ContainerRestartCount > _alertThreshold
| extend Tags = todynamic(ContainerLastStatus)
| extend startedAt = todynamic(Tags.startedAt)
| where startedAt >= Timenow
| summarize arg_max(TimeGenerated, *) by Name

الخطوات التالية