Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/es-419/io/tutorials/prometheus.ipynb
25118 views
Kernel: Python 3
#@title Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License.

Cargar métricas desde el servidor Prometheus

Precaución: Además de los paquetes de Python, este bloc de notas usa sudo apt-get install para instalar paquetes de terceros.

Descripción general

Este tutorial carga métricas de CoreDNS desde un servidor Prometheus en un tf.data.Dataset y luego usa tf.keras para entrenamiento e inferencia.

CoreDNS es un servidor DNS centrado en el descubrimiento de servicios y se implementa bastanta como parte del clúster de Kubernetes. Por esa razón, las operaciones devops a menudo lo supervisan de cerca.

Este tutorial es un ejemplo que podrían usar los desarrolladores que buscan automatización en sus operaciones a través del aprendizaje automático.

Configuración y uso

Instale el paquete tensorflow-io necesario 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
Requirement already satisfied: tensorflow-io in /usr/local/lib/python3.6/dist-packages (0.12.0) Requirement already satisfied: tensorflow<2.2.0,>=2.1.0 in /tensorflow-2.1.0/python3.6 (from tensorflow-io) (2.1.0) Requirement already satisfied: opt-einsum>=2.3.2 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (3.2.0) Requirement already satisfied: google-pasta>=0.1.6 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (0.1.8) Requirement already satisfied: tensorflow-estimator<2.2.0,>=2.1.0rc0 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (2.1.0) Requirement already satisfied: tensorboard<2.2.0,>=2.1.0 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (2.1.0) Requirement already satisfied: wheel>=0.26; python_version >= "3" in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (0.34.2) Requirement already satisfied: grpcio>=1.8.6 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (1.27.2) Requirement already satisfied: astor>=0.6.0 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (0.8.1) Requirement already satisfied: absl-py>=0.7.0 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (0.9.0) Requirement already satisfied: termcolor>=1.1.0 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (1.1.0) Requirement already satisfied: numpy<2.0,>=1.16.0 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (1.18.1) Requirement already satisfied: keras-applications>=1.0.8 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (1.0.8) Requirement already satisfied: protobuf>=3.8.0 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (3.11.3) Requirement already satisfied: keras-preprocessing>=1.1.0 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (1.1.0) Requirement already satisfied: wrapt>=1.11.1 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (1.12.0) Requirement already satisfied: gast==0.2.2 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (0.2.2) Requirement already satisfied: scipy==1.4.1; python_version >= "3" in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (1.4.1) Requirement already satisfied: six>=1.12.0 in /tensorflow-2.1.0/python3.6 (from tensorflow<2.2.0,>=2.1.0->tensorflow-io) (1.14.0) Requirement already satisfied: markdown>=2.6.8 in /tensorflow-2.1.0/python3.6 (from tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (3.2.1) Requirement already satisfied: setuptools>=41.0.0 in /tensorflow-2.1.0/python3.6 (from tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (45.2.0) Requirement already satisfied: werkzeug>=0.11.15 in /tensorflow-2.1.0/python3.6 (from tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (1.0.0) Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /tensorflow-2.1.0/python3.6 (from tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (0.4.1) Requirement already satisfied: google-auth<2,>=1.6.3 in /tensorflow-2.1.0/python3.6 (from tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (1.11.2) Requirement already satisfied: requests<3,>=2.21.0 in /tensorflow-2.1.0/python3.6 (from tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (2.23.0) Requirement already satisfied: h5py in /tensorflow-2.1.0/python3.6 (from keras-applications>=1.0.8->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (2.10.0) Requirement already satisfied: requests-oauthlib>=0.7.0 in /tensorflow-2.1.0/python3.6 (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (1.3.0) Requirement already satisfied: pyasn1-modules>=0.2.1 in /tensorflow-2.1.0/python3.6 (from google-auth<2,>=1.6.3->tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (0.2.8) Requirement already satisfied: cachetools<5.0,>=2.0.0 in /tensorflow-2.1.0/python3.6 (from google-auth<2,>=1.6.3->tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (4.0.0) Requirement already satisfied: rsa<4.1,>=3.1.4 in /tensorflow-2.1.0/python3.6 (from google-auth<2,>=1.6.3->tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (4.0) Requirement already satisfied: certifi>=2017.4.17 in /tensorflow-2.1.0/python3.6 (from requests<3,>=2.21.0->tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (2019.11.28) Requirement already satisfied: idna<3,>=2.5 in /tensorflow-2.1.0/python3.6 (from requests<3,>=2.21.0->tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (2.9) Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /tensorflow-2.1.0/python3.6 (from requests<3,>=2.21.0->tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (1.25.8) Requirement already satisfied: chardet<4,>=3.0.2 in /tensorflow-2.1.0/python3.6 (from requests<3,>=2.21.0->tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (3.0.4) Requirement already satisfied: oauthlib>=3.0.0 in /tensorflow-2.1.0/python3.6 (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (3.1.0) Requirement already satisfied: pyasn1<0.5.0,>=0.4.6 in /tensorflow-2.1.0/python3.6 (from pyasn1-modules>=0.2.1->google-auth<2,>=1.6.3->tensorboard<2.2.0,>=2.1.0->tensorflow<2.2.0,>=2.1.0->tensorflow-io) (0.4.8)
from datetime import datetime import tensorflow as tf import tensorflow_io as tfio

Instalar y configurar CoreDNS y Prometheus

Para fines de demostración, un servidor CoreDNS local con el puerto 9053 abierto para recibir consultas DNS y el puerto 9153 (predeterminado) abierto para exponer métricas para extracción. La siguiente es una configuración básica de Corefile para CoreDNS y está disponible para descargar:

.:9053 { prometheus whoami }

Se pueden encontrar más detalles sobre la instalación en la documentación de 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 &')

El siguiente paso es configurar el servidor Prometheus y usarlo para eliminar las métricas de CoreDNS que están expuestas en el puerto 9153 anterior. El archivo prometheus.yml para la configuración también está disponible para descargar:

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

Para mostrar alguna actividad, el comando dig podría usarse para generar algunas consultas DNS en el servidor CoreDNS que se ha 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 tenemos un servidor CoreDNS del que un servidor Prometheus extrae sus métricas listas para ser consumidas por TensorFlow.

Crear un conjunto de datos para métricas de CoreDNS y usarlo en TensorFlow

Crear un conjunto de datos para métricas de CoreDNS que esté disponible en el servidor PostgreSQL, se puede hacer con tfio.experimental.IODataset.from_prometheus. Se necesitan como mínimo dos argumentos. query se pasa al servidor Prometheus para seleccionar las métricas y length es el período que desea cargar en el 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 anteriormente en el tutorial se enviaron dos consultas DNS, se espera que las métricas para "coredns_dns_request_count_total" sean "2.0" al final de la serie temporal:

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

Profundizar en 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 consta de una tupla (time, values) donde el campo values es un dict de Python ampliado en:

"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 que se use, es posible que se devuelvan varios trabajos/instancias/métricas. Por eso también se usa el dict de Python en la estructura del conjunto de datos.

Tome otra consulta "go_memstats_gc_sys_bytes" como ejemplo. Dado que tanto CoreDNS como Prometheus están escritos en Golang, la métrica "go_memstats_gc_sys_bytes" está disponible tanto para el trabajo "coredns" como para el trabajo "prometheus":

Nota: Esta celda puede generar un error la primera vez que la ejecuta. Ejecútela nuevamente y pasará.

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 Dataset creado ya está listo para pasarse a tf.keras directamente para entrenamiento o inferencia.

Usar el conjunto de datos para el entrenamiento de modelos

Con el conjunto de datos de métricas creado, es posible pasar directamente el conjunto de datos a tf.keras para el entrenamiento o la inferencia del modelo.

Para fines 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 usa es el valor de 'go_memstats_sys_bytes' para CoreDNS con 10 muestras. Sin embargo, dado que se forma una ventana deslizante de window=n_steps y shift=1, se necesitan muestras adicionales (para cualquier dos elementos consecutivos, el primero se toma como x y el segundo como y para el entrenamiento). El total es 10 + n_steps - 1 + 1 = 12 segundos.

El valor de los 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 configuró en este tutorial no tiene ninguna carga de trabajo. Sin embargo, esta es una canalización funcional que podría usarse para cargar métricas desde servidores de producción reales. Luego, el modelo podría mejorarse para resolver un problema del mundo real de la automatización de Devops.