refactor(aula-12): simplificar para helm install direto

Remove indireção GitOps (factory/monitoring repo) que adicionava
complexidade sem valor pedagógico. O foco da aula é observabilidade,
não pipeline de deploy.

Antes: setup.sh → cria repo → push manifests → ArgoCD app → sync → instala
Agora: setup.sh → helm install → pronto

README reescrito com foco em "o que monitorar" (PVC cheio, CrashLoop,
CPU saturada) em vez de "como instalar via GitOps".
This commit is contained in:
ArgoCD Setup
2026-03-14 02:11:10 -03:00
parent e8c793058c
commit 61866c1920
3 changed files with 276 additions and 879 deletions

View File

@@ -1,209 +1,166 @@
# Aula 12 - Victoria Metrics (Observabilidade) # Aula 12 - Observabilidade (Victoria Metrics + Grafana)
Stack completo de monitoramento com Victoria Metrics, Grafana e alertas, instalado via **GitOps com ArgoCD**. Instale monitoramento no cluster e aprenda a **ver o que está acontecendo** — CPU, memória, disco, pods crashando, PVCs enchendo.
## Por que Victoria Metrics? ## Por que esta aula existe
### Alternativa ao Prometheus Nas aulas anteriores construímos um cluster completo: Kubernetes, Gitea, ArgoCD, auto-scaling. Mas se um pod estiver em CrashLoop, um PVC estiver 95% cheio, ou um node estiver com CPU saturada — **como você sabe?**
Victoria Metrics oferece **compatibilidade total** com Prometheus, mas com vantagens: Sem observabilidade, você descobre problemas quando o **usuário reclama**. Com observabilidade, você descobre **antes do usuário**.
| Feature | Prometheus | Victoria Metrics | ## O que instalamos
|---------|------------|------------------|
| Consumo de RAM | Alto | ~7x menor |
| Compressão | Básica | ~10x melhor |
| Velocidade | Normal | ~2-3x mais rápido |
| Setup HA | Complexo (Thanos) | Simples |
| API | PromQL | PromQL + extensões |
### Diferença da Aula-05 ```
helm install monitoring vm/victoria-metrics-k8s-stack
```
| Aula-05 (KEDA) | Aula-12 (Observabilidade) | Um único comando. Sem GitOps intermediário, sem repositório extra, sem pipeline de CI. O foco desta aula é **usar** o monitoramento, não instalar infraestrutura.
|----------------|---------------------------|
| Foco: Auto-scaling | Foco: Monitoramento |
| VM básico (sem Grafana) | VM + Grafana completo |
| Queries para KEDA | Queries para operações |
| Ambiente local | Cluster Hetzner + GitOps |
## Arquitetura ### Componentes
``` ```
┌─────────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────────┐
│ Victoria Metrics Stack │ │ Victoria Metrics Stack │
├─────────────────────────────────────────────────────────────────┤ ├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ vmagent │ │ vmsingle │ │ Grafana │ │ │ vmagent │ │ vmsingle │ │ Grafana │ │
│ │ (coleta) │─│ (storage) │─│ (visualização) │ │ │ (coleta) │─│ (storage) │─│ (visualização) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────────┘ │ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
│ │ │ │ │ │ │ │ │
│ ┌──────┴──────┐ ┌─────┴─────┐ ┌─────┴─────┐ │ ┌──────┴──────┐ ┌─────┴─────┐ ┌─────┴─────┐ │
│ │ node-export │ │ vmalert │ │ Dashboards│ │ │ node-export │ │ vmalert │ │ 20+ dash- │
│ │ kube-state │ │ (alertas) │ │ pré-config│ │ │ kube-state │ │ (alertas) │ │ boards │
│ └─────────────┘ └───────────┘ └───────────┘ │ └─────────────┘ └───────────┘ └───────────┘ │
└─────────────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────────────────┘
``` ```
### Componentes | Componente | O que faz |
|------------|-----------|
| **vmagent** | Scrapes métricas de todos os pods, nodes, services a cada 30s |
| **vmsingle** | Armazena métricas (14 dias de retenção, 10Gi PVC) |
| **vmalert** | Avalia regras de alerta (PVC cheio, pod crashando, CPU alta) |
| **Grafana** | UI com 20+ dashboards pré-configurados |
| **kube-state-metrics** | Expõe estado dos objetos K8s (pods, deployments, PVCs) |
| **node-exporter** | Expõe métricas do SO (CPU, RAM, disco, rede) |
| Componente | Função | ### Por que Victoria Metrics e não Prometheus?
|------------|--------|
| **vmsingle** | Armazena métricas (modo single-node) |
| **vmagent** | Coleta métricas via scrape |
| **vmalert** | Avalia regras e dispara alertas |
| **Grafana** | Interface de visualização |
| **kube-state-metrics** | Métricas de objetos K8s (pods, deployments) |
| **node-exporter** | Métricas de nodes (CPU, RAM, disco) |
## Pré-requisitos Compatível com PromQL, mas mais leve:
- Cluster Kubernetes Hetzner (aula-08) | | Prometheus | Victoria Metrics |
- ArgoCD instalado (aula-11) |---|---|---|
- Gitea com org `factory` (aula-11) | RAM | Alto | ~7x menor |
| Compressão em disco | Básica | ~10x melhor |
| Velocidade de query | Normal | ~2-3x mais rápido |
| HA | Complexo (Thanos) | Simples |
## Estrutura Para um cluster pequeno na Hetzner, Victoria Metrics é a escolha pragmática.
``` ## Instalação
aula-12/
├── README.md # Este arquivo
├── setup.sh # Instalação automatizada
├── cleanup.sh # Remoção via ArgoCD
├── gitops/ # Conteúdo para Gitea
│ └── apps/
│ └── victoria-metrics/
│ ├── Chart.yaml # Helm chart wrapper
│ ├── values.yaml # Configurações do stack
│ └── templates/
│ └── alerts.yaml # VMRule customizado
├── argocd/
│ └── application.yaml # ArgoCD Application CRD
├── alerts/
│ └── vmalert-rules.yaml # Referência (aplicada via gitops/)
└── queries/
└── useful-queries.md # Queries PromQL úteis
```
## Instalação (GitOps)
### 1. Executar Setup
```bash ```bash
cd aula-12 cd aula-12
export KUBECONFIG=$(pwd)/../aula-08/kubeconfig
./setup.sh ./setup.sh
``` ```
O script: O script pergunta:
1. Cria repositório `factory/monitoring` no Gitea 1. Domínio base (herda da aula-10)
2. Faz push dos manifests GitOps 2. Hostname do Grafana (ex: `grafana.kube.quest`)
3. Cria namespace `monitoring` 3. TLS (Let's Encrypt / CloudFlare / HTTP)
4. Aplica ArgoCD Application
5. Aguarda sincronização
### 2. Fluxo GitOps Depois faz `helm install` direto — sem GitOps, sem repos intermediários.
## Acesso ao Grafana
### Via Ingress
``` ```
┌──────────────────┐ push ┌──────────────────┐ URL: https://grafana.kube.quest
│ aula-12/ │ ──────────► │factory/monitoring │ Username: admin
│ gitops/ │ │ (Gitea) │ Password: (exibida no setup.sh)
└──────────────────┘ └────────┬─────────┘
sync │
┌──────────────────┐
│ ArgoCD │
└────────┬─────────┘
apply │
┌──────────────────┐
│ Kubernetes │
│ ns: monitoring │
└──────────────────┘
``` ```
### 3. Verificar Instalação ### Via Port-Forward
```bash ```bash
# Status do ArgoCD Application
kubectl get application monitoring -n argocd
# Pods rodando
kubectl get pods -n monitoring
# Serviços
kubectl get svc -n monitoring
```
## Configuração de DNS
Antes de acessar o Grafana, configure o DNS:
```bash
# Obter IP do Load Balancer
kubectl get svc -n ingress-nginx ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
```
Configure o registro DNS:
- **grafana.kube.quest** → IP do Load Balancer (ex: 49.13.44.102)
## Acessar Grafana
### Via Ingress (Recomendado)
Após configurar o DNS:
- **URL**: https://grafana.kube.quest
- Certificado TLS via Let's Encrypt (automático)
### Credenciais
- **Usuário**: admin
- **Senha**: (gerada automaticamente)
```bash
# Obter senha do Grafana
kubectl get secret monitoring-grafana -n monitoring \
-o jsonpath='{.data.admin-password}' | base64 -d; echo
```
### Via Port-Forward (Alternativa)
Se não tiver DNS configurado:
```bash
# Port-forward Grafana
kubectl port-forward -n monitoring svc/monitoring-grafana 3000:80 kubectl port-forward -n monitoring svc/monitoring-grafana 3000:80
# Acessar
open http://localhost:3000 open http://localhost:3000
``` ```
## Dashboards Incluídos ### Obter senha
O chart `victoria-metrics-k8s-stack` já inclui **20+ dashboards** via Grafana sidecar: ```bash
kubectl get secret -n monitoring -l app.kubernetes.io/name=grafana \
-o jsonpath='{.items[0].data.admin-password}' | base64 -d; echo
```
### Dashboards Principais ## O que monitorar (casos reais)
| Dashboard | Descrição | ### 1. PVC enchendo
|-----------|-----------|
O problema mais comum em clusters pequenos. Um volume Hetzner de 10Gi enche silenciosamente.
```promql
# PVCs acima de 80%
(kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes) > 0.8
```
Dashboard: **Kubernetes / Views / Persistent Volumes**
### 2. Pod em CrashLoop
Quando um pod reinicia repetidamente sem ficar Ready.
```promql
# Pods que restartaram mais de 5x na última hora
sum(increase(kube_pod_container_status_restarts_total[1h])) by (pod, namespace) > 5
```
Dashboard: **Kubernetes / Views / Pods**
### 3. Node com CPU saturada
```promql
# CPU por node (%)
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
```
Dashboard: **Node Exporter / Nodes**
### 4. Memória por namespace
Quem está consumindo mais memória no cluster?
```promql
sum(container_memory_working_set_bytes{container!=""}) by (namespace)
```
Dashboard: **Kubernetes / Views / Namespaces**
### 5. Network throughput
```promql
# Bytes recebidos por pod (rate 5min)
sum(rate(container_network_receive_bytes_total[5m])) by (pod)
```
## Dashboards incluídos
O chart já vem com **20+ dashboards** configurados:
| Dashboard | Uso |
|-----------|-----|
| **Kubernetes / Views / Global** | Visão geral do cluster | | **Kubernetes / Views / Global** | Visão geral do cluster |
| **Kubernetes / Views / Namespaces** | Recursos por namespace | | **Kubernetes / Views / Namespaces** | Recursos por namespace |
| **Kubernetes / Views / Nodes** | CPU, memória, disco por node | | **Kubernetes / Views / Nodes** | CPU, memória, disco por node |
| **Kubernetes / Views / Pods** | Métricas detalhadas de pods | | **Kubernetes / Views / Pods** | Métricas detalhadas de pods |
| **Node Exporter / Nodes** | Métricas de sistema operacional | | **Node Exporter / Nodes** | Métricas do SO |
| **Node Exporter / USE Method / Node** | Utilização, Saturação, Erros | | **Node Exporter / USE Method** | Utilização, Saturação, Erros |
| **VictoriaMetrics / vmagent** | Status da coleta de métricas | | **VictoriaMetrics / vmagent** | Status da coleta |
| **VictoriaMetrics / vmsingle** | Status do storage de métricas | | **VictoriaMetrics / vmsingle** | Status do storage |
### Ver Todos os Dashboards ## Alertas configurados
No Grafana:
1. Menu lateral → **Dashboards**
2. Ou acesse: https://grafana.kube.quest/dashboards
## Alertas Configurados
| Alerta | Condição | Severidade | | Alerta | Condição | Severidade |
|--------|----------|------------| |--------|----------|------------|
@@ -215,274 +172,56 @@ No Grafana:
| NodeLowMemory | RAM livre < 10% | warning | | NodeLowMemory | RAM livre < 10% | warning |
| NodeDiskFull | Disco > 85% | critical | | NodeDiskFull | Disco > 85% | critical |
### Verificar Alertas
```bash ```bash
# Ver alertas ativos # Ver alertas
kubectl get vmrule -n monitoring
# Ver status no VMAlert
kubectl port-forward -n monitoring svc/vmalert 8880:8880 kubectl port-forward -n monitoring svc/vmalert 8880:8880
open http://localhost:8880/alerts open http://localhost:8880/alerts
``` ```
## Queries PromQL Úteis ## Integração com KEDA (Aula-05)
### Uso de Storage Victoria Metrics pode alimentar KEDA para auto-scaling baseado em métricas:
```promql
# Uso de PVC em porcentagem
kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes * 100
# PVCs acima de 80%
(kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes) > 0.8
# Espaço disponível por PVC
kubelet_volume_stats_available_bytes
```
### CPU e Memória
```promql
# CPU por pod (cores)
sum(rate(container_cpu_usage_seconds_total{container!=""}[5m])) by (pod, namespace)
# Memória por namespace
sum(container_memory_working_set_bytes{container!=""}) by (namespace)
# CPU por node (%)
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
```
### Pods e Containers
```promql
# Pods restartando na última hora
sum(increase(kube_pod_container_status_restarts_total[1h])) by (pod, namespace) > 0
# Pods não Ready
kube_pod_status_ready{condition="false"}
# Pods em CrashLoopBackOff
kube_pod_container_status_waiting_reason{reason="CrashLoopBackOff"}
```
### Network
```promql
# Bytes recebidos por pod
sum(rate(container_network_receive_bytes_total[5m])) by (pod)
# Bytes enviados por pod
sum(rate(container_network_transmit_bytes_total[5m])) by (pod)
```
## Integrações
### Com KEDA (Aula-05)
Victoria Metrics pode alimentar KEDA para auto-scaling:
```yaml ```yaml
triggers: triggers:
- type: prometheus - type: prometheus
metadata: metadata:
serverAddress: http://vmsingle-vm.monitoring:8429 serverAddress: http://vmsingle-monitoring-victoria-metrics-k8s-stack.monitoring:8429
query: sum(kube_deployment_status_replicas_unavailable{deployment="myapp"}) query: sum(kube_deployment_status_replicas_unavailable{deployment="myapp"})
threshold: '1' threshold: '1'
``` ```
### Com Alertmanager ## Auto-Resize de PVC (Opcional)
Para notificações (Slack, Email, PagerDuty): Expansão automática de volumes quando atingirem 80%.
```yaml ```bash
# values.yaml helm repo add pvc-autoresizer https://topolvm.github.io/pvc-autoresizer/
vmalert: helm install pvc-autoresizer pvc-autoresizer/pvc-autoresizer \
alertmanager: --namespace pvc-autoresizer \
url: http://alertmanager.monitoring:9093 --create-namespace \
--set controller.args.prometheusURL=http://vmsingle-monitoring-victoria-metrics-k8s-stack.monitoring:8429 \
--set controller.args.noAnnotationCheck=true
# Habilitar no StorageClass
kubectl annotate storageclass hcloud-volumes resize.topolvm.io/enabled="true"
``` ```
Com isso, **todos os PVCs** no cluster são monitorados e expandidos automaticamente.
## Troubleshooting ## Troubleshooting
### Grafana não carrega dashboards ### Grafana não carrega dashboards
```bash ```bash
# Verificar configmap de dashboards
kubectl get configmap -n monitoring | grep dashboard
# Verificar logs do sidecar
kubectl logs -n monitoring -l app.kubernetes.io/name=grafana -c sc-dashboard kubectl logs -n monitoring -l app.kubernetes.io/name=grafana -c sc-dashboard
``` ```
### Métricas não aparecem ### Métricas não aparecem
```bash ```bash
# Verificar targets do vmagent
kubectl port-forward -n monitoring svc/vmagent 8429:8429 kubectl port-forward -n monitoring svc/vmagent 8429:8429
open http://localhost:8429/targets open http://localhost:8429/targets
# Verificar scrape configs
kubectl get configmap -n monitoring vmagent-config -o yaml
```
### VMAlert não dispara alertas
```bash
# Verificar regras carregadas
kubectl port-forward -n monitoring svc/vmalert 8880:8880
open http://localhost:8880/rules
# Verificar logs
kubectl logs -n monitoring -l app=vmalert
```
### ArgoCD mostra OutOfSync
```bash
# Ver diff
argocd app diff monitoring
# Forçar sync
argocd app sync monitoring --prune
```
## Auto-Resize de PVC (Opcional)
Expansão automática de volumes quando atingirem 80% da capacidade.
### Arquitetura
```
┌─────────────────────────────────────────────────────────────────────┐
│ FLUXO DE MÉTRICAS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ kubelet ──────────► vmagent ──────────► vmsingle │
│ (expõe stats (scrape (armazena │
│ do volume) 30s) métricas) │
│ │
│ Métrica: kubelet_volume_stats_used_bytes │
│ Métrica: kubelet_volume_stats_capacity_bytes │
│ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ FLUXO DE RESIZE │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ pvc-autoresizer ───── query ────► vmsingle │
│ │ (consulta % usado) │
│ │ │
│ │ Se usado > 80% (free < 20%): │
│ │ │
│ ▼ │
│ kubectl patch PVC ──────► Kubernetes ──────► Hetzner CSI │
│ (spec.resources. (detecta mudança (expande volume │
│ requests.storage no request) online, sem │
│ += 10Gi) downtime) │
│ │ │
│ ▼ │
│ Pod restart ──────► Filesystem resize ──────► Capacidade OK │
│ │
└─────────────────────────────────────────────────────────────────────┘
```
### Componentes e Responsabilidades
| Componente | Função | Faz resize? |
|------------|--------|-------------|
| **kubelet** | Expõe métricas de volume | ❌ |
| **vmagent** | Coleta métricas (scrape) | ❌ |
| **vmsingle** | Armazena métricas | ❌ |
| **pvc-autoresizer** | Monitora + patch PVC | ✅ |
| **Hetzner CSI** | Expande volume físico | ✅ |
### Pré-requisitos
- StorageClass com `allowVolumeExpansion: true` (já configurado)
- Hetzner CSI Driver (suporta online resize)
- Victoria Metrics coletando métricas do kubelet
### Instalar pvc-autoresizer
```bash
# Adicionar repo Helm
helm repo add pvc-autoresizer https://topolvm.github.io/pvc-autoresizer/
# Instalar com Victoria Metrics + modo automático (sem annotations)
helm install pvc-autoresizer pvc-autoresizer/pvc-autoresizer \
--namespace pvc-autoresizer \
--create-namespace \
--set controller.args.prometheusURL=http://vmsingle-monitoring-victoria-metrics-k8s-stack.monitoring:8429 \
--set controller.args.noAnnotationCheck=true \
--set controller.args.initialResizeGroupByPvc=true
# Habilitar auto-resize no StorageClass
kubectl annotate storageclass hcloud-volumes resize.topolvm.io/enabled="true"
```
### Comportamento Automático
Com `--no-annotation-check`, **todos os PVCs** em StorageClasses com a annotation `resize.topolvm.io/enabled: "true"` são automaticamente monitorados.
**Defaults aplicados:**
- Threshold: 10% livre (expande quando usado > 90%)
- Increase: 10% do tamanho atual
**PVCs futuros** não precisam de annotations - funcionam automaticamente!
### Annotations para Override (Opcional)
Para customizar o comportamento de um PVC específico:
```bash
kubectl annotate pvc <nome-pvc> -n <namespace> \
resize.topolvm.io/storage_limit="10Ti" \
resize.topolvm.io/threshold="20%" \
resize.topolvm.io/increase="10Gi"
```
### Configuração das Annotations (Override)
| Annotation | Valor | Descrição |
|------------|-------|-----------|
| `storage_limit` | `10Ti` | Limite máximo (10TB = max Hetzner) |
| `threshold` | `20%` | Expandir quando free < 20% (usado > 80%) |
| `increase` | `10Gi` | Quanto aumentar por vez |
**Nota:** Sem `storage_limit`, o PVC pode expandir até o máximo do Hetzner (10TB).
### Alerta de Notificação
Quando um PVC é redimensionado, o alerta **PVCAutoResized** é disparado automaticamente (severity: info).
### Verificar Funcionamento
```bash
# Logs do controller
kubectl logs -n pvc-autoresizer deployment/pvc-autoresizer-controller
# Ver PVCs com auto-resize habilitado
kubectl get pvc -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}: {.metadata.annotations.resize\.topolvm\.io/storage_limit}{"\n"}{end}'
```
### Referência
- [pvc-autoresizer GitHub](https://github.com/topolvm/pvc-autoresizer)
---
## Retenção de Dados
Configuração padrão: **14 dias**
Para alterar:
```yaml
# gitops/apps/victoria-metrics/values.yaml
vmsingle:
retentionPeriod: "30d"
``` ```
## Cleanup ## Cleanup
@@ -491,17 +230,11 @@ vmsingle:
./cleanup.sh ./cleanup.sh
``` ```
O script remove: Remove o Helm release e o namespace `monitoring`. Dados de métricas serão perdidos.
1. ArgoCD Application
2. Namespace `monitoring`
3. Repositório Gitea (opcional)
**Nota**: Dados de métricas serão perdidos!
## Referências ## Referências
- [Victoria Metrics Docs](https://docs.victoriametrics.com/) - [Victoria Metrics Docs](https://docs.victoriametrics.com/)
- [victoria-metrics-k8s-stack Chart](https://github.com/VictoriaMetrics/helm-charts/tree/master/charts/victoria-metrics-k8s-stack) - [victoria-metrics-k8s-stack Chart](https://github.com/VictoriaMetrics/helm-charts/tree/master/charts/victoria-metrics-k8s-stack)
- [Grafana Dashboards](https://grafana.com/grafana/dashboards/)
- [PromQL Cheat Sheet](https://promlabs.com/promql-cheat-sheet/) - [PromQL Cheat Sheet](https://promlabs.com/promql-cheat-sheet/)
- [pvc-autoresizer](https://github.com/topolvm/pvc-autoresizer) - Auto-resize de volumes - [pvc-autoresizer](https://github.com/topolvm/pvc-autoresizer)

View File

@@ -1,163 +1,66 @@
#!/bin/bash #!/bin/bash
# ============================================================================= # =============================================================================
# Aula 12 - Cleanup Victoria Metrics # Aula 12 - Cleanup (Remove Victoria Metrics)
# =============================================================================
#
# Remove Victoria Metrics stack via ArgoCD
#
# ============================================================================= # =============================================================================
set -e set -e
# Cores para output
RED='\033[0;31m' RED='\033[0;31m'
GREEN='\033[0;32m' GREEN='\033[0;32m'
YELLOW='\033[1;33m' YELLOW='\033[1;33m'
BLUE='\033[0;34m' BLUE='\033[0;34m'
NC='\033[0m' # No Color CYAN='\033[0;36m'
NC='\033[0m'
# Funções de log
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[OK]${NC} $1"; } log_success() { echo -e "${GREEN}[OK]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Diretório do script
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="${SCRIPT_DIR}/.env"
# Carregar configuração
if [[ -f "$ENV_FILE" ]]; then
source "$ENV_FILE"
fi
echo "" echo ""
echo "==========================================" echo -e "${CYAN}============================================${NC}"
echo " Cleanup Victoria Metrics" echo -e "${CYAN} Cleanup - Aula 12 (Victoria Metrics)${NC}"
echo "==========================================" echo -e "${CYAN}============================================${NC}"
echo "" echo ""
echo "Este script irá remover:"
echo " - ArgoCD Application 'monitoring'"
echo " - Todos os recursos no namespace 'monitoring'"
echo " - Secret do repositório no ArgoCD"
echo ""
echo "ATENÇÃO: Dados de métricas serão PERDIDOS!"
echo ""
read -p "Continuar? [y/N]: " CONFIRM
if [[ "$CONFIRM" != "y" && "$CONFIRM" != "Y" ]]; then log_warn "Isso vai remover:"
log_info "Cancelado pelo usuário" echo " - Victoria Metrics Stack (Helm release)"
echo " - Namespace monitoring (dados de métricas serão perdidos)"
echo " - Arquivo .env"
echo ""
read -p "Continuar? (digite 'sim' para confirmar): " confirm
if [ "$confirm" != "sim" ]; then
log_info "Operação cancelada"
exit 0 exit 0
fi fi
# ============================================================================= echo ""
# REMOVER ARGOCD APPLICATION
# =============================================================================
log_info "Removendo ArgoCD Application..." # Remover Helm release
log_info "Removendo Victoria Metrics Stack..."
if kubectl get application monitoring -n argocd &> /dev/null; then if helm status monitoring -n monitoring &> /dev/null; then
# Remover finalizers para permitir deleção helm uninstall monitoring -n monitoring --wait 2>/dev/null || true
kubectl patch application monitoring -n argocd \ log_success "Helm release removido"
--type json \
--patch='[{"op": "remove", "path": "/metadata/finalizers"}]' 2>/dev/null || true
kubectl delete application monitoring -n argocd --wait=false
log_success "ArgoCD Application removida"
else else
log_info "ArgoCD Application já não existe" log_info "Helm release não encontrado"
fi fi
# Aguardar recursos serem deletados pelo ArgoCD # Remover PVCs
log_info "Aguardando ArgoCD deletar recursos..." log_info "Removendo PVCs..."
sleep 5 kubectl delete pvc --all -n monitoring --wait=false 2>/dev/null || true
# ============================================================================= # Remover namespace
# REMOVER NAMESPACE log_info "Removendo namespace..."
# ============================================================================= kubectl delete namespace monitoring --timeout=60s 2>/dev/null || true
log_success "Namespace removido"
log_info "Removendo namespace 'monitoring'..." # Remover .env
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if kubectl get namespace monitoring &> /dev/null; then if [[ -f "${SCRIPT_DIR}/.env" ]]; then
# Forçar remoção de recursos se necessário rm "${SCRIPT_DIR}/.env"
kubectl delete all --all -n monitoring --timeout=60s 2>/dev/null || true log_info ".env removido"
kubectl delete pvc --all -n monitoring --timeout=60s 2>/dev/null || true
kubectl delete configmap --all -n monitoring --timeout=60s 2>/dev/null || true
kubectl delete secret --all -n monitoring --timeout=60s 2>/dev/null || true
kubectl delete namespace monitoring --timeout=120s 2>/dev/null || {
log_warn "Timeout deletando namespace, forçando..."
kubectl get namespace monitoring -o json | \
jq '.spec.finalizers = []' | \
kubectl replace --raw "/api/v1/namespaces/monitoring/finalize" -f - 2>/dev/null || true
}
log_success "Namespace 'monitoring' removido"
else
log_info "Namespace 'monitoring' já não existe"
fi fi
# =============================================================================
# REMOVER SECRET DO REPOSITÓRIO
# =============================================================================
log_info "Removendo secret do repositório..."
if kubectl get secret factory-monitoring-repo -n argocd &> /dev/null; then
kubectl delete secret factory-monitoring-repo -n argocd
log_success "Secret do repositório removido"
else
log_info "Secret do repositório já não existe"
fi
# =============================================================================
# REMOVER REPOSITÓRIO GITEA (OPCIONAL)
# =============================================================================
if [[ -n "$GITEA_HOST" && -n "$GITEA_TOKEN" ]]; then
echo ""
read -p "Remover repositório 'factory/monitoring' do Gitea? [y/N]: " REMOVE_PROJECT
if [[ "$REMOVE_PROJECT" == "y" || "$REMOVE_PROJECT" == "Y" ]]; then
log_info "Removendo repositório do Gitea..."
DELETE_RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" --request DELETE \
-H "Authorization: token ${GITEA_TOKEN}" \
"https://${GITEA_HOST}/api/v1/repos/factory/monitoring")
if [[ "$DELETE_RESPONSE" == "204" ]]; then
log_success "Repositório removido do Gitea"
else
log_info "Repositório não encontrado no Gitea (HTTP ${DELETE_RESPONSE})"
fi
fi
fi
# =============================================================================
# LIMPAR ARQUIVO .ENV
# =============================================================================
echo "" echo ""
read -p "Remover arquivo de configuração local (.env)? [y/N]: " REMOVE_ENV log_success "Cleanup concluído!"
if [[ "$REMOVE_ENV" == "y" || "$REMOVE_ENV" == "Y" ]]; then
rm -f "$ENV_FILE"
log_success "Arquivo .env removido"
fi
# =============================================================================
# FINALIZAÇÃO
# =============================================================================
echo ""
echo "=========================================="
echo " Cleanup Concluído!"
echo "=========================================="
echo ""
echo "Recursos removidos:"
echo " - ArgoCD Application 'monitoring'"
echo " - Namespace 'monitoring'"
echo " - Secret do repositório no ArgoCD"
echo ""
echo "Para reinstalar:"
echo " ./setup.sh"
echo "" echo ""

View File

@@ -1,40 +1,35 @@
#!/bin/bash #!/bin/bash
# ============================================================================= # =============================================================================
# Aula 12 - Victoria Metrics (Observabilidade via GitOps) # Aula 12 - Victoria Metrics (Observabilidade)
# ============================================================================= # =============================================================================
# #
# Este script instala Victoria Metrics stack usando ArgoCD (GitOps): # Este script instala o stack de monitoramento via Helm:
# 1. Cria projeto 'factory/monitoring' no Gitea # 1. Victoria Metrics (coleta + storage de métricas)
# 2. Push dos manifests GitOps # 2. Grafana (dashboards)
# 3. Cria ArgoCD Application # 3. Alertas pré-configurados
# 4. Victoria Metrics + Grafana são sincronizados automaticamente
# #
# Pré-requisitos: # Pré-requisitos:
# - Cluster Kubernetes (aula-08) # - Cluster Kubernetes (aula-08)
# - ArgoCD instalado (aula-11) # - kubectl e helm instalados
# - Gitea com org 'factory' (aula-10/11)
# #
# ============================================================================= # =============================================================================
set -e set -e
# Cores para output
RED='\033[0;31m' RED='\033[0;31m'
GREEN='\033[0;32m' GREEN='\033[0;32m'
YELLOW='\033[1;33m' YELLOW='\033[1;33m'
BLUE='\033[0;34m' BLUE='\033[0;34m'
NC='\033[0m' # No Color CYAN='\033[0;36m'
NC='\033[0m'
# Funções de log
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[OK]${NC} $1"; } log_success() { echo -e "${GREEN}[OK]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Diretório do script
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="${SCRIPT_DIR}/.env" ENV_FILE="${SCRIPT_DIR}/.env"
GITOPS_DIR="${SCRIPT_DIR}/gitops"
# ============================================================================= # =============================================================================
# VERIFICAR PRÉ-REQUISITOS # VERIFICAR PRÉ-REQUISITOS
@@ -42,42 +37,18 @@ GITOPS_DIR="${SCRIPT_DIR}/gitops"
log_info "Verificando pré-requisitos..." log_info "Verificando pré-requisitos..."
# Verificar kubectl
if ! command -v kubectl &> /dev/null; then if ! command -v kubectl &> /dev/null; then
log_error "kubectl não encontrado. Instale com: brew install kubectl" log_error "kubectl não encontrado"
exit 1 exit 1
fi fi
# Verificar helm
if ! command -v helm &> /dev/null; then if ! command -v helm &> /dev/null; then
log_error "helm não encontrado. Instale com: brew install helm" log_error "helm não encontrado"
exit 1 exit 1
fi fi
# Verificar git
if ! command -v git &> /dev/null; then
log_error "git não encontrado. Instale com: brew install git"
exit 1
fi
# Verificar conexão com cluster
if ! kubectl cluster-info &> /dev/null; then if ! kubectl cluster-info &> /dev/null; then
log_error "Não foi possível conectar ao cluster Kubernetes" log_error "Não foi possível conectar ao cluster"
log_info "Verifique se KUBECONFIG está configurado corretamente"
exit 1
fi
# Verificar se ArgoCD está instalado
if ! kubectl get namespace argocd &> /dev/null; then
log_error "Namespace 'argocd' não encontrado"
log_info "Execute primeiro a aula-11 para instalar o ArgoCD"
exit 1
fi
# Verificar se ArgoCD está rodando
if ! kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server --no-headers 2>/dev/null | grep -q Running; then
log_error "ArgoCD server não está rodando"
log_info "Verifique: kubectl get pods -n argocd"
exit 1 exit 1
fi fi
@@ -87,48 +58,31 @@ log_success "Pré-requisitos verificados"
# CARREGAR CONFIGURAÇÃO # CARREGAR CONFIGURAÇÃO
# ============================================================================= # =============================================================================
# Carregar configuração local (se existir)
if [[ -f "$ENV_FILE" ]]; then if [[ -f "$ENV_FILE" ]]; then
log_info "Carregando configuração local..."
source "$ENV_FILE" source "$ENV_FILE"
fi fi
# Herdar configuração da aula-11 # Herdar domínio da aula-10 ou aula-11
AULA11_ENV="${SCRIPT_DIR}/../aula-11/.env" for ENV_SRC in "${SCRIPT_DIR}/../aula-11/.env" "${SCRIPT_DIR}/../aula-10/.env"; do
if [[ -f "$AULA11_ENV" ]]; then if [[ -f "$ENV_SRC" && -z "$DOMAIN" ]]; then
log_info "Herdando configuração da aula-11..." source "$ENV_SRC"
source "$AULA11_ENV" fi
fi done
# Herdar configuração da aula-10
AULA10_ENV="${SCRIPT_DIR}/../aula-10/.env"
if [[ -f "$AULA10_ENV" ]]; then
log_info "Herdando configuração da aula-10..."
source "$AULA10_ENV"
fi
# ============================================================================= # =============================================================================
# COLETAR CONFIGURAÇÃO # COLETAR CONFIGURAÇÃO
# ============================================================================= # =============================================================================
echo "" echo ""
echo "==========================================" echo -e "${CYAN}═══════════════════════════════════════════════════${NC}"
echo " Configuração Victoria Metrics (GitOps)" echo -e "${CYAN} Victoria Metrics - Observabilidade${NC}"
echo "==========================================" echo -e "${CYAN}═══════════════════════════════════════════════════${NC}"
echo "" echo ""
# Gitea Host
if [[ -z "$GITEA_HOST" ]]; then
read -p "Hostname do Gitea (ex: gitea.kube.quest): " GITEA_HOST
fi
log_info "Gitea: https://${GITEA_HOST}"
# Extrair domínio base
if [[ -z "$DOMAIN" ]]; then if [[ -z "$DOMAIN" ]]; then
DOMAIN=$(echo "$GITEA_HOST" | sed 's/^[^.]*\.//') read -p "Domínio base (ex: kube.quest): " DOMAIN
fi fi
# Grafana Host
if [[ -z "$GRAFANA_HOST" ]]; then if [[ -z "$GRAFANA_HOST" ]]; then
DEFAULT_GRAFANA="grafana.${DOMAIN}" DEFAULT_GRAFANA="grafana.${DOMAIN}"
read -p "Hostname do Grafana [${DEFAULT_GRAFANA}]: " GRAFANA_HOST read -p "Hostname do Grafana [${DEFAULT_GRAFANA}]: " GRAFANA_HOST
@@ -136,334 +90,141 @@ if [[ -z "$GRAFANA_HOST" ]]; then
fi fi
log_info "Grafana: https://${GRAFANA_HOST}" log_info "Grafana: https://${GRAFANA_HOST}"
# Gitea Token (para criar projeto via API) # TLS
if [[ -z "$GITEA_TOKEN" ]]; then
echo ""
echo "Token de acesso Gitea (para criar repositório via API):"
echo " 1. Acesse https://${GITEA_HOST}/user/settings/applications"
echo " 2. Crie um token com permissões de escrita"
echo ""
read -p "Gitea Token: " GITEA_TOKEN
fi
# TLS (herdar da aula-11)
if [[ -z "$USE_CLOUDFLARE" && -z "$USE_LETSENCRYPT" ]]; then if [[ -z "$USE_CLOUDFLARE" && -z "$USE_LETSENCRYPT" ]]; then
echo "" echo ""
echo "Configuração de TLS:" echo "Configuração de TLS:"
echo " 1) CloudFlare (proxy ativo - TLS na borda)" echo " 1) Let's Encrypt (recomendado)"
echo " 2) Let's Encrypt (cert-manager)" echo " 2) CloudFlare (proxy)"
echo " 3) HTTP apenas (desenvolvimento)" echo " 3) HTTP apenas"
read -p "Escolha [1-3]: " TLS_CHOICE read -p "Escolha [1-3]: " TLS_CHOICE
case $TLS_CHOICE in case $TLS_CHOICE in
1) USE_CLOUDFLARE=true; USE_LETSENCRYPT=false ;; 1) USE_CLOUDFLARE=false; USE_LETSENCRYPT=true ;;
2) USE_CLOUDFLARE=false; USE_LETSENCRYPT=true ;; 2) USE_CLOUDFLARE=true; USE_LETSENCRYPT=false ;;
*) USE_CLOUDFLARE=false; USE_LETSENCRYPT=false ;; *) USE_CLOUDFLARE=false; USE_LETSENCRYPT=false ;;
esac esac
fi fi
# Salvar configuração # Salvar
cat > "$ENV_FILE" << EOF cat > "$ENV_FILE" << EOF
# Configuração gerada pelo setup.sh # Configuração gerada pelo setup.sh - $(date)
# $(date)
GITEA_HOST=${GITEA_HOST}
GRAFANA_HOST=${GRAFANA_HOST}
DOMAIN=${DOMAIN} DOMAIN=${DOMAIN}
GRAFANA_HOST=${GRAFANA_HOST}
USE_CLOUDFLARE=${USE_CLOUDFLARE} USE_CLOUDFLARE=${USE_CLOUDFLARE}
USE_LETSENCRYPT=${USE_LETSENCRYPT} USE_LETSENCRYPT=${USE_LETSENCRYPT}
GITEA_TOKEN=${GITEA_TOKEN}
EOF EOF
log_success "Configuração salva em ${ENV_FILE}" log_success "Configuração salva"
# ============================================================================= # =============================================================================
# CRIAR REPOSITÓRIO NO GITEA (VIA API) # PREPARAR VALUES COM HOSTNAME DO GRAFANA
# =============================================================================
log_info "Preparando configuração..."
VALUES_FILE="${SCRIPT_DIR}/gitops/apps/victoria-metrics/values.yaml"
TEMP_VALUES=$(mktemp)
sed "s/grafana\.kube\.quest/${GRAFANA_HOST}/g" "$VALUES_FILE" > "$TEMP_VALUES"
# Ajustar TLS no values
if [[ "$USE_LETSENCRYPT" != "true" ]]; then
# Remover anotação cert-manager se não usa Let's Encrypt
sed -i.bak '/cert-manager.io\/cluster-issuer/d' "$TEMP_VALUES"
rm -f "$TEMP_VALUES.bak"
fi
if [[ "$USE_CLOUDFLARE" == "true" || "$USE_LETSENCRYPT" != "true" ]]; then
# Remover bloco TLS se não usa Let's Encrypt
sed -i.bak '/tls:/,/- grafana/d' "$TEMP_VALUES"
rm -f "$TEMP_VALUES.bak"
fi
# =============================================================================
# INSTALAR VIA HELM
# ============================================================================= # =============================================================================
echo "" echo ""
log_info "=== Criando Repositório no Gitea ===" log_info "=== Instalando Victoria Metrics Stack ==="
# Verificar se org factory existe helm repo add vm https://victoriametrics.github.io/helm-charts/ 2>/dev/null || true
log_info "Verificando organização 'factory'..." helm repo update vm
ORG_RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: token ${GITEA_TOKEN}" \
"https://${GITEA_HOST}/api/v1/orgs/factory")
if [[ "$ORG_RESPONSE" != "200" ]]; then kubectl create namespace monitoring 2>/dev/null || true
log_info "Criando organização 'factory'..."
ORG_CREATE=$(curl -s --request POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
--data '{"username": "factory", "visibility": "limited"}' \
"https://${GITEA_HOST}/api/v1/orgs")
ORG_NAME=$(echo "$ORG_CREATE" | grep -o '"username":"factory"' || true) if helm status monitoring -n monitoring &> /dev/null; then
log_warn "Já instalado. Atualizando..."
if [[ -z "$ORG_NAME" ]]; then HELM_CMD="upgrade"
log_error "Falha ao criar organização 'factory'"
echo "$ORG_CREATE"
exit 1
fi
log_success "Organização 'factory' criada"
else else
log_success "Organização 'factory' já existe" HELM_CMD="install"
fi fi
# Verificar se repositório monitoring existe helm ${HELM_CMD} monitoring vm/victoria-metrics-k8s-stack \
log_info "Verificando repositório 'monitoring'..." --namespace monitoring \
REPO_RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \ -f "$TEMP_VALUES" \
-H "Authorization: token ${GITEA_TOKEN}" \ --wait \
"https://${GITEA_HOST}/api/v1/repos/factory/monitoring") --timeout 10m
if [[ "$REPO_RESPONSE" != "200" ]]; then rm -f "$TEMP_VALUES"
log_info "Criando repositório 'monitoring'..."
REPO_CREATE=$(curl -s --request POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
--data '{"name": "monitoring", "private": false, "auto_init": false}' \
"https://${GITEA_HOST}/api/v1/orgs/factory/repos")
REPO_NAME=$(echo "$REPO_CREATE" | grep -o '"name":"monitoring"' || true) log_success "Victoria Metrics Stack instalado!"
if [[ -z "$REPO_NAME" ]]; then # =============================================================================
log_error "Falha ao criar repositório 'monitoring'" # APLICAR ALERTAS CUSTOMIZADOS
echo "$REPO_CREATE" # =============================================================================
exit 1
fi if [[ -f "${SCRIPT_DIR}/gitops/apps/victoria-metrics/templates/alerts.yaml" ]]; then
log_success "Repositório 'monitoring' criado" echo ""
else log_info "Aplicando alertas customizados..."
log_success "Repositório 'monitoring' já existe" kubectl apply -f "${SCRIPT_DIR}/gitops/apps/victoria-metrics/templates/alerts.yaml" -n monitoring 2>/dev/null || true
log_success "Alertas aplicados"
fi fi
# =============================================================================
# PUSH DOS MANIFESTS GITOPS
# =============================================================================
echo ""
log_info "=== Push dos Manifests GitOps ==="
# Criar diretório temporário para clone
TEMP_DIR=$(mktemp -d)
trap "rm -rf ${TEMP_DIR}" EXIT
cd "${TEMP_DIR}"
# Configurar git
git config --global user.email "argocd@${DOMAIN}" 2>/dev/null || true
git config --global user.name "ArgoCD Setup" 2>/dev/null || true
# Clone do repositório (usando token)
log_info "Clonando repositório..."
GITEA_USER=$(curl -s -H "Authorization: token ${GITEA_TOKEN}" "https://${GITEA_HOST}/api/v1/user" | grep -o '"login":"[^"]*"' | cut -d'"' -f4)
GIT_URL="https://${GITEA_USER}:${GITEA_TOKEN}@${GITEA_HOST}/factory/monitoring.git"
if ! git clone "${GIT_URL}" monitoring 2>/dev/null; then
# Repositório vazio, inicializar
mkdir monitoring
cd monitoring
git init
git remote add origin "${GIT_URL}"
else
cd monitoring
fi
# Copiar arquivos GitOps
log_info "Copiando manifests GitOps..."
cp -r "${GITOPS_DIR}/apps" .
# Configurar values.yaml com hostname do Grafana
log_info "Configurando Grafana hostname..."
if [[ -f "apps/victoria-metrics/values.yaml" ]]; then
sed -i.bak "s/GRAFANA_HOST_PLACEHOLDER/${GRAFANA_HOST}/g" apps/victoria-metrics/values.yaml
rm -f apps/victoria-metrics/values.yaml.bak
fi
# Commit e push
git add -A
if git diff --cached --quiet; then
log_info "Nenhuma mudança para commit"
else
git commit -m "feat: Victoria Metrics stack configuration"
log_info "Pushing para Gitea..."
git push -u origin main 2>/dev/null || git push -u origin master 2>/dev/null || {
# Primeiro push em repo vazio
git push --set-upstream origin main 2>/dev/null || git push --set-upstream origin master
}
log_success "Manifests enviados para Gitea"
fi
cd "${SCRIPT_DIR}"
# =============================================================================
# CRIAR NAMESPACE MONITORING
# =============================================================================
echo ""
log_info "=== Criando Namespace ==="
kubectl create namespace monitoring 2>/dev/null || log_info "Namespace 'monitoring' já existe"
log_success "Namespace 'monitoring' pronto"
# =============================================================================
# CONFIGURAR REPOSITÓRIO NO ARGOCD
# =============================================================================
echo ""
log_info "=== Configurando Repositório no ArgoCD ==="
# Criar secret para o repositório
log_info "Criando secret de acesso ao repositório..."
kubectl apply -f - << EOF
apiVersion: v1
kind: Secret
metadata:
name: factory-monitoring-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://${GITEA_HOST}/factory/monitoring.git
username: ${GITEA_USER}
password: ${GITEA_TOKEN}
EOF
log_success "Repositório configurado no ArgoCD"
# =============================================================================
# CRIAR ARGOCD APPLICATION
# =============================================================================
echo ""
log_info "=== Criando ArgoCD Application ==="
# Construir anotações de Ingress
INGRESS_ANNOTATIONS=""
if [[ "$USE_LETSENCRYPT" == "true" ]]; then
INGRESS_ANNOTATIONS='cert-manager.io/cluster-issuer: letsencrypt-prod'
fi
# Aplicar ArgoCD Application
kubectl apply -f - << EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: monitoring
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://${GITEA_HOST}/factory/monitoring.git
targetRevision: HEAD
path: apps/victoria-metrics
helm:
valueFiles:
- values.yaml
destination:
server: https://kubernetes.default.svc
namespace: monitoring
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
EOF
log_success "ArgoCD Application criada"
# =============================================================================
# AGUARDAR SINCRONIZAÇÃO
# =============================================================================
echo ""
log_info "=== Aguardando Sincronização ==="
log_info "ArgoCD está sincronizando Victoria Metrics stack..."
log_info "Isso pode levar alguns minutos na primeira vez..."
# Aguardar até 5 minutos
for i in {1..60}; do
STATUS=$(kubectl get application monitoring -n argocd -o jsonpath='{.status.sync.status}' 2>/dev/null || echo "Unknown")
HEALTH=$(kubectl get application monitoring -n argocd -o jsonpath='{.status.health.status}' 2>/dev/null || echo "Unknown")
echo -ne "\r Status: ${STATUS} | Health: ${HEALTH} "
if [[ "$STATUS" == "Synced" && "$HEALTH" == "Healthy" ]]; then
echo ""
log_success "Victoria Metrics stack sincronizado e saudável!"
break
fi
if [[ $i -eq 60 ]]; then
echo ""
log_warn "Timeout aguardando sincronização"
log_info "Verifique o status no ArgoCD UI"
fi
sleep 5
done
# ============================================================================= # =============================================================================
# OBTER SENHA DO GRAFANA # OBTER SENHA DO GRAFANA
# ============================================================================= # =============================================================================
echo "" echo ""
log_info "=== Credenciais do Grafana ===" log_info "Obtendo credenciais do Grafana..."
# Aguardar secret ser criado GRAFANA_PASSWORD=""
for i in {1..30}; do for i in {1..30}; do
if kubectl get secret vm-grafana -n monitoring &> /dev/null; then GRAFANA_PASSWORD=$(kubectl get secret -n monitoring -l app.kubernetes.io/name=grafana \
break -o jsonpath='{.items[0].data.admin-password}' 2>/dev/null | base64 -d 2>/dev/null)
fi if [[ -n "$GRAFANA_PASSWORD" ]]; then break; fi
sleep 2 sleep 2
done done
GRAFANA_PASSWORD=$(kubectl get secret vm-grafana -n monitoring -o jsonpath='{.data.admin-password}' 2>/dev/null | base64 -d 2>/dev/null || echo "") # =============================================================================
# RESUMO FINAL
# =============================================================================
if [[ -z "$GRAFANA_PASSWORD" ]]; then PROTOCOL="https"
# Tentar nome alternativo do secret if [[ "$USE_CLOUDFLARE" == "false" && "$USE_LETSENCRYPT" == "false" ]]; then
GRAFANA_PASSWORD=$(kubectl get secret -n monitoring -l app.kubernetes.io/name=grafana -o jsonpath='{.items[0].data.admin-password}' 2>/dev/null | base64 -d 2>/dev/null || echo "admin") PROTOCOL="http"
fi fi
# =============================================================================
# INSTRUÇÕES FINAIS
# =============================================================================
echo "" echo ""
echo "==========================================" echo -e "${CYAN}═══════════════════════════════════════════════════${NC}"
echo " Instalação Concluída!" echo -e "${GREEN} Victoria Metrics Instalado!${NC}"
echo "==========================================" echo -e "${CYAN}═══════════════════════════════════════════════════${NC}"
echo ""
echo "Victoria Metrics Stack instalado via GitOps"
echo "" echo ""
echo "Grafana:" echo "Grafana:"
if [[ "$USE_CLOUDFLARE" == "true" || "$USE_LETSENCRYPT" == "true" ]]; then echo " URL: ${PROTOCOL}://${GRAFANA_HOST}"
echo " URL: https://${GRAFANA_HOST}"
else
echo " URL: http://${GRAFANA_HOST}"
fi
echo " Username: admin" echo " Username: admin"
echo " Password: ${GRAFANA_PASSWORD:-'(ver secret vm-grafana)'}" echo " Password: ${GRAFANA_PASSWORD:-'(kubectl get secret -n monitoring -l app.kubernetes.io/name=grafana -o jsonpath=\"{.items[0].data.admin-password}\" | base64 -d)'}"
echo "" echo ""
echo "Acesso via port-forward:" echo "Acesso alternativo (port-forward):"
echo " kubectl port-forward -n monitoring svc/vm-grafana 3000:80" echo " kubectl port-forward -n monitoring svc/monitoring-grafana 3000:80"
echo " open http://localhost:3000" echo " open http://localhost:3000"
echo "" echo ""
echo "ArgoCD Application:" echo "Verificar:"
echo " kubectl get application monitoring -n argocd"
echo ""
echo "Pods:"
echo " kubectl get pods -n monitoring" echo " kubectl get pods -n monitoring"
echo "" echo ""
echo "GitOps Repository:" echo "Desinstalar:"
echo " https://${GITEA_HOST}/factory/monitoring" echo " ./cleanup.sh"
echo "" echo ""
echo "Verificar métricas:" echo -e "${CYAN}═══════════════════════════════════════════════════${NC}"
echo " kubectl port-forward -n monitoring svc/vmsingle-vm 8429:8429"
echo " curl http://localhost:8429/api/v1/query?query=up"
echo "" echo ""
echo "=========================================="
log_info "Status dos pods:"
kubectl get pods -n monitoring