fix: corrigir tipos de servidor AMD (CPX→CX), autoscaler, stdin e cleanup
- Corrigir tipos Hetzner: CPX não existe, usar CX (Intel shared vCPU) - CX23 (2 vCPU, 4GB) equivalente ao CAX11 - CX33 (4 vCPU, 8GB) equivalente ao CAX21 - CX43 (8 vCPU, 16GB) equivalente ao CAX31 - Corrigir location no autoscaler para amd64 (nbg1→fsn1) - Remover gitlab-pool do autoscaler (substituído pelo Gitea) - Aumentar worker-pool max para 30 - Corrigir Floating IP e Load Balancer hardcoded em nbg1 - Corrigir stdin em read interativo: usar < /dev/tty e read -p - Corrigir cleanup de namespace: lidar com Terminating e finalizers - Corrigir CNPG: nome do deployment, secret e endpointURL duplo - Aulas afetadas: 08, 09, 10, 11, 12, 14, 17
This commit is contained in:
+1
-1
@@ -47,7 +47,7 @@ if [ -f "kubeconfig" ]; then
|
|||||||
# Detectar arch dos nodes para filtrar instance type correto
|
# Detectar arch dos nodes para filtrar instance type correto
|
||||||
NODE_ARCH=$(kubectl get nodes -o jsonpath='{.items[0].metadata.labels.kubernetes\.io/arch}' 2>/dev/null || echo "arm64")
|
NODE_ARCH=$(kubectl get nodes -o jsonpath='{.items[0].metadata.labels.kubernetes\.io/arch}' 2>/dev/null || echo "arm64")
|
||||||
if [[ "$NODE_ARCH" == "amd64" ]]; then
|
if [[ "$NODE_ARCH" == "amd64" ]]; then
|
||||||
INSTANCE_PATTERN="cpx"
|
INSTANCE_PATTERN="cx"
|
||||||
else
|
else
|
||||||
INSTANCE_PATTERN="cax"
|
INSTANCE_PATTERN="cax"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -128,10 +128,7 @@ spec:
|
|||||||
# POOLS DE NODES:
|
# POOLS DE NODES:
|
||||||
#
|
#
|
||||||
# worker-pool: Workloads gerais (CAX21 = 4 vCPU, 8GB)
|
# worker-pool: Workloads gerais (CAX21 = 4 vCPU, 8GB)
|
||||||
- --nodes=1:3:CAX21:nbg1:worker-pool
|
- --nodes=1:30:CAX21:nbg1:worker-pool
|
||||||
#
|
|
||||||
# gitlab-pool: Gitea e serviços pesados (CAX21)
|
|
||||||
- --nodes=1:2:CAX21:nbg1:gitlab-pool
|
|
||||||
#
|
#
|
||||||
# build-pool: Builds Docker (CAX31 = 8 vCPU, 16GB)
|
# build-pool: Builds Docker (CAX31 = 8 vCPU, 16GB)
|
||||||
# Escala 0-1 sob demanda, taint "dedicated=builds:NoSchedule"
|
# Escala 0-1 sob demanda, taint "dedicated=builds:NoSchedule"
|
||||||
|
|||||||
+4
-4
@@ -38,14 +38,14 @@ locals {
|
|||||||
# Endpoint: LoadBalancer IP if enabled, otherwise Floating IP
|
# Endpoint: LoadBalancer IP if enabled, otherwise Floating IP
|
||||||
cluster_endpoint_ip = var.enable_loadbalancer ? hcloud_load_balancer.cluster[0].ipv4 : hcloud_floating_ip.control_plane[0].ip_address
|
cluster_endpoint_ip = var.enable_loadbalancer ? hcloud_load_balancer.cluster[0].ipv4 : hcloud_floating_ip.control_plane[0].ip_address
|
||||||
|
|
||||||
# Arquitetura: mapeia arm64→CAX (Nuremberg) ou amd64→CPX (Frankfurt)
|
# Arquitetura: mapeia arm64→CAX (Nuremberg) ou amd64→CX (Frankfurt)
|
||||||
arch_config = {
|
arch_config = {
|
||||||
arm64 = {
|
arm64 = {
|
||||||
server_type_cp = "cax11"
|
server_type_cp = "cax11"
|
||||||
location = "nbg1"
|
location = "nbg1"
|
||||||
}
|
}
|
||||||
amd64 = {
|
amd64 = {
|
||||||
server_type_cp = "cpx21"
|
server_type_cp = "cx23"
|
||||||
location = "fsn1"
|
location = "fsn1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ resource "hcloud_floating_ip" "control_plane" {
|
|||||||
count = var.enable_loadbalancer ? 0 : 1
|
count = var.enable_loadbalancer ? 0 : 1
|
||||||
type = "ipv4"
|
type = "ipv4"
|
||||||
name = "${local.cluster_name}-cp-ip"
|
name = "${local.cluster_name}-cp-ip"
|
||||||
home_location = "nbg1"
|
home_location = local.selected_arch.location
|
||||||
labels = local.common_labels
|
labels = local.common_labels
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +265,7 @@ resource "hcloud_load_balancer" "cluster" {
|
|||||||
count = var.enable_loadbalancer ? 1 : 0
|
count = var.enable_loadbalancer ? 1 : 0
|
||||||
name = "${local.cluster_name}-lb"
|
name = "${local.cluster_name}-lb"
|
||||||
load_balancer_type = "lb11"
|
load_balancer_type = "lb11"
|
||||||
location = "nbg1"
|
location = local.selected_arch.location
|
||||||
labels = local.common_labels
|
labels = local.common_labels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -240,13 +240,13 @@ if [ "$SKIP_CREDENTIALS" != "true" ]; then
|
|||||||
echo "6. Arquitetura dos nodes"
|
echo "6. Arquitetura dos nodes"
|
||||||
echo ""
|
echo ""
|
||||||
echo " arm64 (CAX) - Ampere Altra, melhor custo/benefício"
|
echo " arm64 (CAX) - Ampere Altra, melhor custo/benefício"
|
||||||
echo " amd64 (CPX) - AMD EPYC, mais disponível"
|
echo " amd64 (CX) - Intel, mais disponível"
|
||||||
echo ""
|
echo ""
|
||||||
read -p " Arquitetura? (arm64/amd64) [arm64]: " arch_input
|
read -p " Arquitetura? (arm64/amd64) [arm64]: " arch_input
|
||||||
ARCH="${arch_input:-arm64}"
|
ARCH="${arch_input:-arm64}"
|
||||||
|
|
||||||
if [[ "$ARCH" == "amd64" ]]; then
|
if [[ "$ARCH" == "amd64" ]]; then
|
||||||
log_success "AMD64 selecionado (CPX em fsn1)"
|
log_success "AMD64 selecionado (CX em fsn1)"
|
||||||
else
|
else
|
||||||
log_success "ARM64 selecionado (CAX em nbg1)"
|
log_success "ARM64 selecionado (CAX em nbg1)"
|
||||||
ARCH="arm64"
|
ARCH="arm64"
|
||||||
@@ -317,8 +317,8 @@ ENABLE_LB_CONFIG=$(grep 'enable_loadbalancer' terraform.tfvars 2>/dev/null | gre
|
|||||||
# Custos estimados baseado na arquitetura selecionada
|
# Custos estimados baseado na arquitetura selecionada
|
||||||
ARCH_CONFIG=$(grep 'arch' terraform.tfvars 2>/dev/null | grep -o 'arm64\|amd64' || echo "arm64")
|
ARCH_CONFIG=$(grep 'arch' terraform.tfvars 2>/dev/null | grep -o 'arm64\|amd64' || echo "arm64")
|
||||||
if [[ "$ARCH_CONFIG" == "amd64" ]]; then
|
if [[ "$ARCH_CONFIG" == "amd64" ]]; then
|
||||||
NODE_TYPE="CPX21"
|
NODE_TYPE="CX23"
|
||||||
NODE_COST="\$6.99"
|
NODE_COST="\$4.99"
|
||||||
else
|
else
|
||||||
NODE_TYPE="CAX11"
|
NODE_TYPE="CAX11"
|
||||||
NODE_COST="\$4.59"
|
NODE_COST="\$4.59"
|
||||||
@@ -575,13 +575,13 @@ log_info "Aplicando manifesto do cluster-autoscaler..."
|
|||||||
# Ajustar server_types do autoscaler conforme arquitetura
|
# Ajustar server_types do autoscaler conforme arquitetura
|
||||||
if [[ "$ARCH" == "amd64" ]]; then
|
if [[ "$ARCH" == "amd64" ]]; then
|
||||||
AUTOSCALER_FILE="${SCRIPT_DIR}/cluster-autoscaler.yaml"
|
AUTOSCALER_FILE="${SCRIPT_DIR}/cluster-autoscaler.yaml"
|
||||||
# CPX equivalentes: CAX21→CPX31, CAX31→CPX41, CAX11→CPX21
|
# CX equivalentes: CAX21→CX33, CAX31→CX43, CAX11→CX23
|
||||||
cat "$AUTOSCALER_FILE" | \
|
cat "$AUTOSCALER_FILE" | \
|
||||||
sed "s|\${TALOS_IMAGE_ID}|$TALOS_IMAGE_ID|g" | \
|
sed "s|\${TALOS_IMAGE_ID}|$TALOS_IMAGE_ID|g" | \
|
||||||
sed "s|\${NETWORK_NAME}|$CLUSTER_NAME-network|g" | \
|
sed "s|\${NETWORK_NAME}|$CLUSTER_NAME-network|g" | \
|
||||||
sed "s|\${FIREWALL_NAME}|$CLUSTER_NAME-firewall|g" | \
|
sed "s|\${FIREWALL_NAME}|$CLUSTER_NAME-firewall|g" | \
|
||||||
sed "s|\${SSH_KEY_NAME}|$SSH_KEY_NAME|g" | \
|
sed "s|\${SSH_KEY_NAME}|$SSH_KEY_NAME|g" | \
|
||||||
sed -e 's/CAX21/CPX31/g' -e 's/CAX31/CPX41/g' -e 's/CAX11/CPX21/g' | \
|
sed -e 's/CAX21/CX33/g' -e 's/CAX31/CX43/g' -e 's/CAX11/CX23/g' -e 's/:nbg1:/:fsn1:/g' | \
|
||||||
kubectl apply -f -
|
kubectl apply -f -
|
||||||
else
|
else
|
||||||
cat cluster-autoscaler.yaml | \
|
cat cluster-autoscaler.yaml | \
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ talos_image_id = 123456789
|
|||||||
# Ambiente (prod, staging, dev)
|
# Ambiente (prod, staging, dev)
|
||||||
environment = "workshop"
|
environment = "workshop"
|
||||||
|
|
||||||
# Arquitetura dos nodes: arm64 (CAX) ou amd64 (CPX)
|
# Arquitetura dos nodes: arm64 (CAX) ou amd64 (CX)
|
||||||
# arm64 = CAX11/21/31 em Nuremberg (nbg1) - melhor custo
|
# arm64 = CAX11/21/31 em Nuremberg (nbg1) - melhor custo
|
||||||
# amd64 = CPX21/31/41 em Frankfurt (fsn1) - mais disponível
|
# amd64 = CX23/33/43 em Frankfurt (fsn1) - mais disponível
|
||||||
# arch = "arm64"
|
# arch = "arm64"
|
||||||
|
|
||||||
# Versão do Talos OS (opcional - default: v1.11.2)
|
# Versão do Talos OS (opcional - default: v1.11.2)
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ variable "talos_version" {
|
|||||||
|
|
||||||
variable "arch" {
|
variable "arch" {
|
||||||
type = string
|
type = string
|
||||||
description = "Arquitetura dos nodes: arm64 (CAX - Ampere Altra, melhor custo) ou amd64 (CPX - AMD EPYC, mais disponível)"
|
description = "Arquitetura dos nodes: arm64 (CAX - Ampere Altra, melhor custo) ou amd64 (CX - Intel, mais disponível)"
|
||||||
default = "arm64"
|
default = "arm64"
|
||||||
|
|
||||||
validation {
|
validation {
|
||||||
|
|||||||
+6
-12
@@ -99,8 +99,7 @@ collect_user_input() {
|
|||||||
echo -e "Deseja usar esta configuração?"
|
echo -e "Deseja usar esta configuração?"
|
||||||
echo -e " 1) Sim, continuar com a configuração existente"
|
echo -e " 1) Sim, continuar com a configuração existente"
|
||||||
echo -e " 2) Não, reconfigurar"
|
echo -e " 2) Não, reconfigurar"
|
||||||
echo -n "Escolha [1/2]: "
|
read -r -p "Escolha [1/2]: " choice < /dev/tty
|
||||||
read -r choice
|
|
||||||
if [[ "$choice" == "1" ]]; then
|
if [[ "$choice" == "1" ]]; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@@ -108,8 +107,7 @@ collect_user_input() {
|
|||||||
|
|
||||||
# Coletar hostname completo
|
# Coletar hostname completo
|
||||||
echo ""
|
echo ""
|
||||||
echo -n "Digite o hostname do n8n (ex: n8n.kube.quest): "
|
read -r -p "Digite o hostname do n8n (ex: n8n.kube.quest): " N8N_HOST < /dev/tty
|
||||||
read -r N8N_HOST
|
|
||||||
|
|
||||||
if [[ -z "$N8N_HOST" ]]; then
|
if [[ -z "$N8N_HOST" ]]; then
|
||||||
log_error "Hostname não pode ser vazio"
|
log_error "Hostname não pode ser vazio"
|
||||||
@@ -124,8 +122,7 @@ collect_user_input() {
|
|||||||
echo "Você usa CloudFlare para DNS?"
|
echo "Você usa CloudFlare para DNS?"
|
||||||
echo " 1) Sim (com proxy/CDN ativado - ícone laranja)"
|
echo " 1) Sim (com proxy/CDN ativado - ícone laranja)"
|
||||||
echo " 2) Não"
|
echo " 2) Não"
|
||||||
echo -n "Escolha [1/2]: "
|
read -r -p "Escolha [1/2]: " choice < /dev/tty
|
||||||
read -r choice
|
|
||||||
|
|
||||||
if [[ "$choice" == "1" ]]; then
|
if [[ "$choice" == "1" ]]; then
|
||||||
USE_CLOUDFLARE=true
|
USE_CLOUDFLARE=true
|
||||||
@@ -139,14 +136,12 @@ collect_user_input() {
|
|||||||
echo "Deseja ativar HTTPS com Let's Encrypt?"
|
echo "Deseja ativar HTTPS com Let's Encrypt?"
|
||||||
echo " 1) Sim (recomendado para produção)"
|
echo " 1) Sim (recomendado para produção)"
|
||||||
echo " 2) Não (apenas HTTP)"
|
echo " 2) Não (apenas HTTP)"
|
||||||
echo -n "Escolha [1/2]: "
|
read -r -p "Escolha [1/2]: " choice < /dev/tty
|
||||||
read -r choice
|
|
||||||
|
|
||||||
if [[ "$choice" == "1" ]]; then
|
if [[ "$choice" == "1" ]]; then
|
||||||
USE_LETSENCRYPT=true
|
USE_LETSENCRYPT=true
|
||||||
echo ""
|
echo ""
|
||||||
echo -n "Digite seu email para Let's Encrypt: "
|
read -r -p "Digite seu email para Let's Encrypt: " LETSENCRYPT_EMAIL < /dev/tty
|
||||||
read -r LETSENCRYPT_EMAIL
|
|
||||||
|
|
||||||
if [[ -z "$LETSENCRYPT_EMAIL" ]]; then
|
if [[ -z "$LETSENCRYPT_EMAIL" ]]; then
|
||||||
log_error "Email é obrigatório para Let's Encrypt"
|
log_error "Email é obrigatório para Let's Encrypt"
|
||||||
@@ -349,8 +344,7 @@ if [[ "$USE_LETSENCRYPT" == "true" ]]; then
|
|||||||
echo -e "${YELLOW} O Let's Encrypt precisa do DNS configurado para emitir o certificado.${NC}"
|
echo -e "${YELLOW} O Let's Encrypt precisa do DNS configurado para emitir o certificado.${NC}"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
echo -n "Pressione ENTER quando o DNS estiver configurado..."
|
read -p "Pressione ENTER quando o DNS estiver configurado..." -r
|
||||||
read -r
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
|||||||
+7
-14
@@ -105,8 +105,7 @@ collect_user_input() {
|
|||||||
echo -e "Deseja usar esta configuração?"
|
echo -e "Deseja usar esta configuração?"
|
||||||
echo -e " 1) Sim, continuar com a configuração existente"
|
echo -e " 1) Sim, continuar com a configuração existente"
|
||||||
echo -e " 2) Não, reconfigurar"
|
echo -e " 2) Não, reconfigurar"
|
||||||
echo -n "Escolha [1/2]: "
|
read -r -p "Escolha [1/2]: " choice < /dev/tty
|
||||||
read -r choice
|
|
||||||
if [[ "$choice" == "1" ]]; then
|
if [[ "$choice" == "1" ]]; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@@ -114,8 +113,7 @@ collect_user_input() {
|
|||||||
|
|
||||||
# Coletar hostname
|
# Coletar hostname
|
||||||
echo ""
|
echo ""
|
||||||
echo -n "Digite o hostname do Gitea (ex: git.kube.quest): "
|
read -r -p "Digite o hostname do Gitea (ex: git.kube.quest): " GITEA_HOST < /dev/tty
|
||||||
read -r GITEA_HOST
|
|
||||||
|
|
||||||
if [[ -z "$GITEA_HOST" ]]; then
|
if [[ -z "$GITEA_HOST" ]]; then
|
||||||
log_error "Hostname não pode ser vazio"
|
log_error "Hostname não pode ser vazio"
|
||||||
@@ -134,8 +132,7 @@ collect_user_input() {
|
|||||||
echo -e "Deseja usar esta configuração de TLS?"
|
echo -e "Deseja usar esta configuração de TLS?"
|
||||||
echo -e " 1) Sim"
|
echo -e " 1) Sim"
|
||||||
echo -e " 2) Não, reconfigurar"
|
echo -e " 2) Não, reconfigurar"
|
||||||
echo -n "Escolha [1/2]: "
|
read -r -p "Escolha [1/2]: " choice < /dev/tty
|
||||||
read -r choice
|
|
||||||
if [[ "$choice" == "1" ]]; then
|
if [[ "$choice" == "1" ]]; then
|
||||||
save_config
|
save_config
|
||||||
return 0
|
return 0
|
||||||
@@ -147,8 +144,7 @@ collect_user_input() {
|
|||||||
echo "Você usa CloudFlare para DNS?"
|
echo "Você usa CloudFlare para DNS?"
|
||||||
echo " 1) Sim (com proxy/CDN ativado - ícone laranja)"
|
echo " 1) Sim (com proxy/CDN ativado - ícone laranja)"
|
||||||
echo " 2) Não"
|
echo " 2) Não"
|
||||||
echo -n "Escolha [1/2]: "
|
read -r -p "Escolha [1/2]: " choice < /dev/tty
|
||||||
read -r choice
|
|
||||||
|
|
||||||
if [[ "$choice" == "1" ]]; then
|
if [[ "$choice" == "1" ]]; then
|
||||||
USE_CLOUDFLARE=true
|
USE_CLOUDFLARE=true
|
||||||
@@ -161,14 +157,12 @@ collect_user_input() {
|
|||||||
echo "Deseja ativar HTTPS com Let's Encrypt?"
|
echo "Deseja ativar HTTPS com Let's Encrypt?"
|
||||||
echo " 1) Sim (recomendado para produção)"
|
echo " 1) Sim (recomendado para produção)"
|
||||||
echo " 2) Não (apenas HTTP)"
|
echo " 2) Não (apenas HTTP)"
|
||||||
echo -n "Escolha [1/2]: "
|
read -r -p "Escolha [1/2]: " choice < /dev/tty
|
||||||
read -r choice
|
|
||||||
|
|
||||||
if [[ "$choice" == "1" ]]; then
|
if [[ "$choice" == "1" ]]; then
|
||||||
USE_LETSENCRYPT=true
|
USE_LETSENCRYPT=true
|
||||||
echo ""
|
echo ""
|
||||||
echo -n "Digite seu email para Let's Encrypt: "
|
read -r -p "Digite seu email para Let's Encrypt: " LETSENCRYPT_EMAIL < /dev/tty
|
||||||
read -r LETSENCRYPT_EMAIL
|
|
||||||
|
|
||||||
if [[ -z "$LETSENCRYPT_EMAIL" ]]; then
|
if [[ -z "$LETSENCRYPT_EMAIL" ]]; then
|
||||||
log_error "Email é obrigatório para Let's Encrypt"
|
log_error "Email é obrigatório para Let's Encrypt"
|
||||||
@@ -340,8 +334,7 @@ if [[ "$USE_LETSENCRYPT" == "true" ]]; then
|
|||||||
echo -e "${YELLOW} O Let's Encrypt precisa do DNS configurado para emitir o certificado.${NC}"
|
echo -e "${YELLOW} O Let's Encrypt precisa do DNS configurado para emitir o certificado.${NC}"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
echo -n "Pressione ENTER quando o DNS estiver configurado..."
|
read -r -p "Pressione ENTER quando o DNS estiver configurado..." < /dev/tty
|
||||||
read -r
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -42,7 +42,13 @@ fi
|
|||||||
|
|
||||||
# Remover namespace argocd
|
# Remover namespace argocd
|
||||||
log_info "Removendo namespace argocd..."
|
log_info "Removendo namespace argocd..."
|
||||||
kubectl delete namespace argocd --timeout=60s 2>/dev/null || true
|
kubectl delete namespace argocd --timeout=120s 2>/dev/null || {
|
||||||
|
log_warn "Namespace preso em Terminating, forçando remoção..."
|
||||||
|
kubectl get namespace argocd -o json | \
|
||||||
|
python3 -c "import sys,json; d=json.load(sys.stdin); d['metadata'].pop('finalizers',None); json.dump(d,sys.stdout)" | \
|
||||||
|
kubectl replace --raw /api/v1/namespaces/argocd/finalize -f - 2>/dev/null || true
|
||||||
|
kubectl wait --for=delete namespace argocd --timeout=60s 2>/dev/null || sleep 5
|
||||||
|
}
|
||||||
|
|
||||||
# Limpar secrets residuais
|
# Limpar secrets residuais
|
||||||
log_info "Limpando secrets residuais..."
|
log_info "Limpando secrets residuais..."
|
||||||
|
|||||||
+11
-1
@@ -236,7 +236,17 @@ log_info "=== Instalando ArgoCD ==="
|
|||||||
helm repo add argo https://argoproj.github.io/argo-helm 2>/dev/null || true
|
helm repo add argo https://argoproj.github.io/argo-helm 2>/dev/null || true
|
||||||
helm repo update
|
helm repo update
|
||||||
|
|
||||||
kubectl create namespace argocd 2>/dev/null || true
|
if kubectl get namespace argocd &>/dev/null; then
|
||||||
|
NS_PHASE=$(kubectl get namespace argocd -o jsonpath='{.status.phase}' 2>/dev/null)
|
||||||
|
if [[ "$NS_PHASE" == "Terminating" ]]; then
|
||||||
|
log_info "Namespace argocd em Terminating, forçando remoção..."
|
||||||
|
kubectl get namespace argocd -o json | \
|
||||||
|
python3 -c "import sys,json; d=json.load(sys.stdin); d['metadata'].pop('finalizers',None); json.dump(d,sys.stdout)" | \
|
||||||
|
kubectl replace --raw /api/v1/namespaces/argocd/finalize -f - 2>/dev/null || true
|
||||||
|
kubectl wait --for=delete namespace argocd --timeout=60s 2>/dev/null || sleep 5
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
kubectl create namespace argocd --dry-run=client -o yaml | kubectl apply -f -
|
||||||
|
|
||||||
if helm status argocd -n argocd &> /dev/null; then
|
if helm status argocd -n argocd &> /dev/null; then
|
||||||
log_warn "ArgoCD já instalado, fazendo upgrade..."
|
log_warn "ArgoCD já instalado, fazendo upgrade..."
|
||||||
|
|||||||
+22
-2
@@ -39,19 +39,39 @@ echo ""
|
|||||||
# Remover Helm release
|
# Remover Helm release
|
||||||
log_info "Removendo Victoria Metrics Stack..."
|
log_info "Removendo Victoria Metrics Stack..."
|
||||||
if helm status monitoring -n monitoring &> /dev/null; then
|
if helm status monitoring -n monitoring &> /dev/null; then
|
||||||
helm uninstall monitoring -n monitoring --wait 2>/dev/null || true
|
helm uninstall monitoring -n monitoring --wait --timeout=120s 2>/dev/null || {
|
||||||
|
log_warn "Helm uninstall falhou, removendo com --no-hooks..."
|
||||||
|
helm uninstall monitoring -n monitoring --no-hooks 2>/dev/null || true
|
||||||
|
}
|
||||||
log_success "Helm release removido"
|
log_success "Helm release removido"
|
||||||
else
|
else
|
||||||
log_info "Helm release não encontrado"
|
log_info "Helm release não encontrado"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Remover finalizers de CRDs do Victoria Metrics (podem prender o namespace)
|
||||||
|
log_info "Limpando finalizers de CRDs..."
|
||||||
|
for crd in vmagents vmalerts vmsingles vmclusters vmnodes vmrules vmauths; do
|
||||||
|
for resource in $(kubectl get $crd.operator.victoriametrics.com -n monitoring -o name 2>/dev/null); do
|
||||||
|
kubectl patch "$resource" -n monitoring --type=json \
|
||||||
|
-p='[{"op":"remove","path":"/metadata/finalizers"}]' 2>/dev/null || true
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
# Remover PVCs
|
# Remover PVCs
|
||||||
log_info "Removendo PVCs..."
|
log_info "Removendo PVCs..."
|
||||||
kubectl delete pvc --all -n monitoring --wait=false 2>/dev/null || true
|
kubectl delete pvc --all -n monitoring --wait=false 2>/dev/null || true
|
||||||
|
|
||||||
# Remover namespace
|
# Remover namespace
|
||||||
log_info "Removendo namespace..."
|
log_info "Removendo namespace..."
|
||||||
kubectl delete namespace monitoring --timeout=60s 2>/dev/null || true
|
if kubectl get namespace monitoring &>/dev/null; then
|
||||||
|
kubectl delete namespace monitoring --timeout=120s 2>/dev/null || {
|
||||||
|
log_warn "Namespace preso em Terminating, forçando remoção..."
|
||||||
|
kubectl get namespace monitoring -o json | \
|
||||||
|
python3 -c "import sys,json; d=json.load(sys.stdin); d['metadata'].pop('finalizers',None); json.dump(d,sys.stdout)" | \
|
||||||
|
kubectl replace --raw /api/v1/namespaces/monitoring/finalize -f - 2>/dev/null || true
|
||||||
|
kubectl wait --for=delete namespace monitoring --timeout=60s 2>/dev/null || sleep 5
|
||||||
|
}
|
||||||
|
fi
|
||||||
log_success "Namespace removido"
|
log_success "Namespace removido"
|
||||||
|
|
||||||
# Remover .env
|
# Remover .env
|
||||||
|
|||||||
+21
-1
@@ -184,7 +184,27 @@ log_info "=== Instalando Victoria Metrics Stack ==="
|
|||||||
helm repo add vm https://victoriametrics.github.io/helm-charts/ 2>/dev/null || true
|
helm repo add vm https://victoriametrics.github.io/helm-charts/ 2>/dev/null || true
|
||||||
helm repo update vm
|
helm repo update vm
|
||||||
|
|
||||||
kubectl create namespace monitoring 2>/dev/null || true
|
# Garantir namespace limpo
|
||||||
|
if kubectl get namespace monitoring &>/dev/null; then
|
||||||
|
NS_PHASE=$(kubectl get namespace monitoring -o jsonpath='{.status.phase}' 2>/dev/null)
|
||||||
|
if [[ "$NS_PHASE" == "Terminating" ]]; then
|
||||||
|
log_info "Namespace monitoring em Terminating, limpando finalizers..."
|
||||||
|
# Remover finalizers de CRDs do Victoria Metrics que prendem o namespace
|
||||||
|
for crd in vmagents vmalerts vmsingles vmclusters vmnodes vmrules vmauths; do
|
||||||
|
for resource in $(kubectl get $crd.operator.victoriametrics.com -n monitoring -o name 2>/dev/null); do
|
||||||
|
kubectl patch "$resource" -n monitoring --type=json \
|
||||||
|
-p='[{"op":"remove","path":"/metadata/finalizers"}]' 2>/dev/null || true
|
||||||
|
done
|
||||||
|
done
|
||||||
|
kubectl wait --for=delete namespace monitoring --timeout=60s 2>/dev/null || {
|
||||||
|
kubectl get namespace monitoring -o json | \
|
||||||
|
python3 -c "import sys,json; d=json.load(sys.stdin); d['metadata'].pop('finalizers',None); json.dump(d,sys.stdout)" | \
|
||||||
|
kubectl replace --raw /api/v1/namespaces/monitoring/finalize -f - 2>/dev/null || true
|
||||||
|
kubectl wait --for=delete namespace monitoring --timeout=30s 2>/dev/null || sleep 5
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
kubectl create namespace monitoring --dry-run=client -o yaml | kubectl apply -f -
|
||||||
kubectl label namespace monitoring pod-security.kubernetes.io/enforce=privileged --overwrite
|
kubectl label namespace monitoring pod-security.kubernetes.io/enforce=privileged --overwrite
|
||||||
|
|
||||||
if helm status monitoring -n monitoring &> /dev/null; then
|
if helm status monitoring -n monitoring &> /dev/null; then
|
||||||
|
|||||||
+14
-2
@@ -56,7 +56,13 @@ kubectl delete pod curl-test -n istio --ignore-not-found=true 2>/dev/null || tru
|
|||||||
# Remover namespace istio (aplicação demo)
|
# Remover namespace istio (aplicação demo)
|
||||||
if kubectl get namespace istio &> /dev/null; then
|
if kubectl get namespace istio &> /dev/null; then
|
||||||
log_info "Removendo namespace istio..."
|
log_info "Removendo namespace istio..."
|
||||||
kubectl delete namespace istio --wait=false 2>/dev/null || true
|
kubectl delete namespace istio --timeout=120s 2>/dev/null || {
|
||||||
|
log_warn "Namespace preso em Terminating, forçando remoção..."
|
||||||
|
kubectl get namespace istio -o json | \
|
||||||
|
python3 -c "import sys,json; d=json.load(sys.stdin); d['metadata'].pop('finalizers',None); json.dump(d,sys.stdout)" | \
|
||||||
|
kubectl replace --raw /api/v1/namespaces/istio/finalize -f - 2>/dev/null || true
|
||||||
|
kubectl wait --for=delete namespace istio --timeout=60s 2>/dev/null || sleep 5
|
||||||
|
}
|
||||||
log_success "Namespace istio marcado para remoção"
|
log_success "Namespace istio marcado para remoção"
|
||||||
else
|
else
|
||||||
log_info "Namespace istio não encontrado"
|
log_info "Namespace istio não encontrado"
|
||||||
@@ -94,7 +100,13 @@ fi
|
|||||||
# Remover namespace istio-system
|
# Remover namespace istio-system
|
||||||
if kubectl get namespace istio-system &> /dev/null; then
|
if kubectl get namespace istio-system &> /dev/null; then
|
||||||
log_info "Removendo namespace istio-system..."
|
log_info "Removendo namespace istio-system..."
|
||||||
kubectl delete namespace istio-system --wait=false 2>/dev/null || true
|
kubectl delete namespace istio-system --timeout=120s 2>/dev/null || {
|
||||||
|
log_warn "Namespace preso em Terminating, forçando remoção..."
|
||||||
|
kubectl get namespace istio-system -o json | \
|
||||||
|
python3 -c "import sys,json; d=json.load(sys.stdin); d['metadata'].pop('finalizers',None); json.dump(d,sys.stdout)" | \
|
||||||
|
kubectl replace --raw /api/v1/namespaces/istio-system/finalize -f - 2>/dev/null || true
|
||||||
|
kubectl wait --for=delete namespace istio-system --timeout=60s 2>/dev/null || sleep 5
|
||||||
|
}
|
||||||
log_success "Namespace istio-system marcado para remoção"
|
log_success "Namespace istio-system marcado para remoção"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
+12
-3
@@ -222,7 +222,17 @@ install_istio() {
|
|||||||
helm repo add istio https://istio-release.storage.googleapis.com/charts 2>/dev/null || true
|
helm repo add istio https://istio-release.storage.googleapis.com/charts 2>/dev/null || true
|
||||||
helm repo update istio
|
helm repo update istio
|
||||||
|
|
||||||
kubectl create namespace istio-system 2>/dev/null || true
|
if kubectl get namespace istio-system &>/dev/null; then
|
||||||
|
NS_PHASE=$(kubectl get namespace istio-system -o jsonpath='{.status.phase}' 2>/dev/null)
|
||||||
|
if [[ "$NS_PHASE" == "Terminating" ]]; then
|
||||||
|
log_info "Namespace istio-system em Terminating, forçando remoção..."
|
||||||
|
kubectl get namespace istio-system -o json | \
|
||||||
|
python3 -c "import sys,json; d=json.load(sys.stdin); d['metadata'].pop('finalizers',None); json.dump(d,sys.stdout)" | \
|
||||||
|
kubectl replace --raw /api/v1/namespaces/istio-system/finalize -f - 2>/dev/null || true
|
||||||
|
kubectl wait --for=delete namespace istio-system --timeout=60s 2>/dev/null || sleep 5
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
kubectl create namespace istio-system --dry-run=client -o yaml | kubectl apply -f -
|
||||||
kubectl label namespace istio-system \
|
kubectl label namespace istio-system \
|
||||||
pod-security.kubernetes.io/enforce=privileged \
|
pod-security.kubernetes.io/enforce=privileged \
|
||||||
pod-security.kubernetes.io/warn=privileged \
|
pod-security.kubernetes.io/warn=privileged \
|
||||||
@@ -577,8 +587,7 @@ main() {
|
|||||||
echo -e "${YELLOW}⚠ Configure o DNS agora antes de continuar.${NC}"
|
echo -e "${YELLOW}⚠ Configure o DNS agora antes de continuar.${NC}"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
echo -n "Pressione ENTER quando o DNS estiver configurado..."
|
read -r -p "Pressione ENTER quando o DNS estiver configurado..." < /dev/tty
|
||||||
read -r
|
|
||||||
|
|
||||||
setup_ingress
|
setup_ingress
|
||||||
build_and_push_images
|
build_and_push_images
|
||||||
|
|||||||
+3
-3
@@ -14,7 +14,7 @@ Nesta aula, vamos instalar o CNPG do zero, criar um cluster HA com backup autom
|
|||||||
|
|
||||||
| Item | AWS RDS Multi-AZ | CNPG na Hetzner |
|
| Item | AWS RDS Multi-AZ | CNPG na Hetzner |
|
||||||
|------|------------------|-----------------|
|
|------|------------------|-----------------|
|
||||||
| Compute | db.r6g.large ~$185/mês | 3× CPX31 ~€36/mês (~$40) |
|
| Compute | db.r6g.large ~$185/mês | 3× CX33 ~€24/mês (~$27) |
|
||||||
| Storage 200GB | ~$23/mês (gp3) | ~€9/mês (hcloud volumes) |
|
| Storage 200GB | ~$23/mês (gp3) | ~€9/mês (hcloud volumes) |
|
||||||
| Backup | 7 dias (free) | ~€6/mês (Object Storage 1TB) |
|
| Backup | 7 dias (free) | ~€6/mês (Object Storage 1TB) |
|
||||||
| **Total mensal** | **~$208/mês** | **~€51/mês (~$56)** |
|
| **Total mensal** | **~$208/mês** | **~€51/mês (~$56)** |
|
||||||
@@ -26,7 +26,7 @@ Nesta aula, vamos instalar o CNPG do zero, criar um cluster HA com backup autom
|
|||||||
|
|
||||||
### Por que Hetzner?
|
### Por que Hetzner?
|
||||||
|
|
||||||
- CPX31: 4 vCPU AMD, 8GB RAM, 160GB NVMe → **~€12/mês**
|
- CX33: 4 vCPU Intel, 8GB RAM, 80GB NVMe → **~€8/mês**
|
||||||
- Object Storage: 1TB S3-compatible, 1TB egress free → **~€6/mês**
|
- Object Storage: 1TB S3-compatible, 1TB egress free → **~€6/mês**
|
||||||
- Sem surpresas: preço fixo, sem egress cost como AWS ($0.09/GB)
|
- Sem surpresas: preço fixo, sem egress cost como AWS ($0.09/GB)
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ Dois operadores PostgreSQL maduros para Kubernetes. Qual escolher?
|
|||||||
|
|
||||||
### Por que CNPG para indie hackers?
|
### Por que CNPG para indie hackers?
|
||||||
|
|
||||||
1. **Menos recursos = custo menor**. StackGres consome 3-5× mais RAM em sidecars. Num CPX31 com 8GB, isso faz diferença.
|
1. **Menos recursos = custo menor**. StackGres consome 3-5× mais RAM em sidecars. Num CX33 com 8GB, isso faz diferença.
|
||||||
2. **Setup mais simples**. Um Cluster CRD resolve. StackGres precisa de SGCluster, SGPostgresConfig, SGPgBouncerConfig, SGBackupConfig, SGPoolingConfig...
|
2. **Setup mais simples**. Um Cluster CRD resolve. StackGres precisa de SGCluster, SGPostgresConfig, SGPgBouncerConfig, SGBackupConfig, SGPoolingConfig...
|
||||||
3. **CNCF Sandbox**. Governança aberta, roadmap transparente, não depende de uma empresa.
|
3. **CNCF Sandbox**. Governança aberta, roadmap transparente, não depende de uma empresa.
|
||||||
4. **GitOps nativo**. CRDs foram desenhados pra serem declarativos. Funciona com ArgoCD/Flux sem hacks.
|
4. **GitOps nativo**. CRDs foram desenhados pra serem declarativos. Funciona com ArgoCD/Flux sem hacks.
|
||||||
|
|||||||
+14
-2
@@ -73,13 +73,25 @@ log_success "Secrets removidos"
|
|||||||
|
|
||||||
# 5. Remover namespace
|
# 5. Remover namespace
|
||||||
log_info "Removendo namespace cnpg..."
|
log_info "Removendo namespace cnpg..."
|
||||||
kubectl delete namespace cnpg --ignore-not-found=true 2>/dev/null || true
|
kubectl delete namespace cnpg --timeout=120s 2>/dev/null || {
|
||||||
|
log_warn "Namespace preso em Terminating, forçando remoção..."
|
||||||
|
kubectl get namespace cnpg -o json | \
|
||||||
|
python3 -c "import sys,json; d=json.load(sys.stdin); d['metadata'].pop('finalizers',None); json.dump(d,sys.stdout)" | \
|
||||||
|
kubectl replace --raw /api/v1/namespaces/cnpg/finalize -f - 2>/dev/null || true
|
||||||
|
kubectl wait --for=delete namespace cnpg --timeout=60s 2>/dev/null || sleep 5
|
||||||
|
}
|
||||||
log_success "Namespace cnpg removido"
|
log_success "Namespace cnpg removido"
|
||||||
|
|
||||||
# 6. Remover CNPG Operator
|
# 6. Remover CNPG Operator
|
||||||
log_info "Removendo CNPG operator..."
|
log_info "Removendo CNPG operator..."
|
||||||
helm uninstall cnpg -n cnpg-system --wait 2>/dev/null || true
|
helm uninstall cnpg -n cnpg-system --wait 2>/dev/null || true
|
||||||
kubectl delete namespace cnpg-system --ignore-not-found=true 2>/dev/null || true
|
kubectl delete namespace cnpg-system --timeout=120s 2>/dev/null || {
|
||||||
|
log_warn "Namespace preso em Terminating, forçando remoção..."
|
||||||
|
kubectl get namespace cnpg-system -o json | \
|
||||||
|
python3 -c "import sys,json; d=json.load(sys.stdin); d['metadata'].pop('finalizers',None); json.dump(d,sys.stdout)" | \
|
||||||
|
kubectl replace --raw /api/v1/namespaces/cnpg-system/finalize -f - 2>/dev/null || true
|
||||||
|
kubectl wait --for=delete namespace cnpg-system --timeout=60s 2>/dev/null || sleep 5
|
||||||
|
}
|
||||||
log_success "CNPG operator removido"
|
log_success "CNPG operator removido"
|
||||||
|
|
||||||
# 7. Remover CRDs
|
# 7. Remover CRDs
|
||||||
|
|||||||
@@ -12,29 +12,15 @@ spec:
|
|||||||
# topology.kubernetes.io/zone = fsn1 | nbg1 | hel1 (datacenter)
|
# topology.kubernetes.io/zone = fsn1 | nbg1 | hel1 (datacenter)
|
||||||
# topology.kubernetes.io/region = eu-central | hel-southeast
|
# topology.kubernetes.io/region = eu-central | hel-southeast
|
||||||
#
|
#
|
||||||
# Layer 1: podAntiAffinity on hostname (hard constraint)
|
# podAntiAffinityType: required → no 2 PG pods on same node (hard constraint)
|
||||||
# → No 2 PG pods on the same node. Ever.
|
# topologyKey: kubernetes.io/hostname → spread across nodes
|
||||||
#
|
#
|
||||||
# Layer 2: podAntiAffinity on zone (soft constraint)
|
# For cross-DC spread, CNPG relies on Kubernetes scheduler topology awareness.
|
||||||
# → Prefer spreading across datacenters. With nodes in fsn1, nbg1, hel1,
|
# With nodes in multiple zones (fsn1, nbg1, hel1), the scheduler naturally
|
||||||
# you get 1 pod per DC. With only eu-central nodes, they still spread
|
# spreads pods when combined with the node autoscaler.
|
||||||
# across FSN and NBG (both in eu-central, ~1-2ms apart).
|
|
||||||
#
|
|
||||||
# Prerequisite for cross-region (eu-central + HEL):
|
|
||||||
# - Node pool in eu-central (FSN + NBG) → aula-08
|
|
||||||
# - Node pool in hel-southeast (HEL) → add worker after aula-08
|
|
||||||
# - Without HEL nodes, all 3 pods stay in eu-central (still HA within region)
|
|
||||||
affinity:
|
affinity:
|
||||||
topologyKey: kubernetes.io/hostname
|
topologyKey: kubernetes.io/hostname
|
||||||
podAntiAffinityType: required
|
podAntiAffinityType: required
|
||||||
podAntiAffinity:
|
|
||||||
preferredDuringSchedulingIgnoredDuringExecution:
|
|
||||||
- weight: 100
|
|
||||||
podAffinityTerm:
|
|
||||||
topologyKey: topology.kubernetes.io/zone
|
|
||||||
labelSelector:
|
|
||||||
matchLabels:
|
|
||||||
cnpg.io/cluster: shared-postgres
|
|
||||||
storage:
|
storage:
|
||||||
size: 10Gi
|
size: 10Gi
|
||||||
storageClass: hcloud-volumes
|
storageClass: hcloud-volumes
|
||||||
@@ -60,10 +46,6 @@ spec:
|
|||||||
initdb:
|
initdb:
|
||||||
database: app
|
database: app
|
||||||
owner: app
|
owner: app
|
||||||
secret:
|
|
||||||
name: shared-postgres-superuser
|
|
||||||
superuserSecret:
|
|
||||||
name: shared-postgres-superuser
|
|
||||||
backup:
|
backup:
|
||||||
barmanObjectStore:
|
barmanObjectStore:
|
||||||
destinationPath: s3://CHANGE_BUCKET_NAME/cnpg-backups/shared-postgres
|
destinationPath: s3://CHANGE_BUCKET_NAME/cnpg-backups/shared-postgres
|
||||||
|
|||||||
+16
-10
@@ -135,26 +135,22 @@ collect_config() {
|
|||||||
if [[ -z "$S3_ENDPOINT" ]]; then
|
if [[ -z "$S3_ENDPOINT" ]]; then
|
||||||
S3_ENDPOINT="nbg1.your-objectstorage.com"
|
S3_ENDPOINT="nbg1.your-objectstorage.com"
|
||||||
fi
|
fi
|
||||||
echo -ne "Endpoint (${GREEN}${S3_ENDPOINT}${NC}): "
|
read -r -p "Endpoint (${GREEN}${S3_ENDPOINT}${NC}): " input < /dev/tty
|
||||||
read -r input
|
|
||||||
[[ -n "$input" ]] && S3_ENDPOINT="$input"
|
[[ -n "$input" ]] && S3_ENDPOINT="$input"
|
||||||
|
|
||||||
if [[ -z "$S3_BUCKET" ]]; then
|
if [[ -z "$S3_BUCKET" ]]; then
|
||||||
S3_BUCKET="cnpg-backups"
|
S3_BUCKET="cnpg-backups"
|
||||||
fi
|
fi
|
||||||
echo -ne "Bucket name (${GREEN}${S3_BUCKET}${NC}): "
|
read -r -p "Bucket name (${GREEN}${S3_BUCKET}${NC}): " input < /dev/tty
|
||||||
read -r input
|
|
||||||
[[ -n "$input" ]] && S3_BUCKET="$input"
|
[[ -n "$input" ]] && S3_BUCKET="$input"
|
||||||
|
|
||||||
echo -ne "Access Key ID: "
|
read -r -p "Access Key ID: " S3_ACCESS_KEY < /dev/tty
|
||||||
read -r S3_ACCESS_KEY
|
|
||||||
if [[ -z "$S3_ACCESS_KEY" ]]; then
|
if [[ -z "$S3_ACCESS_KEY" ]]; then
|
||||||
log_error "Access Key é obrigatória"
|
log_error "Access Key é obrigatória"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -ne "Secret Access Key: "
|
read -rs -p "Secret Access Key: " S3_SECRET_KEY < /dev/tty
|
||||||
read -rs S3_SECRET_KEY
|
|
||||||
echo ""
|
echo ""
|
||||||
if [[ -z "$S3_SECRET_KEY" ]]; then
|
if [[ -z "$S3_SECRET_KEY" ]]; then
|
||||||
log_error "Secret Key é obrigatória"
|
log_error "Secret Key é obrigatória"
|
||||||
@@ -191,7 +187,7 @@ install_cnpg_operator() {
|
|||||||
log_success "CNPG operator instalado"
|
log_success "CNPG operator instalado"
|
||||||
|
|
||||||
log_info "Aguardando operator ficar ready..."
|
log_info "Aguardando operator ficar ready..."
|
||||||
kubectl wait --for=condition=available deployment/cnpg-controller-manager -n cnpg-system --timeout=120s
|
kubectl wait --for=condition=available deployment/cnpg-cloudnative-pg -n cnpg-system --timeout=120s
|
||||||
log_success "CNPG operator pronto"
|
log_success "CNPG operator pronto"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,6 +201,16 @@ setup_namespace_and_secrets() {
|
|||||||
echo -e "${CYAN} Criando namespace e secrets${NC}"
|
echo -e "${CYAN} Criando namespace e secrets${NC}"
|
||||||
echo -e "${CYAN}═══════════════════════════════════════════════════════════${NC}"
|
echo -e "${CYAN}═══════════════════════════════════════════════════════════${NC}"
|
||||||
|
|
||||||
|
if kubectl get namespace cnpg &>/dev/null; then
|
||||||
|
NS_PHASE=$(kubectl get namespace cnpg -o jsonpath='{.status.phase}' 2>/dev/null)
|
||||||
|
if [[ "$NS_PHASE" == "Terminating" ]]; then
|
||||||
|
log_info "Namespace cnpg em Terminating, forçando remoção..."
|
||||||
|
kubectl get namespace cnpg -o json | \
|
||||||
|
python3 -c "import sys,json; d=json.load(sys.stdin); d['metadata'].pop('finalizers',None); json.dump(d,sys.stdout)" | \
|
||||||
|
kubectl replace --raw /api/v1/namespaces/cnpg/finalize -f - 2>/dev/null || true
|
||||||
|
kubectl wait --for=delete namespace cnpg --timeout=60s 2>/dev/null || sleep 5
|
||||||
|
fi
|
||||||
|
fi
|
||||||
kubectl create namespace cnpg --dry-run=client -o yaml | kubectl apply -f -
|
kubectl create namespace cnpg --dry-run=client -o yaml | kubectl apply -f -
|
||||||
|
|
||||||
log_info "Criando secret de credenciais S3..."
|
log_info "Criando secret de credenciais S3..."
|
||||||
@@ -228,7 +234,7 @@ create_cluster() {
|
|||||||
|
|
||||||
log_info "Gerando cluster.yaml com suas configurações..."
|
log_info "Gerando cluster.yaml com suas configurações..."
|
||||||
sed -e "s|CHANGE_BUCKET_NAME|${S3_BUCKET}|g" \
|
sed -e "s|CHANGE_BUCKET_NAME|${S3_BUCKET}|g" \
|
||||||
-e "s|CHANGE_ENDPOINT|https://${S3_ENDPOINT}|g" \
|
-e "s|CHANGE_ENDPOINT|${S3_ENDPOINT}|g" \
|
||||||
"${SCRIPT_DIR}/cnpg/cluster.yaml" | kubectl apply -f -
|
"${SCRIPT_DIR}/cnpg/cluster.yaml" | kubectl apply -f -
|
||||||
|
|
||||||
log_success "Cluster aplicado"
|
log_success "Cluster aplicado"
|
||||||
|
|||||||
Reference in New Issue
Block a user