تحميل المقاييس من خادم بروميثيوس

عرض على TensorFlow.org تشغيل في Google Colab عرض المصدر على جيثب تحميل دفتر

ملخص

هذه الأحمال CoreDNS تعليمي المقاييس من بروميثيوس الخادم إلى tf.data.Dataset ، ثم يستخدم tf.keras للتدريب والاستدلال.

CoreDNS هو خادم DNS مع التركيز على اكتشاف الخدمة، ويتم نشرها على نطاق واسع كجزء من Kubernetes العنقودية. لهذا السبب ، غالبًا ما تراقب عن كثب عمليات devops.

هذا البرنامج التعليمي هو مثال يمكن استخدامه من قبل المطورين الذين يبحثون عن الأتمتة في عملياتهم من خلال التعلم الآلي.

الإعداد والاستخدام

قم بتثبيت حزمة tensorflow-io المطلوبة ، وأعد تشغيل وقت التشغيل

import os
try:
  %tensorflow_version 2.x
except Exception:
  pass
TensorFlow 2.x selected.
pip install tensorflow-io
from datetime import datetime

import tensorflow as tf
import tensorflow_io as tfio

تثبيت وإعداد CoreDNS و Prometheus

لعرض الأغراض، الخادم CoreDNS محليا مع منفذ 9053 مفتوحة لتلقي الاستفسارات DNS ومنفذ 9153 (defult) مفتوحة لفضح المقاييس للكشط. ما يلي هو تكوين Corefile الأساسي للCoreDNS ومتاح لل تحميل :

.:9053 {
  prometheus
  whoami
}

يمكن العثور على مزيد من التفاصيل حول التثبيت على CoreDNS في الوثائق .

curl -s -OL https://github.com/coredns/coredns/releases/download/v1.6.7/coredns_1.6.7_linux_amd64.tgz
tar -xzf coredns_1.6.7_linux_amd64.tgz

curl -s -OL https://raw.githubusercontent.com/tensorflow/io/master/docs/tutorials/prometheus/Corefile

cat Corefile
.:9053 {
  prometheus
  whoami
}
# Run `./coredns` as a background process.
# IPython doesn't recognize `&` in inline bash cells.
get_ipython().system_raw('./coredns &')

الخطوة التالية هي لإعداد ملقم بروميثيوس واستخدام بروميثيوس لمقاييس CoreDNS كشط التي يتعرض لها على المنفذ 9153 من فوق. و prometheus.yml ملف التكوين هو أيضا متوفرة لل تحميل :

curl -s -OL https://github.com/prometheus/prometheus/releases/download/v2.15.2/prometheus-2.15.2.linux-amd64.tar.gz
tar -xzf prometheus-2.15.2.linux-amd64.tar.gz --strip-components=1

curl -s -OL https://raw.githubusercontent.com/tensorflow/io/master/docs/tutorials/prometheus/prometheus.yml

cat prometheus.yml
global:
  scrape_interval:     1s
  evaluation_interval: 1s
alerting:
  alertmanagers:

  - static_configs:
    - targets:
rule_files:
scrape_configs:
- job_name: 'prometheus'
  static_configs:
  - targets: ['localhost:9090']
- job_name: "coredns"
  static_configs:
  - targets: ['localhost:9153']
# Run `./prometheus` as a background process.
# IPython doesn't recognize `&` in inline bash cells.
get_ipython().system_raw('./prometheus &')

من أجل إظهار بعض النشاط، dig القيادة يمكن أن تستخدم لتوليد الاستفسارات DNS قليلة على الخادم CoreDNS الذي تم الإعداد:

sudo apt-get install -y -qq dnsutils
dig @127.0.0.1 -p 9053 demo1.example.org
; <<>> DiG 9.11.3-1ubuntu1.11-Ubuntu <<>> @127.0.0.1 -p 9053 demo1.example.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53868
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 3
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 855234f1adcb7a28 (echoed)
;; QUESTION SECTION:
;demo1.example.org.     IN  A

;; ADDITIONAL SECTION:
demo1.example.org.  0   IN  A   127.0.0.1
_udp.demo1.example.org. 0   IN  SRV 0 0 45361 .

