From 12f6f48c640c66e12b0cd8d5520e8c868b07a58d Mon Sep 17 00:00:00 2001 From: ArgoCD Setup Date: Fri, 23 Jan 2026 22:52:43 -0300 Subject: [PATCH] feat(aula-10): migrar para Hetzner Object Storage + melhorias MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- aula-10/README.md | 101 ++++++++----- aula-10/cleanup.sh | 2 +- aula-10/gitlab-values.yaml | 92 ++++++------ aula-10/object-storage-secret.yaml | 22 +++ aula-10/registry-storage-secret.yaml | 24 ++++ aula-10/setup.sh | 207 ++++++++++++++++++++++----- 6 files changed, 334 insertions(+), 114 deletions(-) create mode 100644 aula-10/object-storage-secret.yaml create mode 100644 aula-10/registry-storage-secret.yaml diff --git a/aula-10/README.md b/aula-10/README.md index 376112b..b518f16 100644 --- a/aula-10/README.md +++ b/aula-10/README.md @@ -29,11 +29,21 @@ Deploy do GitLab em Kubernetes usando Helm chart oficial, com Container Registry │ │ (Git Storage) │ │ │ └──────────────────────┘ │ │ │ -│ ┌──────────┐ ┌───────┐ ┌──────────┐ │ -│ │PostgreSQL│ │ Redis │ │ MinIO │ │ -│ │ (10Gi) │ │(10Gi) │ │ (10Gi) │ │ -│ └──────────┘ └───────┘ └──────────┘ │ -└─────────────────────────────────────────┘ +│ ┌──────────┐ ┌───────┐ │ +│ │PostgreSQL│ │ Redis │ │ +│ │ (10Gi) │ │(10Gi) │ │ +│ └──────────┘ └───────┘ │ +└──────────────┬──────────────────────────┘ + │ + ▼ + ┌─────────────────────┐ + │ Hetzner Object │ + │ Storage (S3) │ + │ - uploads │ + │ - artifacts │ + │ - registry images │ + │ - lfs objects │ + └─────────────────────┘ ``` ## Pré-requisitos @@ -41,8 +51,11 @@ Deploy do GitLab em Kubernetes usando Helm chart oficial, com Container Registry 1. **Cluster Talos na Hetzner** (aula-08) com: - Hetzner CSI Driver (StorageClass: hcloud-volumes) - NGINX Ingress Controller com LoadBalancer -2. **kubectl** instalado -3. **Helm** 3.x instalado +2. **Hetzner Object Storage** (bucket + credenciais): + - Criar bucket em: https://console.hetzner.cloud → Object Storage + - Gerar Access Key e Secret Key +3. **kubectl** instalado +4. **Helm** 3.x instalado ## Contexto do Cluster @@ -71,6 +84,7 @@ O script é interativo e pergunta: 1. **Hostname do GitLab** (ex: `git.kube.quest`) - FQDN completo 2. **Usa CloudFlare?** (com proxy/CDN) - pode herdar da aula-09 3. **Ativar Let's Encrypt?** (se não usar CloudFlare) +4. **Hetzner Object Storage** - endpoint, bucket e credenciais ### Opções de TLS @@ -128,43 +142,51 @@ Com isso, o Workhorse confia nos headers `X-Forwarded-*` vindos do CloudFlare e | Gitaly | 512Mi | 1Gi | 10Gi | | PostgreSQL | 512Mi | 1Gi | 10Gi | | Redis | 256Mi | 512Mi | 10Gi | -| MinIO | 128Mi | 256Mi | 10Gi | | Shell | 64Mi | 128Mi | - | | Toolbox | 256Mi | 512Mi | - | -| **Total** | ~5Gi | ~8Gi | 40Gi | +| **Total** | ~5Gi | ~8Gi | 30Gi | -## Pod Anti-Affinity (Distribuicao Inteligente) +**Object Storage (externo):** +- Hetzner Object Storage (S3-compatible) +- Uploads, artifacts, LFS, registry images +- Custo: €0.006/GB/mês (paga por uso) -O GitLab configura **antiAffinity** para garantir que webservice e sidekiq rodem em nos diferentes: +## Distribuição Inteligente de Pods + +O GitLab usa **anti-affinity preferencial** para se adaptar automaticamente ao cluster: ```yaml gitlab: webservice: affinity: podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchLabels: - app: sidekiq - topologyKey: kubernetes.io/hostname + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app: sidekiq + topologyKey: kubernetes.io/hostname ``` -### Por que isso importa? +### Comportamento Adaptativo -Sem antiAffinity, webservice (~2.5Gi) + sidekiq (~2Gi) = 4.5Gi no mesmo no CAX11 (4GB): -- **Resultado**: OOMKilled constantes, servico instavel +| Cenário | Comportamento | +|---------|---------------| +| 1 nó grande (8GB+) | Tudo roda junto no mesmo nó | +| Múltiplos nós pequenos | Distribui automaticamente | +| Sem recursos suficientes | Cluster Autoscaler cria nós novos | -Com antiAffinity: -- Kubernetes detecta que nao pode agendar no mesmo no -- Pod fica **Pending** -- Cluster Autoscaler cria um novo no automaticamente -- Pods distribuidos = servico estavel +### Por que preferencial ao invés de obrigatório? -### Licao do Workshop +- **Obrigatório** (`required`): pods ficam Pending se não houver nós separados +- **Preferencial** (`preferred`): funciona com qualquer topologia, otimiza quando possível -> "Kubernetes nao e so rodar containers - e **orquestracao inteligente**. -> Quando configuramos antiAffinity, o scheduler entendeu que precisava de mais -> recursos e o autoscaler provisionou automaticamente." +### Lição do Workshop + +> "Configurações adaptativas são melhores que rígidas. O anti-affinity preferencial +> permite que o GitLab funcione em um nó grande ou distribua em vários pequenos, +> sem intervenção manual." ## Padrão de Domínios @@ -191,6 +213,13 @@ DOMAIN=kube.quest USE_CLOUDFLARE=true USE_LETSENCRYPT=false LETSENCRYPT_EMAIL= + +# Hetzner Object Storage (use a mesma região do cluster) +S3_ENDPOINT=nbg1.your-objectstorage.com +S3_ACCESS_KEY=xxxxx +S3_SECRET_KEY=xxxxx +S3_BUCKET=gitlab-workshop +S3_REGION=nbg1 ``` ## Acesso @@ -321,15 +350,21 @@ kubectl run test --rm -it --image=busybox -- wget -qO- http://gitlab-registry:50 ## Custos +| Cenário | Workers | Custo/mês | +|---------|---------|-----------| +| 1x CAX21 (8GB) | 1 nó | ~$8.49 | +| 2x CAX11 (4GB) | 2 nós (distribuído) | ~$9.18 | + | Recurso | Custo/mês | |---------|-----------| -| Workers (2x CAX11 - antiAffinity) | ~$9.18 | -| Volumes (4x 10Gi = 40Gi) | ~$1.94 | +| Volumes (3x 10Gi = 30Gi) | ~$1.45 | +| Object Storage (~10GB uso) | ~€0.06 | | LoadBalancer (compartilhado) | ~$1.80 (1/3) | -| **Total GitLab** | ~$12.92 | -**Nota:** O antiAffinity requer 2 workers minimos (webservice e sidekiq em nos separados). -O Cluster Autoscaler provisiona automaticamente quando necessario. +**Nota:** O anti-affinity preferencial permite ambos os cenários. +O Cluster Autoscaler provisiona nós automaticamente quando necessário. + +**Vantagem Object Storage:** Sem volume MinIO (economia de ~$0.50/mês) + storage ilimitado. ## Referências diff --git a/aula-10/cleanup.sh b/aula-10/cleanup.sh index 78e30f8..6c9f7ab 100755 --- a/aula-10/cleanup.sh +++ b/aula-10/cleanup.sh @@ -45,7 +45,7 @@ echo "" log_warn "ATENÇÃO: Isso vai remover os recursos da aula 10:" echo " - GitLab e todos os componentes" -echo " - Volumes persistentes (PostgreSQL, Redis, MinIO, Gitaly)" +echo " - Volumes persistentes (PostgreSQL, Redis, Gitaly)" echo " - cert-manager (se instalado)" echo " - Arquivo .env" echo "" diff --git a/aula-10/gitlab-values.yaml b/aula-10/gitlab-values.yaml index 099c9ef..a0374dc 100644 --- a/aula-10/gitlab-values.yaml +++ b/aula-10/gitlab-values.yaml @@ -76,8 +76,10 @@ nginx-ingress: gitlab: # Webservice (Rails app - UI e API) - # NOTA: antiAffinity garante que webservice e sidekiq rodem em nós diferentes - # Isso evita OOM quando ambos competem por memória no mesmo nó CAX11 (4GB) + # Anti-affinity preferencial: distribui se possível, mas não obriga + # - 1 nó grande (8GB): tudo roda junto + # - Múltiplos nós pequenos: distribui automaticamente + # - Sem recursos: autoscaler cria nós novos webservice: minReplicas: 1 maxReplicas: 1 @@ -93,17 +95,18 @@ gitlab: threads: min: 1 max: 2 - # Anti-affinity: não rodar no mesmo nó que sidekiq + # Anti-affinity preferencial: tenta separar de sidekiq, mas não obriga affinity: podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchLabels: - app: sidekiq - topologyKey: kubernetes.io/hostname + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app: sidekiq + topologyKey: kubernetes.io/hostname # Sidekiq (background jobs) - # Anti-affinity: não rodar no mesmo nó que webservice sidekiq: minReplicas: 1 maxReplicas: 1 @@ -117,13 +120,16 @@ gitlab: # Desabilitar memory watchdog interno do GitLab (deixa o OOM killer do K8s gerenciar) memoryKiller: maxRss: 2000000000 # 2GB - maior que o limite para evitar kills prematuros + # Anti-affinity preferencial: tenta separar de webservice, mas não obriga affinity: podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchLabels: - app: webservice - topologyKey: kubernetes.io/hostname + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app: webservice + topologyKey: kubernetes.io/hostname # Gitaly (Git storage) gitaly: @@ -213,38 +219,31 @@ redis: storageClass: hcloud-volumes # ============================================================================= -# MINIO (Object Storage) +# OBJECT STORAGE (Hetzner Object Storage - S3 compatible) # ============================================================================= -# NOTA: As imagens padrão do GitLab chart não suportam ARM64. -# Usamos as imagens oficiais multi-arch do MinIO. -minio: - install: true - image: minio/minio - imageTag: RELEASE.2024-06-13T22-53-53Z - minioMc: - image: minio/mc - tag: RELEASE.2024-06-12T14-34-03Z - resources: - requests: - memory: 128Mi - cpu: 50m - limits: - memory: 256Mi - cpu: 200m - persistence: - size: 10Gi - storageClass: hcloud-volumes +# Usamos o Hetzner Object Storage ao invés do MinIO bundled. +# Vantagens: +# - Sem volume persistente (economia de $0.50/mês) +# - Sem pod MinIO (economia de recursos) +# - Storage ilimitado (paga por uso: €0.006/GB) +# - Alta disponibilidade gerenciada pela Hetzner +# +# Pré-requisito: criar bucket e credenciais na Hetzner Console +# O setup.sh cria o Secret gitlab-object-storage automaticamente -# Ou usar object storage externo (S3, etc): -# global: -# minio: -# enabled: false -# appConfig: -# object_store: -# enabled: true -# connection: -# secret: gitlab-object-storage -# key: connection +minio: + install: false + +global: + minio: + enabled: false + appConfig: + object_store: + enabled: true + proxy_download: true + connection: + secret: gitlab-object-storage + key: connection # ============================================================================= # REGISTRY (Container Registry) @@ -261,7 +260,10 @@ registry: limits: memory: 256Mi cpu: 200m - # Storage usa MinIO bundled automaticamente quando minio.install=true + # Storage usa Hetzner Object Storage (configurado via global.appConfig.object_store) + storage: + secret: gitlab-registry-storage + key: config # ============================================================================= # COMPONENTES DESABILITADOS (economia de recursos) diff --git a/aula-10/object-storage-secret.yaml b/aula-10/object-storage-secret.yaml new file mode 100644 index 0000000..0f4d0a7 --- /dev/null +++ b/aula-10/object-storage-secret.yaml @@ -0,0 +1,22 @@ +# ============================================================================= +# Secret para GitLab Object Storage (Hetzner S3) +# ============================================================================= +# Usado por: uploads, artifacts, lfs, packages, etc. +# +# Variáveis substituídas pelo setup.sh via envsubst: +# - S3_REGION, S3_ACCESS_KEY, S3_SECRET_KEY, S3_ENDPOINT +# +apiVersion: v1 +kind: Secret +metadata: + name: gitlab-object-storage + namespace: gitlab +type: Opaque +stringData: + connection: | + provider: AWS + region: ${S3_REGION} + aws_access_key_id: ${S3_ACCESS_KEY} + aws_secret_access_key: ${S3_SECRET_KEY} + endpoint: https://${S3_ENDPOINT} + path_style: true diff --git a/aula-10/registry-storage-secret.yaml b/aula-10/registry-storage-secret.yaml new file mode 100644 index 0000000..111ccc4 --- /dev/null +++ b/aula-10/registry-storage-secret.yaml @@ -0,0 +1,24 @@ +# ============================================================================= +# Secret para GitLab Registry Storage (Hetzner S3) +# ============================================================================= +# Usado por: Container Registry +# Formato diferente do object-storage (registry usa config YAML) +# +# Variáveis substituídas pelo setup.sh via envsubst: +# - S3_BUCKET, S3_ACCESS_KEY, S3_SECRET_KEY, S3_REGION, S3_ENDPOINT +# +apiVersion: v1 +kind: Secret +metadata: + name: gitlab-registry-storage + namespace: gitlab +type: Opaque +stringData: + config: | + s3: + bucket: ${S3_BUCKET} + accesskey: ${S3_ACCESS_KEY} + secretkey: ${S3_SECRET_KEY} + region: ${S3_REGION} + regionendpoint: https://${S3_ENDPOINT} + v4auth: true diff --git a/aula-10/setup.sh b/aula-10/setup.sh index 8838f27..cdcf717 100755 --- a/aula-10/setup.sh +++ b/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}"