feat(aula-10): migrar para Hetzner Object Storage + melhorias
Mudanças principais: - Substituir MinIO bundled por Hetzner Object Storage (S3) - Secrets YAML com envsubst para credenciais S3 - Anti-affinity preferencial (adapta a qualquer topologia) - Detecção automática de cert-manager existente - Menu TLS simplificado (Let's Encrypt/CloudFlare/HTTP) - Perguntar hostname do registry separadamente - Exibição unificada de TLS (não mais CloudFlare: true/false)
This commit is contained in:
207
aula-10/setup.sh
207
aula-10/setup.sh
@@ -46,6 +46,13 @@ USE_CLOUDFLARE=""
|
||||
USE_LETSENCRYPT=""
|
||||
LETSENCRYPT_EMAIL=""
|
||||
|
||||
# Hetzner Object Storage
|
||||
S3_ENDPOINT=""
|
||||
S3_ACCESS_KEY=""
|
||||
S3_SECRET_KEY=""
|
||||
S3_BUCKET=""
|
||||
S3_REGION=""
|
||||
|
||||
# =============================================================================
|
||||
# FUNÇÕES DE CONFIGURAÇÃO
|
||||
# =============================================================================
|
||||
@@ -60,6 +67,13 @@ DOMAIN=${DOMAIN}
|
||||
USE_CLOUDFLARE=${USE_CLOUDFLARE}
|
||||
USE_LETSENCRYPT=${USE_LETSENCRYPT}
|
||||
LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
|
||||
|
||||
# Hetzner Object Storage
|
||||
S3_ENDPOINT=${S3_ENDPOINT}
|
||||
S3_ACCESS_KEY=${S3_ACCESS_KEY}
|
||||
S3_SECRET_KEY=${S3_SECRET_KEY}
|
||||
S3_BUCKET=${S3_BUCKET}
|
||||
S3_REGION=${S3_REGION}
|
||||
EOF
|
||||
log_success "Configuração salva em .env"
|
||||
}
|
||||
@@ -102,11 +116,19 @@ collect_user_input() {
|
||||
|
||||
# Se já tem GITLAB_HOST configurado, oferecer usar
|
||||
if [[ -n "$GITLAB_HOST" ]]; then
|
||||
# Determinar tipo de TLS para exibição
|
||||
if [[ "$USE_LETSENCRYPT" == "true" ]]; then
|
||||
TLS_TYPE="Let's Encrypt"
|
||||
elif [[ "$USE_CLOUDFLARE" == "true" ]]; then
|
||||
TLS_TYPE="CloudFlare"
|
||||
else
|
||||
TLS_TYPE="Sem TLS (HTTP)"
|
||||
fi
|
||||
|
||||
echo -e "Configuração existente encontrada:"
|
||||
echo -e " GitLab: ${GREEN}${GITLAB_HOST}${NC}"
|
||||
echo -e " Registry: ${GREEN}${REGISTRY_HOST}${NC}"
|
||||
echo -e " CloudFlare: ${GREEN}${USE_CLOUDFLARE}${NC}"
|
||||
echo -e " Let's Encrypt: ${GREEN}${USE_LETSENCRYPT}${NC}"
|
||||
echo -e " TLS: ${GREEN}${TLS_TYPE}${NC}"
|
||||
echo ""
|
||||
echo -e "Deseja usar esta configuração?"
|
||||
echo -e " 1) Sim, continuar com a configuração existente"
|
||||
@@ -128,18 +150,33 @@ collect_user_input() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Derivar Domain e Registry automaticamente
|
||||
# Extrair domínio base
|
||||
DOMAIN=$(extract_domain "$GITLAB_HOST")
|
||||
REGISTRY_HOST="registry.${DOMAIN}"
|
||||
|
||||
# Perguntar hostname do registry (sugerir padrão)
|
||||
DEFAULT_REGISTRY="registry.${DOMAIN}"
|
||||
echo -n "Digite o hostname do Registry (enter para ${DEFAULT_REGISTRY}): "
|
||||
read -r REGISTRY_HOST
|
||||
if [[ -z "$REGISTRY_HOST" ]]; then
|
||||
REGISTRY_HOST="$DEFAULT_REGISTRY"
|
||||
fi
|
||||
|
||||
log_info "Registry será: ${REGISTRY_HOST}"
|
||||
|
||||
# Se já tem configuração de TLS, oferecer usar
|
||||
if [[ -n "$USE_CLOUDFLARE" ]]; then
|
||||
if [[ -n "$USE_CLOUDFLARE" || -n "$USE_LETSENCRYPT" ]]; then
|
||||
# Determinar tipo de TLS para exibição
|
||||
if [[ "$USE_LETSENCRYPT" == "true" ]]; then
|
||||
TLS_TYPE="Let's Encrypt"
|
||||
elif [[ "$USE_CLOUDFLARE" == "true" ]]; then
|
||||
TLS_TYPE="CloudFlare"
|
||||
else
|
||||
TLS_TYPE="Sem TLS (HTTP)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "Configuração de TLS encontrada:"
|
||||
echo -e " CloudFlare: ${GREEN}${USE_CLOUDFLARE}${NC}"
|
||||
echo -e " Let's Encrypt: ${GREEN}${USE_LETSENCRYPT}${NC}"
|
||||
echo -e " TLS: ${GREEN}${TLS_TYPE}${NC}"
|
||||
echo ""
|
||||
echo -e "Deseja usar esta configuração de TLS?"
|
||||
echo -e " 1) Sim"
|
||||
@@ -152,44 +189,104 @@ collect_user_input() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Perguntar sobre CloudFlare
|
||||
# Perguntar sobre TLS
|
||||
echo ""
|
||||
echo "Você usa CloudFlare para DNS?"
|
||||
echo " 1) Sim (com proxy/CDN ativado - ícone laranja)"
|
||||
echo " 2) Não"
|
||||
echo -n "Escolha [1/2]: "
|
||||
echo "Como deseja configurar TLS/HTTPS?"
|
||||
echo " 1) Let's Encrypt (recomendado - certificado automático)"
|
||||
echo " 2) CloudFlare (proxy/CDN - NOTA: SSH usa IP direto, não proxy)"
|
||||
echo " 3) Sem TLS (apenas HTTP - dev/workshop)"
|
||||
echo -n "Escolha [1/2/3]: "
|
||||
read -r choice
|
||||
|
||||
if [[ "$choice" == "1" ]]; then
|
||||
USE_CLOUDFLARE=true
|
||||
USE_LETSENCRYPT=false
|
||||
log_info "CloudFlare irá gerenciar TLS automaticamente na edge"
|
||||
else
|
||||
USE_CLOUDFLARE=false
|
||||
|
||||
# Perguntar sobre Let's Encrypt
|
||||
echo ""
|
||||
echo "Deseja ativar HTTPS com Let's Encrypt?"
|
||||
echo " 1) Sim (recomendado para produção)"
|
||||
echo " 2) Não (apenas HTTP)"
|
||||
echo -n "Escolha [1/2]: "
|
||||
read -r choice
|
||||
|
||||
if [[ "$choice" == "1" ]]; then
|
||||
case "$choice" in
|
||||
1)
|
||||
USE_LETSENCRYPT=true
|
||||
USE_CLOUDFLARE=false
|
||||
echo ""
|
||||
echo -n "Digite seu email para Let's Encrypt: "
|
||||
read -r LETSENCRYPT_EMAIL
|
||||
|
||||
if [[ -z "$LETSENCRYPT_EMAIL" ]]; then
|
||||
log_error "Email é obrigatório para Let's Encrypt"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
;;
|
||||
2)
|
||||
USE_CLOUDFLARE=true
|
||||
USE_LETSENCRYPT=false
|
||||
log_info "CloudFlare irá gerenciar TLS na edge"
|
||||
log_warn "NOTA: Git via SSH (porta 22) não passa pelo proxy CloudFlare"
|
||||
;;
|
||||
*)
|
||||
USE_CLOUDFLARE=false
|
||||
USE_LETSENCRYPT=false
|
||||
;;
|
||||
esac
|
||||
|
||||
# Coletar configuração do Hetzner Object Storage
|
||||
echo ""
|
||||
echo -e "${CYAN}═══════════════════════════════════════════════════${NC}"
|
||||
echo -e "${CYAN} Hetzner Object Storage${NC}"
|
||||
echo -e "${CYAN}═══════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
echo "O GitLab usa Hetzner Object Storage para armazenar:"
|
||||
echo " - Uploads de usuários"
|
||||
echo " - Artifacts de CI/CD"
|
||||
echo " - Container Registry images"
|
||||
echo " - LFS objects"
|
||||
echo ""
|
||||
echo "Crie um bucket e credenciais em:"
|
||||
echo " https://console.hetzner.cloud → Object Storage"
|
||||
echo ""
|
||||
|
||||
# Se já tem configuração, oferecer usar
|
||||
if [[ -n "$S3_ENDPOINT" && -n "$S3_ACCESS_KEY" ]]; then
|
||||
echo -e "Configuração existente encontrada:"
|
||||
echo -e " Endpoint: ${GREEN}${S3_ENDPOINT}${NC}"
|
||||
echo -e " Bucket: ${GREEN}${S3_BUCKET}${NC}"
|
||||
echo ""
|
||||
echo -e "Deseja usar esta configuração?"
|
||||
echo -e " 1) Sim"
|
||||
echo -e " 2) Não, reconfigurar"
|
||||
echo -n "Escolha [1/2]: "
|
||||
read -r choice
|
||||
if [[ "$choice" == "1" ]]; then
|
||||
save_config
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -n "Endpoint (ex: nbg1.your-objectstorage.com): "
|
||||
read -r S3_ENDPOINT
|
||||
if [[ -z "$S3_ENDPOINT" ]]; then
|
||||
log_error "Endpoint não pode ser vazio"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extrair região do endpoint (fsn1, nbg1, etc)
|
||||
S3_REGION=$(echo "$S3_ENDPOINT" | cut -d. -f1)
|
||||
|
||||
echo -n "Bucket name (ex: gitlab-workshop): "
|
||||
read -r S3_BUCKET
|
||||
if [[ -z "$S3_BUCKET" ]]; then
|
||||
log_error "Bucket não pode ser vazio"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -n "Access Key: "
|
||||
read -r S3_ACCESS_KEY
|
||||
if [[ -z "$S3_ACCESS_KEY" ]]; then
|
||||
log_error "Access Key não pode ser vazia"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -n "Secret Key: "
|
||||
read -rs S3_SECRET_KEY
|
||||
echo ""
|
||||
if [[ -z "$S3_SECRET_KEY" ]]; then
|
||||
log_error "Secret Key não pode ser vazia"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Salvar configuração
|
||||
save_config
|
||||
}
|
||||
@@ -238,6 +335,19 @@ EOF
|
||||
log_success "ClusterIssuer 'letsencrypt-prod' criado"
|
||||
}
|
||||
|
||||
create_object_storage_secrets() {
|
||||
log_info "Criando Secrets para Hetzner Object Storage..."
|
||||
|
||||
# Exportar variáveis para envsubst
|
||||
export S3_REGION S3_ACCESS_KEY S3_SECRET_KEY S3_ENDPOINT S3_BUCKET
|
||||
|
||||
# Aplicar secrets usando envsubst para substituir variáveis
|
||||
envsubst < "$SCRIPT_DIR/object-storage-secret.yaml" | kubectl apply -f -
|
||||
envsubst < "$SCRIPT_DIR/registry-storage-secret.yaml" | kubectl apply -f -
|
||||
|
||||
log_success "Secrets criados"
|
||||
}
|
||||
|
||||
show_dns_instructions() {
|
||||
# Obter IP do LoadBalancer
|
||||
LB_IP=$(kubectl get svc -n ingress-nginx ingress-nginx-controller \
|
||||
@@ -383,7 +493,15 @@ kubectl create namespace gitlab --dry-run=client -o yaml | kubectl apply -f -
|
||||
echo ""
|
||||
|
||||
# =============================================================================
|
||||
# 6. INSTALAR GITLAB VIA HELM
|
||||
# 6. CRIAR SECRETS DO OBJECT STORAGE
|
||||
# =============================================================================
|
||||
|
||||
create_object_storage_secrets
|
||||
|
||||
echo ""
|
||||
|
||||
# =============================================================================
|
||||
# 7. INSTALAR GITLAB VIA HELM
|
||||
# =============================================================================
|
||||
|
||||
log_info "=== Instalando GitLab (isso pode levar 10-15 minutos) ==="
|
||||
@@ -391,11 +509,18 @@ log_info "=== Instalando GitLab (isso pode levar 10-15 minutos) ==="
|
||||
# Construir argumentos do Helm dinamicamente
|
||||
HELM_ARGS=""
|
||||
|
||||
# Detectar cert-manager já instalado (ex: aula-09)
|
||||
# Se existe, desabilitar o bundled para evitar conflito de CRDs
|
||||
if kubectl get crd certificates.cert-manager.io &> /dev/null; then
|
||||
log_info "cert-manager detectado - usando instalação existente"
|
||||
HELM_ARGS="$HELM_ARGS --set installCertmanager=false"
|
||||
fi
|
||||
|
||||
# Configurar hosts
|
||||
HELM_ARGS="$HELM_ARGS --set global.hosts.domain=${DOMAIN}"
|
||||
HELM_ARGS="$HELM_ARGS --set global.hosts.gitlab.name=${GITLAB_HOST}"
|
||||
HELM_ARGS="$HELM_ARGS --set global.hosts.registry.name=${REGISTRY_HOST}"
|
||||
HELM_ARGS="$HELM_ARGS --set global.hosts.minio.name=minio.${GITLAB_HOST}"
|
||||
# MinIO desabilitado - usando Hetzner Object Storage
|
||||
|
||||
# Configurar TLS
|
||||
if [[ "$USE_LETSENCRYPT" == "true" ]]; then
|
||||
@@ -409,6 +534,8 @@ if [[ "$USE_LETSENCRYPT" == "true" ]]; then
|
||||
elif [[ "$USE_CLOUDFLARE" == "true" ]]; then
|
||||
# CloudFlare: TLS na edge, backend HTTP
|
||||
# Workhorse precisa confiar nos IPs do CloudFlare para X-Forwarded-For
|
||||
HELM_ARGS="$HELM_ARGS --set global.ingress.configureCertmanager=false"
|
||||
HELM_ARGS="$HELM_ARGS --set certmanager-issuer.install=false"
|
||||
HELM_ARGS="$HELM_ARGS --set global.ingress.tls.enabled=false"
|
||||
HELM_ARGS="$HELM_ARGS --set global.hosts.https=true"
|
||||
# CloudFlare IPv4 CIDRs (https://www.cloudflare.com/ips-v4)
|
||||
@@ -416,6 +543,8 @@ elif [[ "$USE_CLOUDFLARE" == "true" ]]; then
|
||||
HELM_ARGS="$HELM_ARGS --set-json gitlab.webservice.workhorse.trustedCIDRsForXForwardedFor='${CLOUDFLARE_CIDRS}'"
|
||||
else
|
||||
# Apenas HTTP
|
||||
HELM_ARGS="$HELM_ARGS --set global.ingress.configureCertmanager=false"
|
||||
HELM_ARGS="$HELM_ARGS --set certmanager-issuer.install=false"
|
||||
HELM_ARGS="$HELM_ARGS --set global.ingress.tls.enabled=false"
|
||||
HELM_ARGS="$HELM_ARGS --set global.hosts.https=false"
|
||||
fi
|
||||
@@ -513,15 +642,23 @@ echo " - Gitaly (Git storage)"
|
||||
echo " - GitLab Shell (SSH)"
|
||||
echo " - PostgreSQL"
|
||||
echo " - Redis"
|
||||
echo " - MinIO (object storage)"
|
||||
echo " - Hetzner Object Storage (S3)"
|
||||
echo " - Container Registry"
|
||||
echo ""
|
||||
# Determinar tipo de TLS para exibição
|
||||
if [[ "$USE_LETSENCRYPT" == "true" ]]; then
|
||||
TLS_TYPE="Let's Encrypt"
|
||||
elif [[ "$USE_CLOUDFLARE" == "true" ]]; then
|
||||
TLS_TYPE="CloudFlare"
|
||||
else
|
||||
TLS_TYPE="Sem TLS (HTTP)"
|
||||
fi
|
||||
|
||||
echo "Configuração:"
|
||||
echo " GitLab: ${GITLAB_HOST}"
|
||||
echo " Registry: ${REGISTRY_HOST}"
|
||||
echo " Domínio: ${DOMAIN}"
|
||||
echo " CloudFlare: ${USE_CLOUDFLARE}"
|
||||
echo " Let's Encrypt: ${USE_LETSENCRYPT}"
|
||||
echo " TLS: ${TLS_TYPE}"
|
||||
echo ""
|
||||
echo "URLs:"
|
||||
echo " Web: ${PROTOCOL}://${GITLAB_HOST}"
|
||||
|
||||
Reference in New Issue
Block a user