Files
workshop/aula-12/setup.sh
ArgoCD Setup 4b92838ac3 aula-12: Victoria Metrics + Grafana via GitOps
Stack completo de observabilidade:
- Victoria Metrics (vmsingle, vmagent, vmalert)
- Grafana com dashboards built-in
- Alertas customizados (PVC, pods, nodes, deployments)
- pvc-autoresizer para expansão automática de volumes
- Queries PromQL documentadas

Instalação via ArgoCD seguindo padrão GitOps da aula-11.
2026-01-08 17:11:28 -03:00

468 lines
15 KiB
Bash
Executable File

#!/bin/bash
# =============================================================================
# Aula 12 - Victoria Metrics (Observabilidade via GitOps)
# =============================================================================
#
# Este script instala Victoria Metrics stack usando ArgoCD (GitOps):
# 1. Cria projeto 'factory/monitoring' no GitLab
# 2. Push dos manifests GitOps
# 3. Cria ArgoCD Application
# 4. Victoria Metrics + Grafana são sincronizados automaticamente
#
# Pré-requisitos:
# - Cluster Kubernetes (aula-08)
# - ArgoCD instalado (aula-11)
# - GitLab com grupo 'factory' (aula-10/11)
#
# =============================================================================
set -e
# Cores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Funções de log
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[OK]${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"
GITOPS_DIR="${SCRIPT_DIR}/gitops"
# =============================================================================
# VERIFICAR PRÉ-REQUISITOS
# =============================================================================
log_info "Verificando pré-requisitos..."
# Verificar kubectl
if ! command -v kubectl &> /dev/null; then
log_error "kubectl não encontrado. Instale com: brew install kubectl"
exit 1
fi
# Verificar helm
if ! command -v helm &> /dev/null; then
log_error "helm não encontrado. Instale com: brew install helm"
exit 1
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
log_error "Não foi possível conectar ao cluster Kubernetes"
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
fi
log_success "Pré-requisitos verificados"
# =============================================================================
# CARREGAR CONFIGURAÇÃO
# =============================================================================
# Carregar configuração local (se existir)
if [[ -f "$ENV_FILE" ]]; then
log_info "Carregando configuração local..."
source "$ENV_FILE"
fi
# Herdar configuração da aula-11
AULA11_ENV="${SCRIPT_DIR}/../aula-11/.env"
if [[ -f "$AULA11_ENV" ]]; then
log_info "Herdando configuração da aula-11..."
source "$AULA11_ENV"
fi
# 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
# =============================================================================
echo ""
echo "=========================================="
echo " Configuração Victoria Metrics (GitOps)"
echo "=========================================="
echo ""
# GitLab Host
if [[ -z "$GITLAB_HOST" ]]; then
read -p "Hostname do GitLab (ex: git.kube.quest): " GITLAB_HOST
fi
log_info "GitLab: https://${GITLAB_HOST}"
# Extrair domínio base
if [[ -z "$DOMAIN" ]]; then
DOMAIN=$(echo "$GITLAB_HOST" | sed 's/^[^.]*\.//')
fi
# Grafana Host
if [[ -z "$GRAFANA_HOST" ]]; then
DEFAULT_GRAFANA="grafana.${DOMAIN}"
read -p "Hostname do Grafana [${DEFAULT_GRAFANA}]: " GRAFANA_HOST
GRAFANA_HOST="${GRAFANA_HOST:-$DEFAULT_GRAFANA}"
fi
log_info "Grafana: https://${GRAFANA_HOST}"
# GitLab Token (para criar projeto via API)
if [[ -z "$GITLAB_TOKEN" ]]; then
echo ""
echo "Token de acesso GitLab (para criar projeto via API):"
echo " 1. Acesse https://${GITLAB_HOST}/-/user_settings/personal_access_tokens"
echo " 2. Crie um token com scope 'api'"
echo ""
read -p "GitLab Token: " GITLAB_TOKEN
fi
# TLS (herdar da aula-11)
if [[ -z "$USE_CLOUDFLARE" && -z "$USE_LETSENCRYPT" ]]; then
echo ""
echo "Configuração de TLS:"
echo " 1) CloudFlare (proxy ativo - TLS na borda)"
echo " 2) Let's Encrypt (cert-manager)"
echo " 3) HTTP apenas (desenvolvimento)"
read -p "Escolha [1-3]: " TLS_CHOICE
case $TLS_CHOICE in
1) USE_CLOUDFLARE=true; USE_LETSENCRYPT=false ;;
2) USE_CLOUDFLARE=false; USE_LETSENCRYPT=true ;;
*) USE_CLOUDFLARE=false; USE_LETSENCRYPT=false ;;
esac
fi
# Salvar configuração
cat > "$ENV_FILE" << EOF
# Configuração gerada pelo setup.sh
# $(date)
GITLAB_HOST=${GITLAB_HOST}
GRAFANA_HOST=${GRAFANA_HOST}
DOMAIN=${DOMAIN}
USE_CLOUDFLARE=${USE_CLOUDFLARE}
USE_LETSENCRYPT=${USE_LETSENCRYPT}
GITLAB_TOKEN=${GITLAB_TOKEN}
EOF
log_success "Configuração salva em ${ENV_FILE}"
# =============================================================================
# CRIAR PROJETO NO GITLAB (VIA API)
# =============================================================================
echo ""
log_info "=== Criando Projeto no GitLab ==="
# Verificar se grupo factory existe
log_info "Verificando grupo 'factory'..."
GROUP_RESPONSE=$(curl -s --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
"https://${GITLAB_HOST}/api/v4/groups?search=factory")
GROUP_ID=$(echo "$GROUP_RESPONSE" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
if [[ -z "$GROUP_ID" ]]; then
log_info "Criando grupo 'factory'..."
GROUP_CREATE=$(curl -s --request POST --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
--header "Content-Type: application/json" \
--data '{"name": "factory", "path": "factory", "visibility": "internal"}' \
"https://${GITLAB_HOST}/api/v4/groups")
GROUP_ID=$(echo "$GROUP_CREATE" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
if [[ -z "$GROUP_ID" ]]; then
log_error "Falha ao criar grupo 'factory'"
log_info "Crie manualmente em https://${GITLAB_HOST}/admin/groups/new"
exit 1
fi
log_success "Grupo 'factory' criado (ID: ${GROUP_ID})"
else
log_success "Grupo 'factory' já existe (ID: ${GROUP_ID})"
fi
# Verificar se projeto monitoring existe
log_info "Verificando projeto 'monitoring'..."
PROJECT_RESPONSE=$(curl -s --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
"https://${GITLAB_HOST}/api/v4/projects?search=monitoring")
PROJECT_EXISTS=$(echo "$PROJECT_RESPONSE" | grep -o '"path_with_namespace":"factory/monitoring"' || true)
if [[ -z "$PROJECT_EXISTS" ]]; then
log_info "Criando projeto 'monitoring'..."
PROJECT_CREATE=$(curl -s --request POST --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
--header "Content-Type: application/json" \
--data "{\"name\": \"monitoring\", \"namespace_id\": ${GROUP_ID}, \"visibility\": \"internal\", \"initialize_with_readme\": false}" \
"https://${GITLAB_HOST}/api/v4/projects")
PROJECT_ID=$(echo "$PROJECT_CREATE" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
if [[ -z "$PROJECT_ID" ]]; then
log_error "Falha ao criar projeto 'monitoring'"
echo "$PROJECT_CREATE"
exit 1
fi
log_success "Projeto 'monitoring' criado (ID: ${PROJECT_ID})"
else
log_success "Projeto 'monitoring' já existe"
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..."
GIT_URL="https://oauth2:${GITLAB_TOKEN}@${GITLAB_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 GitLab..."
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 GitLab"
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://${GITLAB_HOST}/factory/monitoring.git
username: oauth2
password: ${GITLAB_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://${GITLAB_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
# =============================================================================
echo ""
log_info "=== Credenciais do Grafana ==="
# Aguardar secret ser criado
for i in {1..30}; do
if kubectl get secret vm-grafana -n monitoring &> /dev/null; then
break
fi
sleep 2
done
GRAFANA_PASSWORD=$(kubectl get secret vm-grafana -n monitoring -o jsonpath='{.data.admin-password}' 2>/dev/null | base64 -d 2>/dev/null || echo "")
if [[ -z "$GRAFANA_PASSWORD" ]]; then
# Tentar nome alternativo do secret
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")
fi
# =============================================================================
# INSTRUÇÕES FINAIS
# =============================================================================
echo ""
echo "=========================================="
echo " Instalação Concluída!"
echo "=========================================="
echo ""
echo "Victoria Metrics Stack instalado via GitOps"
echo ""
echo "Grafana:"
if [[ "$USE_CLOUDFLARE" == "true" || "$USE_LETSENCRYPT" == "true" ]]; then
echo " URL: https://${GRAFANA_HOST}"
else
echo " URL: http://${GRAFANA_HOST}"
fi
echo " Username: admin"
echo " Password: ${GRAFANA_PASSWORD:-'(ver secret vm-grafana)'}"
echo ""
echo "Acesso via port-forward:"
echo " kubectl port-forward -n monitoring svc/vm-grafana 3000:80"
echo " open http://localhost:3000"
echo ""
echo "ArgoCD Application:"
echo " kubectl get application monitoring -n argocd"
echo ""
echo "Pods:"
echo " kubectl get pods -n monitoring"
echo ""
echo "GitOps Repository:"
echo " https://${GITLAB_HOST}/factory/monitoring"
echo ""
echo "Verificar métricas:"
echo " kubectl port-forward -n monitoring svc/vmsingle-vm 8429:8429"
echo " curl http://localhost:8429/api/v1/query?query=up"
echo ""
echo "=========================================="