Muat metrik dari server Prometheus

Lihat di TensorFlow.org Jalankan di Google Colab Lihat sumber di GitHub Unduh buku catatan

Ringkasan

Tutorial beban CoreDNS metrik dari Prometheus server menjadi tf.data.Dataset , kemudian menggunakan tf.keras untuk pelatihan dan inferensi.

CoreDNS adalah server DNS dengan fokus pada penemuan layanan, dan secara luas digunakan sebagai bagian dari Kubernetes cluster. Untuk alasan itu sering dipantau secara ketat oleh operasi devops.

Tutorial ini adalah contoh yang dapat digunakan oleh pengembang yang mencari otomatisasi dalam operasi mereka melalui pembelajaran mesin.

Pengaturan dan penggunaan

Instal paket tensorflow-io yang diperlukan, dan mulai ulang runtime

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

Instal dan atur CoreDNS dan Prometheus

Untuk tujuan demo, server CoreDNS lokal dengan port 9053 terbuka untuk menerima permintaan DNS dan port 9153 (defult) terbuka untuk mengekspos metrik untuk menggores. Berikut ini adalah konfigurasi dasar Corefile untuk CoreDNS dan tersedia untuk men-download :

.:9053 {
  prometheus
  whoami
}

Rincian lebih lanjut tentang instalasi dapat ditemukan di CoreDNS ini dokumentasi .

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 &')

Langkah berikutnya adalah untuk setup Prometheus server dan menggunakan Prometheus untuk CoreDNS mengikis metrik yang terkena pada port 9153 dari atas. The prometheus.yml file untuk konfigurasi juga tersedia untuk men-download :

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 &')

Dalam rangka untuk menunjukkan beberapa aktivitas, dig perintah dapat digunakan untuk menghasilkan beberapa pertanyaan DNS terhadap server CoreDNS yang telah setup:

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

Sekarang server CoreDNS yang metriknya diambil oleh server Prometheus dan siap digunakan oleh TensorFlow.

Buat Dataset untuk metrik CoreDNS dan gunakan di TensorFlow

Buat Dataset untuk CoreDNS metrik yang tersedia dari server PostgreSQL, bisa dilakukan dengan tfio.experimental.IODataset.from_prometheus . Minimal diperlukan dua argumen. query akan diteruskan ke server Prometheus untuk memilih metrik dan length adalah periode yang Anda ingin beban ke Dataset.

Anda bisa mulai dengan "coredns_dns_request_count_total" dan "5" (detik) untuk membuat Dataset bawah. Sejak awal tutorial dua query DNS dikirim, diharapkan bahwa metrik untuk "coredns_dns_request_count_total" akan "2.0" pada akhir seri waktu:

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

Melihat lebih jauh ke dalam spesifikasi Dataset:

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

Hal ini jelas bahwa dataset terdiri dari (time, values) tuple di mana values bidang adalah dict python diperluas ke:

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

Dalam contoh di atas, 'coredns' adalah nama pekerjaan, 'localhost:9153' adalah nama contoh, dan 'coredns_dns_request_count_total' adalah nama metrik. Perhatikan bahwa tergantung pada kueri Prometheus yang digunakan, ada kemungkinan beberapa pekerjaan/instance/metrik dapat dikembalikan. Ini juga alasan mengapa python dict telah digunakan dalam struktur Dataset.

Ambil permintaan lain "go_memstats_gc_sys_bytes" sebagai contoh. Karena kedua CoreDNS dan Prometheus ditulis dalam Golang, "go_memstats_gc_sys_bytes" metrik yang tersedia untuk kedua "coredns" kerja dan "prometheus" pekerjaan:

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

Menciptakan Dataset siap untuk diteruskan ke tf.keras langsung baik untuk tujuan pelatihan atau inferensi sekarang.

Gunakan Dataset untuk pelatihan model

Dengan metrik Dataset diciptakan, adalah mungkin untuk langsung lulus Dataset untuk tf.keras untuk model pelatihan atau inferensi.

Untuk tujuan demo, tutorial ini hanya akan menggunakan model LSTM yang sangat sederhana dengan 1 fitur dan 2 langkah sebagai input:

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')

Dataset yang akan digunakan adalah nilai 'go_memstats_sys_bytes' untuk CoreDNS dengan 10 sampel. Namun, karena jendela geser dari window=n_steps dan shift=1 terbentuk, sampel tambahan diperlukan (untuk setiap dua elemen consecute, yang pertama diambil sebagai x dan yang kedua diambil sebagai y untuk pelatihan). Jumlah ini 10 + n_steps - 1 + 1 = 12 detik.

Nilai data juga ditingkatkan untuk [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>

Model terlatih di atas sebenarnya tidak terlalu berguna, karena server CoreDNS yang telah disiapkan dalam tutorial ini tidak memiliki beban kerja apa pun. Namun, ini adalah saluran kerja yang dapat digunakan untuk memuat metrik dari server produksi yang sebenarnya. Model kemudian dapat ditingkatkan untuk memecahkan masalah dunia nyata dari otomatisasi devops.