refactor: migrar GitLab → Gitea (aulas 10, 11, 13)
- Aula 10: Gitea + Registry + Actions + Runner (substituiu GitLab) - gitea-values.yaml: PostgreSQL standalone, Valkey standalone, ~800Mi RAM - setup.sh/cleanup.sh: namespace gitea, Helm gitea-charts/gitea + actions - README.md: documentação completa com de→para (GitLab/Harbor/Tekton vs Gitea) - Aula 11: ArgoCD (GitOps) — removido GitLab Runner (runner vive na aula-10) - setup.sh: só ArgoCD, integração SSH com Gitea - node-bugado/.gitea/workflows/ci.yml: pipeline convertida - Aula 13: Container Factory — atualizado para Gitea - setup.sh/cleanup.sh: referências GitLab → Gitea - pipelines/postgresql/ci.yml: Gitea Actions workflow - README.md: conexão com act_runner explicada - CLAUDE.md: tabela de aulas atualizada
This commit is contained in:
@@ -1,49 +1,127 @@
|
||||
# Aula 10 - GitLab via Helm (Cluster Hetzner Cloud)
|
||||
# Aula 10 - Plataforma de Desenvolvimento (Gitea)
|
||||
|
||||
Deploy do GitLab em Kubernetes usando Helm chart oficial, com Container Registry, SSH e TLS configurável.
|
||||
Git Server + Container Registry + CI/CD Runner — tudo num único deploy.
|
||||
|
||||
## Por que esta aula existe
|
||||
|
||||
Nas aulas anteriores construímos um cluster Kubernetes na Hetzner com autoscaling, ingress e storage. Agora precisamos de uma **plataforma de desenvolvimento** para:
|
||||
|
||||
1. **Hospedar código** (Git)
|
||||
2. **Armazenar imagens Docker** (Container Registry)
|
||||
3. **Automatizar builds e deploys** (CI/CD)
|
||||
|
||||
Normalmente, isso exigiria 3 ferramentas separadas. Nesta aula, mostramos como o Gitea entrega as 3 em um único binário.
|
||||
|
||||
## Por que Gitea (e não GitLab, Harbor, Tekton)?
|
||||
|
||||
A escolha de ferramentas é uma decisão de arquitetura. No ecossistema Kubernetes, existem opções especializadas para cada peça:
|
||||
|
||||
### De → Para
|
||||
|
||||
| Função | Opção "Enterprise" | O que usamos | Por quê |
|
||||
|--------|-------------------|--------------|---------|
|
||||
| **Git Server** | GitLab CE/EE | **Gitea** | GitLab pede ~5Gi RAM, 8 pods, 2 nodes. Gitea pede ~500Mi, 1 pod, 1 node. |
|
||||
| **Container Registry** | Harbor | **Gitea (integrado)** | Harbor é um projeto separado (~1Gi RAM, PostgreSQL, Redis, storage backend). Gitea já tem registry OCI embutido. |
|
||||
| **CI/CD** | Tekton / GitLab CI | **Gitea Actions** | Tekton é poderoso mas complexo (CRDs, pipelines, tasks, triggers — curva de aprendizado alta). Gitea Actions usa sintaxe GitHub Actions, que a maioria já conhece. |
|
||||
|
||||
### A conta fecha assim
|
||||
|
||||
```
|
||||
Abordagem "enterprise" (GitLab + Harbor + Tekton):
|
||||
GitLab: ~5Gi RAM, 8 pods, 40Gi storage, 2 nodes ($12.92/mês)
|
||||
Harbor: ~1Gi RAM, 5 pods, 20Gi storage ($5/mês)
|
||||
Tekton: ~512Mi RAM, 4 CRDs, curva de aprendizado
|
||||
Total: ~6.5Gi RAM, 17+ pods (~$18/mês)
|
||||
|
||||
Abordagem Gitea (tudo integrado):
|
||||
Gitea: ~500Mi RAM, 3 pods, 21Gi storage, 1 node ($7.41/mês)
|
||||
Total: ~500Mi RAM, 3 pods (~$7/mês)
|
||||
```
|
||||
|
||||
**Para um workshop com cluster pequeno na Hetzner (CAX11 com 4GB RAM), a conta não fecha com a abordagem enterprise.**
|
||||
|
||||
### Mas e a sintaxe do CI?
|
||||
|
||||
Esse é o ponto decisivo. Gitea Actions usa **sintaxe GitHub Actions** — o padrão de fato da indústria:
|
||||
|
||||
```yaml
|
||||
# .gitea/workflows/ci.yml — mesma sintaxe do GitHub Actions
|
||||
name: Build
|
||||
on: [push]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: docker build -t minha-app .
|
||||
```
|
||||
|
||||
Se você sabe GitHub Actions, sabe Gitea Actions. Se você sabe Gitea Actions, sabe GitHub Actions. Tekton tem sua própria DSL (PipelineRun, TaskRun, etc.) que não transfere pra nenhuma outra plataforma.
|
||||
|
||||
### Comparação visual: GitLab vs Gitea
|
||||
|
||||
| | GitLab | Gitea |
|
||||
|---|---|---|
|
||||
| **RAM** | ~5 Gi (request) | ~500 Mi |
|
||||
| **Pods** | 8 (webservice, sidekiq, gitaly, shell, postgres, redis, minio, registry) | 3 (gitea, postgresql, valkey) |
|
||||
| **Storage** | 40 Gi (4 PVCs) | 21 Gi (3 PVCs) |
|
||||
| **Nodes mínimos** | 2 (antiAffinity webservice/sidekiq) | 1 |
|
||||
| **Install time** | 10-15 min | 2-3 min |
|
||||
| **CI Syntax** | `.gitlab-ci.yml` (proprietária) | `.gitea/workflows/*.yml` (GitHub Actions) |
|
||||
| **Registry** | Componente separado (+ MinIO/S3) | Integrado (OCI nativo) |
|
||||
| **Runner** | `gitlab-runner` (Helm chart separado) | `act_runner` (Helm chart separado) |
|
||||
|
||||
## Arquitetura
|
||||
|
||||
```
|
||||
Hetzner LoadBalancer
|
||||
│
|
||||
┌───────────────────┼───────────────────┐
|
||||
│ │ │
|
||||
:80/:443 :22 │
|
||||
│ │ │
|
||||
▼ ▼ │
|
||||
┌───────────────┐ ┌─────────────┐ │
|
||||
│ NGINX Ingress │ │ TCP Service │ │
|
||||
└───────┬───────┘ └──────┬──────┘ │
|
||||
│ │ │
|
||||
▼ ▼ │
|
||||
┌─────────────────────────────────────────┐ │
|
||||
│ GitLab (namespace: gitlab) │ │
|
||||
│ ┌──────────┐ ┌────────┐ ┌─────────┐ │ │
|
||||
│ │Webservice│ │Sidekiq │ │ Shell │◄─┼─────┘
|
||||
│ │ (Rails) │ │ (Jobs) │ │ (SSH) │ │
|
||||
│ └────┬─────┘ └───┬────┘ └─────────┘ │
|
||||
│ │ │ │
|
||||
│ ┌────▼────────────▼────┐ │
|
||||
│ │ Gitaly │ │
|
||||
│ │ (Git Storage) │ │
|
||||
│ └──────────────────────┘ │
|
||||
┌───────────────────┼──────────────┐
|
||||
│ │ │
|
||||
:80/:443 :22 │
|
||||
│ │ │
|
||||
▼ ▼ │
|
||||
┌───────────────┐ ┌─────────────┐ │
|
||||
│ NGINX Ingress │ │ TCP Service │ │
|
||||
└───────┬───────┘ └──────┬──────┘ │
|
||||
│ │ │
|
||||
▼ ▼ │
|
||||
┌──────────────────────────────────────────┐
|
||||
│ Namespace: gitea │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌───────┐ │
|
||||
│ │PostgreSQL│ │ Redis │ │
|
||||
│ │ (10Gi) │ │(10Gi) │ │
|
||||
│ └──────────┘ └───────┘ │
|
||||
└──────────────┬──────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────┐
|
||||
│ Hetzner Object │
|
||||
│ Storage (S3) │
|
||||
│ - uploads │
|
||||
│ - artifacts │
|
||||
│ - registry images │
|
||||
│ - lfs objects │
|
||||
└─────────────────────┘
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ Gitea Pod │ │
|
||||
│ │ Web UI + API + Git + SSH │◄────┘
|
||||
│ │ Container Registry (OCI) │
|
||||
│ │ Gitea Actions (habilitado) │
|
||||
│ └──────────────┬──────────────────┘
|
||||
│ │
|
||||
│ ┌──────────────┼──────────────┐
|
||||
│ │ │ │
|
||||
│ ▼ ▼ ▼
|
||||
│ PostgreSQL Valkey act_runner
|
||||
│ (10Gi) (1Gi) + DinD
|
||||
│ (builds Docker)
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### O act_runner em detalhe
|
||||
|
||||
O runner é instalado como um **StatefulSet** com 2 containers:
|
||||
|
||||
| Container | O que faz |
|
||||
|-----------|-----------|
|
||||
| `act-runner` | Conecta ao Gitea, escuta por jobs, executa workflows |
|
||||
| `dind` (Docker-in-Docker) | Daemon Docker privilegiado — permite `docker build` e `docker push` dentro dos workflows |
|
||||
|
||||
Quando você faz `git push` num repo que tem `.gitea/workflows/ci.yml`, o fluxo é:
|
||||
|
||||
```
|
||||
git push → Gitea recebe → act_runner detecta workflow
|
||||
→ Runner cria container temporário
|
||||
→ Executa steps (checkout, build, push)
|
||||
→ Imagem vai pro Gitea Container Registry
|
||||
→ Kubernetes puxa a imagem no deploy
|
||||
```
|
||||
|
||||
## Pré-requisitos
|
||||
@@ -51,40 +129,37 @@ 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. **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
|
||||
|
||||
Esta aula usa o cluster Kubernetes provisionado na **aula-08**. O `kubeconfig` foi gerado automaticamente pelo OpenTofu.
|
||||
|
||||
```bash
|
||||
# Verificar se o cluster está acessível
|
||||
export KUBECONFIG=$(pwd)/../aula-08/kubeconfig
|
||||
kubectl cluster-info
|
||||
```
|
||||
2. **kubectl** instalado
|
||||
3. **Helm** 3.x instalado
|
||||
|
||||
## Instalação
|
||||
|
||||
```bash
|
||||
cd aula-10
|
||||
|
||||
# Configurar acesso ao cluster (kubeconfig da aula-08)
|
||||
export KUBECONFIG=$(pwd)/../aula-08/kubeconfig
|
||||
|
||||
# Executar setup interativo
|
||||
chmod +x setup.sh
|
||||
./setup.sh
|
||||
```
|
||||
|
||||
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
|
||||
1. **Hostname do Gitea** (ex: `gitea.kube.quest`) - FQDN completo
|
||||
2. **Usa CloudFlare?** (com proxy/CDN)
|
||||
3. **Ativar Let's Encrypt?** (se não usar CloudFlare)
|
||||
4. **Hetzner Object Storage** - endpoint, bucket e credenciais
|
||||
|
||||
### O que o setup.sh instala
|
||||
|
||||
```
|
||||
1. cert-manager (se Let's Encrypt)
|
||||
2. Gitea via Helm (gitea-charts/gitea)
|
||||
- Web UI + API + Git + SSH
|
||||
- Container Registry (packages)
|
||||
- PostgreSQL standalone
|
||||
- Valkey (cache)
|
||||
3. Gitea Actions Runner via Helm (gitea-charts/actions)
|
||||
- act_runner + Docker-in-Docker
|
||||
- Registration token obtido automaticamente
|
||||
4. TCP passthrough no NGINX para SSH (porta 22)
|
||||
```
|
||||
|
||||
### Opções de TLS
|
||||
|
||||
@@ -94,132 +169,59 @@ O script é interativo e pergunta:
|
||||
| **Outro DNS + Let's Encrypt** | cert-manager | HTTP-01 challenge automático |
|
||||
| **Outro DNS + HTTP** | Nenhum | Apenas HTTP (dev/workshop) |
|
||||
|
||||
### CloudFlare e Trusted Proxies (Erro 422)
|
||||
## Componentes e Recursos
|
||||
|
||||
Quando você usa CloudFlare com proxy ativo (ícone laranja), o tráfego passa pelos servidores do CloudFlare antes de chegar ao GitLab:
|
||||
| Componente | Chart | Memory Request | Memory Limit | Volume |
|
||||
|------------|-------|----------------|--------------|--------|
|
||||
| Gitea | gitea-charts/gitea | 512Mi | 1Gi | 10Gi |
|
||||
| PostgreSQL | (subchart) | 128Mi | 256Mi | 10Gi |
|
||||
| Valkey | (subchart) | 32Mi | 64Mi | 1Gi |
|
||||
| act_runner + DinD | gitea-charts/actions | 128Mi | 256Mi | 5Gi |
|
||||
| **Total** | | **~800Mi** | **~1.6Gi** | **~26Gi** |
|
||||
|
||||
```
|
||||
Usuário → CloudFlare (TLS) → LoadBalancer → NGINX → GitLab
|
||||
↓
|
||||
Adiciona headers:
|
||||
X-Forwarded-For: IP-do-usuario
|
||||
X-Forwarded-Proto: https
|
||||
```
|
||||
## Funcionalidades
|
||||
|
||||
**Problema:** Por padrão, o GitLab (Workhorse) não confia nesses headers. Resultado:
|
||||
- GitLab pensa que a requisição veio via HTTP (não HTTPS)
|
||||
- CSRF token é gerado para HTTPS mas validado como HTTP
|
||||
- **Erro 422: "The change you requested was rejected"**
|
||||
### 1. Container Registry (OCI)
|
||||
|
||||
**Solução:** O `setup.sh` configura automaticamente os IPs do CloudFlare como proxies confiáveis:
|
||||
|
||||
```yaml
|
||||
gitlab.webservice.workhorse.trustedCIDRsForXForwardedFor:
|
||||
- 173.245.48.0/20 # CloudFlare
|
||||
- 103.21.244.0/22
|
||||
- 103.22.200.0/22
|
||||
# ... (todos os CIDRs do CloudFlare)
|
||||
```
|
||||
|
||||
Com isso, o Workhorse confia nos headers `X-Forwarded-*` vindos do CloudFlare e o login funciona corretamente.
|
||||
|
||||
> **Lição:** Proxies reversos (CloudFlare, NGINX, HAProxy) adicionam headers para preservar informações do cliente original. O backend precisa ser configurado para confiar nesses headers, caso contrário terá problemas de protocolo e autenticação.
|
||||
|
||||
## Componentes Instalados
|
||||
|
||||
**Da aula-08 (infraestrutura):**
|
||||
- Hetzner CSI Driver (StorageClass: hcloud-volumes)
|
||||
- NGINX Ingress Controller com LoadBalancer
|
||||
|
||||
**Instalados por este script:**
|
||||
- **cert-manager** (se Let's Encrypt ativado)
|
||||
- **GitLab** com todos os componentes
|
||||
|
||||
| Componente | Memory Request | Memory Limit | Volume |
|
||||
|------------|----------------|--------------|--------|
|
||||
| Webservice | 2Gi | 2.5Gi | - |
|
||||
| Sidekiq | 1.5Gi | 2Gi | - |
|
||||
| Gitaly | 512Mi | 1Gi | 10Gi |
|
||||
| PostgreSQL | 512Mi | 1Gi | 10Gi |
|
||||
| Redis | 256Mi | 512Mi | 10Gi |
|
||||
| Shell | 64Mi | 128Mi | - |
|
||||
| Toolbox | 256Mi | 512Mi | - |
|
||||
| **Total** | ~5Gi | ~8Gi | 30Gi |
|
||||
|
||||
**Object Storage (externo):**
|
||||
- Hetzner Object Storage (S3-compatible)
|
||||
- Uploads, artifacts, LFS, registry images
|
||||
- Custo: €0.006/GB/mês (paga por uso)
|
||||
|
||||
## Distribuição Inteligente de Pods
|
||||
|
||||
O GitLab usa **anti-affinity preferencial** para se adaptar automaticamente ao cluster:
|
||||
|
||||
```yaml
|
||||
gitlab:
|
||||
webservice:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchLabels:
|
||||
app: sidekiq
|
||||
topologyKey: kubernetes.io/hostname
|
||||
```
|
||||
|
||||
### Comportamento Adaptativo
|
||||
|
||||
| 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 |
|
||||
|
||||
### Por que preferencial ao invés de obrigatório?
|
||||
|
||||
- **Obrigatório** (`required`): pods ficam Pending se não houver nós separados
|
||||
- **Preferencial** (`preferred`): funciona com qualquer topologia, otimiza quando possível
|
||||
|
||||
### 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
|
||||
|
||||
| Serviço | Domínio |
|
||||
|---------|---------|
|
||||
| Web UI | {GITLAB_HOST} (ex: git.kube.quest) |
|
||||
| Registry | registry.{DOMAIN} (ex: registry.kube.quest) |
|
||||
| SSH | {GITLAB_HOST}:22 |
|
||||
|
||||
Exemplo com hostname `git.kube.quest`:
|
||||
- https://git.kube.quest
|
||||
- https://registry.kube.quest
|
||||
- git@git.kube.quest
|
||||
|
||||
## Arquivo de Configuração
|
||||
|
||||
O `setup.sh` gera um arquivo `.env` (herda configuração de TLS da aula-09):
|
||||
O Gitea inclui um Container Registry OCI integrado. Sem Harbor, sem MinIO, sem componentes extras.
|
||||
|
||||
```bash
|
||||
# aula-10/.env (gerado automaticamente)
|
||||
GITLAB_HOST=git.kube.quest
|
||||
REGISTRY_HOST=registry.kube.quest
|
||||
DOMAIN=kube.quest
|
||||
USE_CLOUDFLARE=true
|
||||
USE_LETSENCRYPT=false
|
||||
LETSENCRYPT_EMAIL=
|
||||
# Login no registry
|
||||
docker login gitea.kube.quest
|
||||
|
||||
# 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
|
||||
# Push de imagem
|
||||
docker tag minha-app:v1 gitea.kube.quest/usuario/minha-app:v1
|
||||
docker push gitea.kube.quest/usuario/minha-app:v1
|
||||
```
|
||||
|
||||
### 2. Gitea Actions (CI/CD)
|
||||
|
||||
CI/CD integrado com sintaxe GitHub Actions. Sem Tekton, sem CRDs extras, sem DSL proprietária.
|
||||
|
||||
```yaml
|
||||
# .gitea/workflows/build.yml
|
||||
name: Build
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: |
|
||||
echo "${{ secrets.REGISTRY_TOKEN }}" | docker login gitea.kube.quest -u ${{ gitea.actor }} --password-stdin
|
||||
docker build -t gitea.kube.quest/${{ gitea.repository }}:${{ github.sha }} .
|
||||
docker push gitea.kube.quest/${{ gitea.repository }}:${{ github.sha }}
|
||||
```
|
||||
|
||||
### 3. SSH
|
||||
|
||||
```bash
|
||||
# Clonar via SSH
|
||||
git clone git@gitea.kube.quest:usuario/projeto.git
|
||||
|
||||
# Configurar chave SSH: Settings → SSH/GPG Keys
|
||||
```
|
||||
|
||||
## Acesso
|
||||
@@ -227,148 +229,119 @@ S3_REGION=nbg1
|
||||
### Web UI
|
||||
|
||||
```
|
||||
URL: https://git.{domain}
|
||||
Usuário: root
|
||||
Senha: (ver abaixo)
|
||||
```
|
||||
|
||||
### Obter senha do root
|
||||
|
||||
```bash
|
||||
kubectl get secret gitlab-gitlab-initial-root-password \
|
||||
-n gitlab \
|
||||
-o jsonpath='{.data.password}' | base64 -d; echo
|
||||
```
|
||||
|
||||
### SSH
|
||||
|
||||
```bash
|
||||
# Clonar repositório via SSH
|
||||
git clone git@git.kube.quest:grupo/projeto.git
|
||||
|
||||
# Configurar chave SSH no GitLab
|
||||
# Settings → SSH Keys → Adicionar sua chave pública
|
||||
URL: https://gitea.kube.quest
|
||||
Usuário: gitea_admin
|
||||
Senha: (exibida no final do setup.sh)
|
||||
```
|
||||
|
||||
### Container Registry
|
||||
|
||||
```bash
|
||||
# Login no registry
|
||||
docker login registry.kube.quest
|
||||
docker login gitea.kube.quest
|
||||
# Username: gitea_admin
|
||||
# Password: (mesma senha do admin)
|
||||
```
|
||||
|
||||
# Push de imagem
|
||||
docker tag minha-app:v1 registry.kube.quest/grupo/projeto:v1
|
||||
docker push registry.kube.quest/grupo/projeto:v1
|
||||
### Verificar Runner
|
||||
|
||||
```bash
|
||||
# Pod do runner
|
||||
kubectl get pods -n gitea -l app.kubernetes.io/name=actions
|
||||
|
||||
# Logs
|
||||
kubectl logs -n gitea -l app.kubernetes.io/name=actions -c act-runner -f
|
||||
|
||||
# Workflows executados
|
||||
# Via UI: https://gitea.kube.quest/{owner}/{repo}/actions
|
||||
```
|
||||
|
||||
## Comandos Úteis
|
||||
|
||||
```bash
|
||||
# Ver todos os pods
|
||||
kubectl get pods -n gitlab
|
||||
kubectl get pods -n gitea
|
||||
|
||||
# Ver logs do webservice
|
||||
kubectl logs -n gitlab -l app=webservice -f
|
||||
# Ver logs do Gitea
|
||||
kubectl logs -n gitea -l app.kubernetes.io/name=gitea -f
|
||||
|
||||
# Ver logs do sidekiq
|
||||
kubectl logs -n gitlab -l app=sidekiq -f
|
||||
|
||||
# Reiniciar componente
|
||||
kubectl rollout restart deployment -n gitlab gitlab-webservice-default
|
||||
|
||||
# Rails console
|
||||
kubectl exec -it -n gitlab \
|
||||
$(kubectl get pod -n gitlab -l app=toolbox -o name | head -1) \
|
||||
-- gitlab-rails console
|
||||
|
||||
# Backup
|
||||
kubectl exec -it -n gitlab \
|
||||
$(kubectl get pod -n gitlab -l app=toolbox -o name | head -1) \
|
||||
-- backup-utility
|
||||
# Reiniciar Gitea
|
||||
kubectl rollout restart deployment -n gitea gitea
|
||||
|
||||
# Ver certificados (se Let's Encrypt)
|
||||
kubectl get certificate -n gitlab
|
||||
kubectl get certificate -n gitea
|
||||
|
||||
# Desinstalar (apenas GitLab)
|
||||
# Desinstalar
|
||||
./cleanup.sh
|
||||
```
|
||||
|
||||
**Nota:** O `cleanup.sh` remove apenas GitLab, clientes e cert-manager. A infraestrutura (CSI Driver, NGINX Ingress, LoadBalancer) é mantida pois pertence à aula-08.
|
||||
|
||||
## Configurações Adicionais
|
||||
|
||||
### Adicionar GitLab Runner
|
||||
|
||||
```bash
|
||||
# Obter registration token
|
||||
kubectl get secret gitlab-gitlab-runner-secret \
|
||||
-n gitlab \
|
||||
-o jsonpath='{.data.runner-registration-token}' | base64 -d; echo
|
||||
|
||||
# Instalar runner
|
||||
helm install gitlab-runner gitlab/gitlab-runner \
|
||||
--namespace gitlab \
|
||||
--set gitlabUrl=https://git.kube.quest \
|
||||
--set runnerRegistrationToken=<token>
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Pods não iniciam
|
||||
|
||||
```bash
|
||||
# Verificar eventos
|
||||
kubectl get events -n gitlab --sort-by='.lastTimestamp'
|
||||
|
||||
# Verificar PVCs
|
||||
kubectl get pvc -n gitlab
|
||||
|
||||
# Verificar se CSI driver está funcionando
|
||||
kubectl get pods -n kube-system -l app=hcloud-csi
|
||||
kubectl get events -n gitea --sort-by='.lastTimestamp'
|
||||
kubectl get pvc -n gitea
|
||||
```
|
||||
|
||||
### SSH não conecta
|
||||
|
||||
```bash
|
||||
# Verificar se porta 22 está no ConfigMap
|
||||
# Verificar TCP passthrough
|
||||
kubectl get configmap tcp-services -n ingress-nginx -o yaml
|
||||
|
||||
# Verificar gitlab-shell pod
|
||||
kubectl get pods -n gitlab -l app=gitlab-shell
|
||||
```
|
||||
|
||||
### Registry não funciona
|
||||
|
||||
```bash
|
||||
# Verificar pod do registry
|
||||
kubectl get pods -n gitlab -l app=registry
|
||||
kubectl logs -n gitlab -l app=registry
|
||||
curl -v https://gitea.kube.quest/v2/
|
||||
```
|
||||
|
||||
# Testar internamente
|
||||
kubectl run test --rm -it --image=busybox -- wget -qO- http://gitlab-registry:5000/v2/
|
||||
### Runner não executa workflows
|
||||
|
||||
```bash
|
||||
# Verificar se o runner está registrado
|
||||
kubectl logs -n gitea -l app.kubernetes.io/name=actions -c act-runner --tail=20
|
||||
|
||||
# Verificar se DinD está rodando
|
||||
kubectl logs -n gitea -l app.kubernetes.io/name=actions -c dind --tail=10
|
||||
|
||||
# Erro "Docker connection failed" → DinD não compartilha socket
|
||||
# Verificar se extraVolumeMounts do dind inclui docker-socket
|
||||
```
|
||||
|
||||
### Runner crashando (OOM)
|
||||
|
||||
O Gitea pode usar mais memória durante migrações de repos grandes. Se ocorrer OOM:
|
||||
|
||||
```bash
|
||||
# Aumentar limit temporariamente
|
||||
helm upgrade gitea gitea-charts/gitea -n gitea \
|
||||
--reuse-values \
|
||||
--set resources.limits.memory=1Gi
|
||||
```
|
||||
|
||||
## 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 |
|
||||
|---------|-----------|
|
||||
| Volumes (3x 10Gi = 30Gi) | ~$1.45 |
|
||||
| Object Storage (~10GB uso) | ~€0.06 |
|
||||
| Worker (1x CAX11) | ~$4.59 |
|
||||
| Volumes (~26Gi) | ~$1.26 |
|
||||
| LoadBalancer (compartilhado) | ~$1.80 (1/3) |
|
||||
| **Total** | **~$7.65** |
|
||||
|
||||
**Nota:** O anti-affinity preferencial permite ambos os cenários.
|
||||
O Cluster Autoscaler provisiona nós automaticamente quando necessário.
|
||||
## Lições do Workshop
|
||||
|
||||
**Vantagem Object Storage:** Sem volume MinIO (economia de ~$0.50/mês) + storage ilimitado.
|
||||
1. **Nem sempre precisa da ferramenta "enterprise"** — Gitea substitui GitLab + Harbor + parcialmente Tekton com 10x menos recursos
|
||||
2. **Registry integrado** é suficiente para a maioria dos casos — Harbor justifica-se quando você precisa de vulnerability scanning, replicação multi-site, ou compliance (assinatura de imagens)
|
||||
3. **Sintaxe GitHub Actions é portável** — o que você aprende aqui transfere direto pro GitHub, e vice-versa
|
||||
4. **Docker-in-Docker no Kubernetes** requer namespace com PodSecurity `privileged` — é o trade-off pra ter builds Docker no cluster
|
||||
|
||||
## Referências
|
||||
|
||||
- [GitLab Helm Chart](https://docs.gitlab.com/charts/)
|
||||
- [GitLab Helm Chart Values](https://gitlab.com/gitlab-org/charts/gitlab/-/blob/master/values.yaml)
|
||||
- [External Ingress](https://docs.gitlab.com/charts/advanced/external-ingress/)
|
||||
- [NGINX TCP Services](https://kubernetes.github.io/ingress-nginx/user-guide/exposing-tcp-udp-services/)
|
||||
- [Gitea Docs](https://docs.gitea.com/)
|
||||
- [Gitea Helm Chart](https://gitea.com/gitea/helm-chart)
|
||||
- [Gitea Container Registry](https://docs.gitea.com/usage/packages/container)
|
||||
- [Gitea Actions](https://docs.gitea.com/usage/actions/overview)
|
||||
- [act_runner](https://docs.gitea.com/usage/actions/act-runner)
|
||||
- [ArtifactHub - Gitea](https://artifacthub.io/packages/helm/gitea/gitea)
|
||||
- [ArtifactHub - Gitea Actions](https://artifacthub.io/packages/helm/gitea/actions)
|
||||
|
||||
Reference in New Issue
Block a user