Ver en TensorFlow.org | Ejecutar en Google Colab | Ver fuente en GitHub | Descargar libreta |
Descripción general
Este tutorial cargas CoreDNS métricas de un Prometeo servidor en un tf.data.Dataset
, a continuación, utiliza tf.keras
para la formación y la inferencia.
CoreDNS es un servidor DNS con un enfoque de descubrimiento de servicios, y es ampliamente desplegado como parte de la Kubernetes clúster. Por esa razón, a menudo las operaciones de DevOps lo controlan de cerca.
Este tutorial es un ejemplo que podría ser utilizado por devops en busca de automatización en sus operaciones a través del aprendizaje automático.
Configuración y uso
Instale el paquete tensorflow-io requerido y reinicie el tiempo de ejecución
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
Instalar y configurar CoreDNS y Prometheus
Para propósitos de demostración, un servidor CoreDNS localmente con el puerto 9053
abierto a recibir consultas de DNS y el puerto 9153
(defult) abierta para exponer las métricas para raspar. La siguiente es una configuración básica para el fichero de núcleo CoreDNS y está disponible para descarga :
.:9053 {
prometheus
whoami
}
Más detalles acerca de la instalación se podían encontrar en CoreDNS de documentación .
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 &')
El siguiente paso es configurar el servidor de Prometeo y el uso de Prometeo a CoreDNS rascado métricas que están expuestas en el puerto 9153
desde arriba. El prometheus.yml
archivo de configuración también está disponible para su descarga :
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 &')
Con el fin de mostrar alguna actividad, dig
de comandos podría ser utilizado para generar un par de consultas DNS contra el servidor CoreDNS que ha sido configurado:
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
Ahora, un servidor CoreDNS cuyas métricas son extraídas por un servidor Prometheus y están listas para ser consumidas por TensorFlow.
Cree un conjunto de datos para las métricas de CoreDNS y utilícelo en TensorFlow
Crear un conjunto de datos para CoreDNS métricas que se encuentra disponible en el servidor PostgreSQL, que se podría hacer con tfio.experimental.IODataset.from_prometheus
. Como mínimo, se necesitan dos argumentos. query
se pasa al servidor de Prometeo para seleccionar las métricas y la length
es el período que desea cargar en conjunto de datos.
Puede comenzar con "coredns_dns_request_count_total"
y "5"
(segundos) para crear el conjunto de datos a continuación. Dado que fueron enviados anteriormente en el tutorial de dos consultas DNS, se espera que las métricas para "coredns_dns_request_count_total"
serán "2.0"
al final de la serie de tiempo:
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
Analizando más a fondo las especificaciones del conjunto de datos:
(
TensorSpec(shape=(), dtype=tf.int64, name=None),
{
'coredns': {
'localhost:9153': {
'coredns_dns_request_count_total': TensorSpec(shape=(), dtype=tf.float64, name=None)
}
}
}
)
Es obvio que el conjunto de datos consiste en una (time, values)
tupla donde el values
de campo es un diccionario ampliado en Python:
"job_name": {
"instance_name": {
"metric_name": value,
},
}
En el ejemplo anterior, 'coredns'
es el nombre del trabajo, 'localhost:9153'
es el nombre de la instancia, y 'coredns_dns_request_count_total'
es el nombre de la métrica. Tenga en cuenta que, según la consulta de Prometheus utilizada, es posible que se devuelvan varios trabajos / instancias / métricas. Esta es también la razón por la que se ha utilizado python dict en la estructura del conjunto de datos.
Tome otra consulta "go_memstats_gc_sys_bytes"
como un ejemplo. Dado que ambos CoreDNS y Prometeo están escritos en Golang, "go_memstats_gc_sys_bytes"
métrica está disponible tanto para "coredns"
trabajo y "prometheus"
de empleo:
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
El creado Dataset
está listo para ser pasado a tf.keras
directamente, ya sea para fines de entrenamiento o de inferencia ahora.
Usa el conjunto de datos para el entrenamiento de modelos
Con la métrica del conjunto de datos creada, es posible pasar directamente al conjunto de datos para tf.keras
para la formación de modelo o inferencia.
Para propósitos de demostración, este tutorial solo usará un modelo LSTM muy simple con 1 característica y 2 pasos como entrada:
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')
El conjunto de datos que se utilizará es el valor de 'go_memstats_sys_bytes' para CoreDNS con 10 muestras. Sin embargo, desde una ventana deslizante de window=n_steps
y shift=1
están formados, se necesitan muestras adicionales (para cualquier par de elementos consecute, la primera se toma como x
, y la segunda se toma como y
para la formación). El total es 10 + n_steps - 1 + 1 = 12
segundos.
El valor de datos también se escala a [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>
El modelo entrenado anterior no es muy útil en realidad, ya que el servidor CoreDNS que se ha configurado en este tutorial no tiene ninguna carga de trabajo. Sin embargo, esta es una canalización de trabajo que podría usarse para cargar métricas desde verdaderos servidores de producción. Luego, el modelo podría mejorarse para resolver el problema del mundo real de la automatización de DevOps.