Visão Geral do Prometheus
O Prometheus é um ecossistema de monitoramento e alerta de código aberto, originalmente desenvolvido pelo SoundCloud. Desde 2016, integra a Cloud Native Computing Foundation (CNCF) como o segundo projeto graduado após o Kubernetes. Sua arquitetura é projetada especificamente para ambientes dinâmicos e microsserviços, destacando-se pelos seguintes pilares:
- Modelo de Dados Multidimensional: Séries temporais identificadas por nomes de métricas e pares chave-valor (labels).
- Linguagem de Consulta Poderosa (PromQL): Permite realizar agregações e cálculos complexos em tempo real.
- Coleta via Pull: O servidor busca métricas via HTTP, eliminando a necessidade de agentes pesados.
- Descoberta de Serviços: Integração nativa com Kubernetes para identificar alvos dinamicamente.
- Armazenamento Eficiente: Banco de dados de séries temporais (TSDB) otimizado para gravação em disco local.
A arquitetura central consiste no Prometheus Server (coleta e armazenamento), Exporters (transforma métricas de terceiros), Pushgateway (para jobs de curta duração) e o Alertmanager (gestão de notificações).
Implementação no Kubernetes
Para gerenciar o Prometheus em um cluster, utilizamos ConfigMaps para as configurações e Deployments para a execução do binário. Abaixo, definimos o arquivo de configuração básico prometheus.yml encapsulado em um recurso Kubernetes:
apiVersion: v1
kind: ConfigMap
metadata:
name: prom-core-config
namespace: monitoring
data:
prometheus.yml: |
global:
scrape_interval: 20s
evaluation_interval: 20s
scrape_configs:
- job_name: 'cluster-monitor'
static_configs:
- targets: ['localhost:9090']
Configuração de RBAC
Como o Prometheus precisa consultar a API do Kubernetes para descobrir recursos (Nodes, Pods, Endpoints), é necessário configurar permissões específicas via ClusterRole:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prom-discovery-role
rules:
- apiGroups: [""]
resources: ["nodes", "nodes/proxy", "services", "endpoints", "pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["extensions", "networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prom-discovery-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prom-discovery-role
subjects:
- kind: ServiceAccount
name: prom-service-account
namespace: monitoring
Deployment e Persistência
Ao implantar o Prometheus, um desafio comum é a permissão de escrita no volume de dados. O uso de securityContext resolve conflitos de propriedade de arquivos quando montamos volumes do host:
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus-server
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: prom-server
template:
metadata:
labels:
app: prom-server
spec:
serviceAccountName: prom-service-account
securityContext:
runAsUser: 0
containers:
- name: prom-container
image: prom/prometheus:v2.35.0
args:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/data/prom"
- "--web.enable-lifecycle"
ports:
- containerPort: 9090
name: api-port
volumeMounts:
- name: config-storage
mountPath: /etc/prometheus
- name: metrics-storage
mountPath: /data/prom
volumes:
- name: config-storage
configMap:
name: prom-core-config
- name: metrics-storage
hostPath:
path: /mnt/prom_data
Monitoramento de Nodes com Node Exporter
Para coletar métricas de hardware (CPU, Memória, Disco) dos nós físicos ou virtuais, utilizamos o node_exporter como um DaemonSet. Isso garante que cada instância do cluster execute um coletor.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-metrics-agent
namespace: monitoring
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
hostNetwork: true
hostPID: true
containers:
- name: exporter
image: prom/node-exporter:latest
ports:
- containerPort: 9100
volumeMounts:
- name: proc-fs
mountPath: /host/proc
readOnly: true
- name: sys-fs
mountPath: /host/sys
readOnly: true
volumes:
- name: proc-fs
hostPath:
path: /proc
- name: sys-fs
hostPath:
path: /sys
Descoberta Automática de Nós
Em vez de listar IPs manualmente, configuramos o Prometheus para usar a kubernetes_sd_configs. Através do relabel_configs, mapeamos a porta padrão de monitoramento do Kubelet para a porta do Node Exporter (9100):
- job_name: 'kubernetes-nodes'
kubernetes_sd_configs:
- role: node
relabel_configs:
- source_labels: [__address__]
regex: '(.*):10250'
replacement: '${1}:9100'
target_label: __address__
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
Monitoramento de Contêineres com cAdvisor
O cAdvisor fornece métricas detalhadas sobre o uso de recursos por contêiner. No Kubernetes, ele já vem integrado ao Kubelet. Para acessar eses dados, configuramos uma tarefa que consulta o proxy da API do nó:
- job_name: 'k8s-container-metrics'
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
- role: node
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- target_label: __metrics_path__
replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
source_labels: [__meta_kubernetes_node_name]
Análise de Dados com PromQL
O PromQL permite transformar dados brutos em inteligência operacional. Entender os tipos de métricas é fundamental:
- Counter: Valores que apenas crescem (ex: total de requisições). Usamos
rate()para calcular a taxa por segundo. - Gauge: Valores que oscilam (ex: uso atual de memória). Usamos
delta()para ver variações em um período. - Histogram/Summary: Utilizados para latência e distribuição de tamanhos (percentis).
Exemplo: Cálculo de Uso de CPU
Para calcular a porcentagem de uso de CPU de um Pod específico, comparamos a taxa de consumo de tempo de CPU com o limite definido (quota):
(
sum(rate(container_cpu_usage_seconds_total{image!="",pod!=""}[2m])) by (pod, namespace)
/
sum(container_spec_cpu_quota{image!="",pod!=""}/100000) by (pod, namespace)
) * 100
Descoberta Baseada em Annotations
Uma prática comum é permitir que os desenvolvedores exponham métricas apenas adicionando anotações nos Services do Kubernetes. O Prometheus pode ser configurado para "ouvir" essas anotações:
- job_name: 'annotated-services'
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
Com essa configuração, qualquer Service que possua prometheus.io/scrape: "true" será automaticamente incluído no pipeline de monitoramento, garantindo escalabilidade e autonomia para as equipes de desenvolvimento.