;; Query time: 0 msec
;; SERVER: 127.0.0.1#9053(127.0.0.1)
;; WHEN: Tue Mar 03 22:35:20 UTC 2020
;; MSG SIZE  rcvd: 132
dig @127.0.0.1 -p 9053 demo2.example.org
; <<>> DiG 9.11.3-1ubuntu1.11-Ubuntu <<>> @127.0.0.1 -p 9053 demo2.example.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53163
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 3
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: f18b2ba23e13446d (echoed)
;; QUESTION SECTION:
;demo2.example.org.     IN  A

;; ADDITIONAL SECTION:
demo2.example.org.  0   IN  A   127.0.0.1
_udp.demo2.example.org. 0   IN  SRV 0 0 42194 .

;; Query time: 0 msec
;; SERVER: 127.0.0.1#9053(127.0.0.1)
;; WHEN: Tue Mar 03 22:35:21 UTC 2020
;; MSG SIZE  rcvd: 132

الآن هو خادم CoreDNS الذي يتم إلغاء مقاييسه بواسطة خادم Prometheus وجاهز للاستهلاك بواسطة TensorFlow.

قم بإنشاء مجموعة بيانات لمقاييس CoreDNS واستخدمها في TensorFlow

إنشاء قاعدة بيانات للCoreDNS المقاييس التي تتوفر من خدمة الإنترنت، ويمكن أن يتم مع tfio.experimental.IODataset.from_prometheus . في الحد الأدنى هناك حاجة إلى حجتين. query يتم تمريرها إلى خادم بروميثيوس لتحديد المقاييس و length هي الفترة التي تريد الحمل إلى مجموعة بيانات.

يمكنك أن تبدأ مع "coredns_dns_request_count_total" و "5" (ثانية) لإنشاء مجموعة بيانات أدناه. منذ أرسلت في وقت سابق في الاستعلامات DNS البرنامج التعليمي اثنين، ومن المتوقع أن مقاييس "coredns_dns_request_count_total" سيكون "2.0" في نهاية السلسلة الزمنية:

dataset = tfio.experimental.IODataset.from_prometheus(
      "coredns_dns_request_count_total", 5, endpoint="http://localhost:9090")


print("Dataset Spec:\n{}\n".format(dataset.element_spec))

