TensorFlow.org에서 보기 | Google Colab에서 실행하기 | GitHub에서소스 보기 | 노트북 다운로드하기 |
주의: Python 패키지 외에 이 노트북에서는 sudo apt-get install
을 사용하여 타자 패키지를 설치합니다.
개요
이 튜토리얼은 Prometheus 서버에서 tf.data.Dataset
로 CoreDNS 메트릭을 로드한 다음 훈련과 추론에 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 설치 및 설정하기
데모 목적으로, DNS 쿼리를 수신하기 위해 포트 9053
이 열려 있고 스크래핑에 대한 메트릭을 노출하기 위해 포트 9153
(기본값)이 열려 있는 CoreDNS 서버가 로컬에 있습니다. 다음은 CoreDNS에 대한 기본 Corefile 구성이며 다운로드할 수 있습니다.
.: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 &')
다음 단계로 Prometheus 서버를 설정하고 Prometheus를 사용하여 위의 포트 9153
에서 노출된 CoreDNS 메트릭을 스크래핑합니다. 구성을 위한 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
명령을 사용하여 설정된 CoreDNS 서버에 대해 몇 가지 DNS 쿼리를 생성할 수 있습니다.
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 메트릭에 대한 Dataset를 만들고 TensorFlow에서 사용하기
PostgreSQL 서버에서 사용할 수 있고 tfio.experimental.IODataset.from_prometheus
를 통해 수행할 수 있는 CoreDNS 메트릭의 Dataset를 만듭니다. 최소한 두 가지 인수가 필요합니다. query
는 메트릭을 선택하기 위해 Prometheus 서버로 전달되고 length
는 Dataset에 로드하려는 기간입니다.
"coredns_dns_request_count_total"
및 "5"
(초)로 시작하여 아래 Dataset를 만들 수 있습니다. 튜토리얼 앞부분에서 두 개의 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
Dataset의 사양을 자세히 살펴보겠습니다.
( TensorSpec(shape=(), dtype=tf.int64, name=None), { 'coredns': { 'localhost:9153': { 'coredns_dns_request_count_total': TensorSpec(shape=(), dtype=tf.float64, name=None) } } } )
데이터세트는 (time, values)
튜플로 구성되는 것을 분명히 알 수 있으며, values
필드는 다음으로 확장된 Python dict입니다.
"job_name": { "instance_name": { "metric_name": value, }, }
위의 예에서 'coredns'
는 작업 이름이고, 'localhost:9153'
은 인스턴스 이름이며, 'coredns_dns_request_count_total'
은 메트릭 이름입니다. 사용된 Prometheus 쿼리에 따라 여러 작업/인스턴스/메트릭이 반환될 수 있습니다. 이것은 또한 Python dict이 Dataset의 구조에 사용된 이유이기도 합니다.
다른 쿼리 "go_memstats_gc_sys_bytes"
를 예로 들어 보겠습니다. CoreDNS와 Prometheus가 모두 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
로 직접 전달할 수 있습니다.
모델 훈련에 Dataset 사용하기
메트릭 Dataset가 생성되면 모델 훈련 또는 추론을 위해 Dataset를 tf.keras
로 바로 전달할 수 있습니다.
데모 목적으로 이 튜토리얼에서는 1개의 특성과 2개의 스텝을 입력으로 포함하는 매우 간단한 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')
사용할 데이터세트는 10개의 샘플이 있는 CoreDNS의 'go_memstats_sys_bytes' 값입니다. 그러나 window=n_steps
및 shift=1
의 슬라이딩 윈도우가 형성되기 때문에 추가 샘플이 필요합니다(연속된 두 요소에 대해 첫 번째 요소는 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 자동화의 실제 문제를 해결할 수 있습니다.