โหลดเมตริกจากเซิร์ฟเวอร์ Prometheus

ดูบน TensorFlow.org ทำงานใน Google Colab ดูแหล่งที่มาบน GitHub ดาวน์โหลดโน๊ตบุ๊ค

ภาพรวม

กวดวิชานี้จะโหลด 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 ที่มีอยู่จากเซิร์ฟเวอร์ PostgreSQL, สามารถทำได้ด้วย 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 ฟิลด์เป็น Dict หลามขยายตัวใน:

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

ในตัวอย่างข้างต้น, 'coredns' เป็นชื่องาน 'localhost:9153' เป็นชื่ออินสแตนซ์และ 'coredns_dns_request_count_total' เป็นชื่อตัวชี้วัด โปรดทราบว่าขึ้นอยู่กับการสืบค้น Prometheus ที่ใช้ มีความเป็นไปได้ที่งาน/อินสแตนซ์/เมตริกหลายรายการสามารถส่งคืนได้ นี่เป็นเหตุผลว่าทำไม python dict จึงถูกใช้ในโครงสร้างของชุดข้อมูล

ใช้แบบสอบถามอีก "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 ที่ง่ายมากพร้อม 1 ฟีเจอร์และ 2 ขั้นตอนเป็นอินพุต:

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