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:
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user