print("CoreDNS Time Series:")
for (time, value) in dataset:
  # time is milli second, convert to data time:
  time = datetime.fromtimestamp(time // 1000)
  print("{}: {}".format(time, value['coredns']['localhost:9153']['coredns_dns_request_count_total']))
Dataset Spec:
(TensorSpec(shape=(), dtype=tf.int64, name=None), {'coredns': {'localhost:9153': {'coredns_dns_request_count_total': TensorSpec(shape=(), dtype=tf.float64, name=None)} } })

CoreDNS Time Series:
2020-03-03 22:35:17: 2.0
2020-03-03 22:35:18: 2.0
2020-03-03 22:35:19: 2.0
2020-03-03 22:35:20: 2.0
2020-03-03 22:35:21: 2.0

مزيد من البحث في مواصفات مجموعة البيانات:

(
  TensorSpec(shape=(), dtype=tf.int64, name=None),
  {
    'coredns': {
      'localhost:9153': {
        'coredns_dns_request_count_total': TensorSpec(shape=(), dtype=tf.float64, name=None)
      }
    }
  }
)

ومن الواضح أن مجموعة البيانات يتكون من (time, values) الصفوف (tuple) حيث values الحقل هو ديكت الثعبان سعت إلى:

"job_name": {
  "instance_name": {
    "metric_name": value,
  },
}

في المثال أعلاه، 'coredns' هو اسم الوظيفة، 'localhost:9153' هو اسم مثيل، و 'coredns_dns_request_count_total' هو اسم المتري. لاحظ أنه بناءً على استعلام بروميثيوس المستخدم ، من الممكن إرجاع وظائف / مثيلات / مقاييس متعددة. هذا أيضًا هو سبب استخدام pythonict في بنية مجموعة البيانات.

خذ استفسار آخر "go_memstats_gc_sys_bytes" كمثال على ذلك. منذ مكتوبة على حد سواء CoreDNS وبروميثيوس في Golang، "go_memstats_gc_sys_bytes" المقياس هو متاح لكل من "coredns" وظيفة و "prometheus" المهمة:

dataset = tfio.experimental.IODataset.from_prometheus(
    "go_memstats_gc_sys_bytes", 5, endpoint="http://localhost:9090")

print("Time Series CoreDNS/Prometheus Comparision:")
for (time, value) in dataset:
  # time is milli second, convert to data time:
  time = datetime.fromtimestamp(time // 1000)
  print("{}: {}/{}".format(
      time,
      value['coredns']['localhost:9153']['go_memstats_gc_sys_bytes'],
      value['prometheus']['localhost:9090']['go_memstats_gc_sys_bytes']))
Time Series CoreDNS/Prometheus Comparision:
2020-03-03 22:35:17: 2385920.0/2775040.0
2020-03-03 22:35:18: 2385920.0/2775040.0
2020-03-03 22:35:19: 2385920.0/2775040.0
2020-03-03 22:35:20: 2385920.0/2775040.0
2020-03-03 22:35:21: 2385920.0/2775040.0

وأنشئت Dataset على استعداد لتمريرها إلى tf.keras مباشرة لأي أغراض التدريب أو الاستدلال الآن.

استخدم مجموعة البيانات للتدريب على النموذج

مع المقاييس التي تم إنشاؤها الإدراجات، فمن الممكن أن يمر مباشرة إلى مجموعة بيانات tf.keras للتدريب نموذج أو الاستدلال.

لأغراض العرض ، سيستخدم هذا البرنامج التعليمي نموذج LSTM بسيط للغاية مع ميزة واحدة وخطوتين كمدخلات:

n_steps, n_features = 2, 1
simple_lstm_model = tf.keras.models.Sequential([
    tf.keras.layers.LSTM(8, input_shape=(n_steps, n_features)),
    tf.keras.layers.Dense(1)
])

simple_lstm_model.compile(optimizer='adam', loss='mae')

مجموعة البيانات التي سيتم استخدامها هي قيمة "go_memstats_sys_bytes" لـ CoreDNS مع 10 عينات. ومع ذلك، منذ نافذة انزلاق window=n_steps و shift=1 يتم تشكيلها، وهناك حاجة إلى عينات إضافية (لأي عناصر consecute اثنين، الأول هو تؤخذ على أنها x ويؤخذ الثانية كما y للتدريب). ويبلغ مجموع 10 + n_steps - 1 + 1 = 12 ثواني.

يتم تحجيم قيمة البيانات أيضا إلى [0, 1] .

n_samples = 10

dataset = tfio.experimental.IODataset.from_prometheus(
    "go_memstats_sys_bytes", n_samples + n_steps - 1 + 1, endpoint="http://localhost:9090")

# take go_memstats_gc_sys_bytes from coredns job 
dataset = dataset.map(lambda _, v: v['coredns']['localhost:9153']['go_memstats_sys_bytes'])

# find the max value and scale the value to [0, 1]
v_max = dataset.reduce(tf.constant(0.0, tf.float64), tf.math.maximum)
dataset = dataset.map(lambda v: (v / v_max))

# expand the dimension by 1 to fit n_features=1
dataset = dataset.map(lambda v: tf.expand_dims(v, -1))

# take a sliding window
dataset = dataset.window(n_steps, shift=1, drop_remainder=True)
dataset = dataset.flat_map(lambda d: d.batch(n_steps))


# the first value is x and the next value is y, only take 10 samples
x = dataset.take(n_samples)
y = dataset.skip(1).take(n_samples)

dataset = tf.data.Dataset.zip((x, y))

# pass the final dataset to model.fit for training
simple_lstm_model.fit(dataset.batch(1).repeat(10),  epochs=5, steps_per_epoch=10)
Train for 10 steps
Epoch 1/5
10/10 [==============================] - 2s 150ms/step - loss: 0.8484
Epoch 2/5
10/10 [==============================] - 0s 10ms/step - loss: 0.7808
Epoch 3/5
10/10 [==============================] - 0s 10ms/step - loss: 0.7102
Epoch 4/5
10/10 [==============================] - 0s 11ms/step - loss: 0.6359
Epoch 5/5
10/10 [==============================] - 0s 11ms/step - loss: 0.5572
<tensorflow.python.keras.callbacks.History at 0x7f1758f3da90>

النموذج المدرب أعلاه ليس مفيدًا جدًا في الواقع ، لأن خادم CoreDNS الذي تم إعداده في هذا البرنامج التعليمي لا يحتوي على أي عبء عمل. ومع ذلك ، يعد هذا خط أنابيب عمل يمكن استخدامه لتحميل المقاييس من خوادم الإنتاج الحقيقية. يمكن بعد ذلك تحسين النموذج لحل مشكلة العالم الحقيقي لأتمتة devops.