diff --git a/CLAUDE.md b/CLAUDE.md index f4ad535..db1b4c2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -33,14 +33,15 @@ App de demonstração: `node-bugado` - trava após N requests para demonstrar he # Aulas 01-06 (Local) cd aula-XX && ./setup.sh # ou kubectl apply -f . -# Aulas 07-13 (Hetzner) +# Aulas 07-15 (Hetzner) cd aula-08 && ./setup.sh # Cluster base cd aula-09 && ./setup.sh # n8n -cd aula-10 && ./setup.sh # Gitea +cd aula-10 && ./setup.sh # Gitea + Registry + Runner cd aula-11 && ./setup.sh # ArgoCD -cd aula-12 && ./setup.sh # Victoria Metrics +cd aula-12 && ./setup.sh # Victoria Metrics + Grafana cd aula-13 && ./setup.sh # Container Factory cd aula-14 && ./setup.sh # Istio Traffic Splitting +cd aula-15 && ./setup.sh # APM: Tempo + OpenTelemetry ``` ## App node-bugado diff --git a/aula-10/gitlab-registry-storage-secret.yaml b/aula-10/gitlab-registry-storage-secret.yaml deleted file mode 100644 index df9791a..0000000 --- a/aula-10/gitlab-registry-storage-secret.yaml +++ /dev/null @@ -1,34 +0,0 @@ -# ============================================================================= -# GitLab Registry Storage Secret - Hetzner Object Storage -# ============================================================================= -# -# Este secret configura o Registry para usar Hetzner Object Storage (S3 compatível) -# -# ANTES DE APLICAR: -# 1. Crie o bucket "gitlab-registry" na Hetzner Cloud Console -# 2. Gere credenciais S3 (Access Key + Secret Key) -# 3. Substitua os valores abaixo -# -# Para aplicar: -# kubectl apply -f gitlab-registry-storage-secret.yaml -# -# ============================================================================= - -apiVersion: v1 -kind: Secret -metadata: - name: gitlab-registry-storage - namespace: gitlab -type: Opaque -stringData: - config: | - s3: - bucket: gitlab-registry - accesskey: - secretkey: - region: eu-central - regionendpoint: https://fsn1.your-objectstorage.com - v4auth: true - secure: true - chunksize: 5242880 - rootdirectory: / diff --git a/aula-10/gitlab-values.yaml b/aula-10/gitlab-values.yaml deleted file mode 100644 index f9390c2..0000000 --- a/aula-10/gitlab-values.yaml +++ /dev/null @@ -1,329 +0,0 @@ -# ============================================================================= -# GitLab Helm Chart - Configuração Base para Hetzner CAX11 -# ============================================================================= -# -# Esta configuração: -# - Usa NGINX Ingress Controller externo (instalado na aula-08) -# - Define ~5GB de recursos distribuídos em 2 workers CAX11 (antiAffinity) -# - Desabilita componentes não essenciais para economizar recursos -# - Configura Registry para container images -# -# Valores dinâmicos (configurados via --set no setup.sh): -# - global.hosts.domain -# - global.hosts.gitlab.name -# - global.hosts.registry.name -# - global.hosts.minio.name -# - global.hosts.https -# - global.ingress.tls.enabled -# - global.ingress.configureCertmanager -# -# Cenário CloudFlare (proxy ativo): -# - global.ingress.tls.enabled=false -# - global.hosts.https=true -# - gitlab.webservice.workhorse.trustedCIDRsForXForwardedFor=[CloudFlare IPs] -# -# Cenário Let's Encrypt: -# - global.ingress.tls.enabled=true -# - global.hosts.https=true -# - global.ingress.configureCertmanager=true -# - global.ingress.annotations.cert-manager.io/cluster-issuer=letsencrypt-prod -# -# ============================================================================= - -global: - # Desabilitar MinIO interno (migrado para Hetzner Object Storage) - minio: - enabled: false - - # Usar Ingress Controller externo - ingress: - class: nginx - # configureCertmanager é definido via --set no setup.sh (true para Let's Encrypt) - annotations: - nginx.ingress.kubernetes.io/proxy-body-size: "0" - nginx.ingress.kubernetes.io/proxy-read-timeout: "900" - nginx.ingress.kubernetes.io/proxy-connect-timeout: "900" - nginx.ingress.kubernetes.io/proxy-buffering: "off" - # cert-manager.io/cluster-issuer é adicionado via --set quando Let's Encrypt - - # Timezone - time_zone: America/Sao_Paulo - - # Pod Security - evitar warnings de PodSecurity - pod: - securityContext: - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - - # Email (opcional - configurar depois) - # email: - # from: gitlab@kube.quest - # display_name: GitLab - # reply_to: noreply@kube.quest - -# ============================================================================= -# NGINX BUNDLED - DESABILITAR (usamos o externo) -# ============================================================================= -nginx-ingress: - enabled: false - -# ============================================================================= -# CERT-MANAGER - DESABILITAR BUNDLED -# ============================================================================= -# O cert-manager é instalado separadamente se Let's Encrypt for escolhido. -# global.ingress.configureCertmanager controla a integração. - -# ============================================================================= -# GITLAB COMPONENTS -# ============================================================================= - -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) - webservice: - minReplicas: 1 - maxReplicas: 1 - resources: - requests: - memory: 2Gi - cpu: 200m - limits: - memory: 2.5Gi - cpu: 1 - workerProcesses: 1 - puma: - threads: - min: 1 - max: 2 - # Anti-affinity: não rodar no mesmo nó que sidekiq - # Node affinity: preferir nodes do pool gitlab-pool (CAX21 com 8GB) - affinity: - nodeAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - preference: - matchExpressions: - - key: hcloud/node-group - operator: In - values: - - gitlab-pool - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - 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 - resources: - requests: - memory: 1.5Gi - cpu: 100m - limits: - memory: 2Gi - cpu: 500m - # 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 - # Node affinity: preferir nodes do pool gitlab-pool (CAX21 com 8GB) - affinity: - nodeAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - preference: - matchExpressions: - - key: hcloud/node-group - operator: In - values: - - gitlab-pool - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchLabels: - app: webservice - topologyKey: kubernetes.io/hostname - - # Gitaly (Git storage) - gitaly: - # Node affinity: preferir nodes do pool gitlab-pool (CAX21 com 8GB) - affinity: - nodeAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - preference: - matchExpressions: - - key: hcloud/node-group - operator: In - values: - - gitlab-pool - resources: - requests: - memory: 512Mi - cpu: 100m - limits: - memory: 1Gi - cpu: 500m - persistence: - size: 10Gi # Mínimo Hetzner ($0.0484/GB) - storageClass: hcloud-volumes - - # GitLab Shell (SSH) - gitlab-shell: - minReplicas: 1 - maxReplicas: 1 - service: - type: ClusterIP # TCP passthrough pelo NGINX - resources: - requests: - memory: 64Mi - cpu: 50m - limits: - memory: 128Mi - cpu: 100m - - # Toolbox (backup, rake tasks) - toolbox: - enabled: true - resources: - requests: - memory: 256Mi - cpu: 50m - limits: - memory: 512Mi - cpu: 200m - - # GitLab Exporter (métricas) - gitlab-exporter: - enabled: false # Economiza recursos - - # Migrations - migrations: - resources: - requests: - memory: 256Mi - cpu: 100m - - # KAS (Kubernetes Agent Server) - desabilitar - kas: - enabled: false - -# ============================================================================= -# POSTGRESQL -# ============================================================================= -postgresql: - install: true - primary: - affinity: - nodeAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - preference: - matchExpressions: - - key: hcloud/node-group - operator: In - values: - - gitlab-pool - resources: - requests: - memory: 512Mi - cpu: 100m - limits: - memory: 1Gi - cpu: 500m - persistence: - size: 10Gi # Mínimo Hetzner ($0.0484/GB) - storageClass: hcloud-volumes - -# ============================================================================= -# REDIS -# ============================================================================= -redis: - install: true - master: - resources: - requests: - memory: 256Mi - cpu: 50m - limits: - memory: 512Mi - cpu: 200m - persistence: - size: 10Gi # Mínimo Hetzner ($0.0484/GB) - storageClass: hcloud-volumes - -# ============================================================================= -# MINIO (Object Storage) - DESABILITADO -# ============================================================================= -# Migrado para Hetzner Object Storage para resolver problema de espaço (89% cheio) -# O Registry agora usa S3 externo (Hetzner Object Storage) -# -# Para voltar ao MinIO interno (rollback): -# 1. Mudar minio.install: true -# 2. Remover registry.storage configuração -# 3. Re-deploy GitLab -minio: - install: false - -# ============================================================================= -# REGISTRY (Container Registry) - Usando Hetzner Object Storage -# ============================================================================= -# IMPORTANTE: Antes de fazer deploy, criar o secret: -# kubectl apply -f gitlab-registry-storage-secret.yaml -# -# O secret contém as credenciais S3 para o Hetzner Object Storage -registry: - enabled: true - hpa: - minReplicas: 1 - maxReplicas: 1 - resources: - requests: - memory: 128Mi - cpu: 50m - limits: - memory: 256Mi - cpu: 200m - # Storage configurado para Hetzner Object Storage (S3 compatível) - storage: - secret: gitlab-registry-storage - key: config - -# ============================================================================= -# COMPONENTES DESABILITADOS (economia de recursos) -# ============================================================================= - -# GitLab Runner - instalar separadamente se necessário -gitlab-runner: - install: false - -# Prometheus - usar Victoria Metrics da aula-05 -prometheus: - install: false - -# Grafana -grafana: - install: false - -# GitLab Pages -gitlab-pages: - enabled: false - -# Praefect (Gitaly HA) - não necessário para instalação pequena -praefect: - enabled: false - -# Spamcheck -spamcheck: - enabled: false - -# ============================================================================= -# UPGRADECHECK -# ============================================================================= -upgradeCheck: - enabled: false diff --git a/aula-10/object-storage-secret.yaml b/aula-10/object-storage-secret.yaml deleted file mode 100644 index 0f4d0a7..0000000 --- a/aula-10/object-storage-secret.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# ============================================================================= -# 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 deleted file mode 100644 index 111ccc4..0000000 --- a/aula-10/registry-storage-secret.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# ============================================================================= -# 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-11/gitlab-runner-values.yaml b/aula-11/gitlab-runner-values.yaml deleted file mode 100644 index 197d536..0000000 --- a/aula-11/gitlab-runner-values.yaml +++ /dev/null @@ -1,148 +0,0 @@ -# ============================================================================= -# GitLab Runner Helm Chart - Executor Kubernetes -# ============================================================================= -# -# Configura GitLab Runner para executar jobs como pods no Kubernetes. -# Suporta Docker-in-Docker para build de imagens. -# -# Valores dinâmicos (configurados via --set no setup.sh): -# - gitlabUrl -# - runnerToken (novo método) ou runnerRegistrationToken (legacy) -# -# ============================================================================= - -# Número máximo de jobs simultâneos -concurrent: 2 - -# Intervalo de check por novos jobs (segundos) -checkInterval: 30 - -# Intervalo de heartbeat (segundos) -heartbeatInterval: 30 - -# ============================================================================= -# CONFIGURAÇÃO DO RUNNER -# ============================================================================= -runners: - # Executor: kubernetes (jobs rodam como pods) - executor: kubernetes - - # Privileged mode necessário para Docker-in-Docker - privileged: true - - # Namespace onde os jobs serão executados - namespace: gitlab - - # Tags para identificar o runner - tags: "kubernetes,docker,hetzner" - - # Rodar jobs sem tag também - runUntagged: true - - # Proteger branches protegidas - protected: false - - # Imagem padrão para jobs - image: alpine:latest - - # Helper image (para git clone, artifacts, etc) - helper: - image: gitlab/gitlab-runner-helper:alpine-latest - - # Configuração TOML adicional - config: | - [[runners]] - [runners.kubernetes] - image = "alpine:latest" - privileged = true - - # IMPORTANTE: Helper image para ARM64 (Hetzner CAX nodes) - # Sem isso, o runner tenta usar x86_64 e falha - helper_image = "gitlab/gitlab-runner-helper:arm64-latest" - - # Recursos para pods de job (aumentados para builds Docker) - # CAX31 tem 8 vCPU e 16GB - aproveitar para builds rápidos - cpu_request = "500m" - cpu_limit = "4000m" - memory_request = "1Gi" - memory_limit = "8Gi" - - # Timeout para pods - poll_timeout = 600 - - # Pull policy - pull_policy = ["if-not-present"] - - # Node selector para usar o build-pool (CAX31) - [runners.kubernetes.node_selector] - "node-pool" = "build" - - # Toleration para o taint do build-pool - [[runners.kubernetes.node_tolerations]] - key = "dedicated" - operator = "Equal" - value = "builds" - effect = "NoSchedule" - - # Volume para Docker certs (DinD) - [[runners.kubernetes.volumes.empty_dir]] - name = "docker-certs" - mount_path = "/certs/client" - medium = "Memory" - - # Volume para cache de build - [[runners.kubernetes.volumes.empty_dir]] - name = "build-cache" - mount_path = "/cache" - medium = "" - -# ============================================================================= -# RECURSOS DO RUNNER (manager pod) -# ============================================================================= -resources: - requests: - memory: 128Mi - cpu: 50m - limits: - memory: 256Mi - cpu: 200m - -# ============================================================================= -# RBAC -# ============================================================================= -rbac: - create: true - # Permissões para criar pods, secrets, configmaps - rules: - - apiGroups: [""] - resources: ["pods", "pods/exec", "secrets", "configmaps"] - verbs: ["get", "list", "watch", "create", "patch", "update", "delete"] - - apiGroups: [""] - resources: ["pods/attach", "pods/log"] - verbs: ["get", "create"] - -# ============================================================================= -# SERVICE ACCOUNT -# ============================================================================= -serviceAccount: - create: true - name: gitlab-runner - -# ============================================================================= -# MÉTRICAS (opcional) -# ============================================================================= -metrics: - enabled: false - -# ============================================================================= -# POD SECURITY -# ============================================================================= -podSecurityContext: - runAsNonRoot: true - runAsUser: 100 - -securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: false - capabilities: - drop: ["ALL"] diff --git a/aula-11/node-bugado/.gitlab-ci.yml b/aula-11/node-bugado/.gitlab-ci.yml deleted file mode 100644 index e220b84..0000000 --- a/aula-11/node-bugado/.gitlab-ci.yml +++ /dev/null @@ -1,116 +0,0 @@ -# ============================================================================= -# GitLab CI/CD Pipeline - node-bugado -# ============================================================================= -# -# Pipeline GitOps: -# 1. Build: Constrói imagem Docker e faz push para GitLab Registry -# 2. Deploy: Atualiza manifests no repo GitOps (ArgoCD faz sync) -# -# Variáveis necessárias (Settings → CI/CD → Variables): -# - GITOPS_REPO: URL do repositório GitOps (ex: git@git.kube.quest:user/gitops-demo.git) -# - DEPLOY_KEY: Chave SSH privada para push no repo GitOps -# -# ============================================================================= - -stages: - - build - - deploy - -variables: - # Registry do GitLab - REGISTRY: ${CI_REGISTRY} - IMAGE_NAME: ${CI_REGISTRY_IMAGE} - # Para usar registry externo, descomente: - # REGISTRY: registry.kube.quest - # IMAGE_NAME: ${REGISTRY}/${CI_PROJECT_PATH} - -# ============================================================================= -# BUILD - Construir e publicar imagem Docker -# ============================================================================= -build: - stage: build - image: docker:24 - services: - - docker:24-dind - variables: - DOCKER_TLS_CERTDIR: "/certs" - before_script: - - docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY} - script: - - echo "Building ${IMAGE_NAME}:${CI_COMMIT_SHA}" - - docker build -t ${IMAGE_NAME}:${CI_COMMIT_SHA} . - - docker tag ${IMAGE_NAME}:${CI_COMMIT_SHA} ${IMAGE_NAME}:latest - - docker push ${IMAGE_NAME}:${CI_COMMIT_SHA} - - docker push ${IMAGE_NAME}:latest - only: - - main - - master - tags: - - kubernetes - - docker - -# ============================================================================= -# DEPLOY - Atualizar manifests no repositório GitOps -# ============================================================================= -deploy: - stage: deploy - image: alpine:latest - before_script: - - apk add --no-cache git openssh-client - # Configurar SSH para o repo GitOps - - mkdir -p ~/.ssh - - echo "${DEPLOY_KEY}" | tr -d '\r' > ~/.ssh/id_ed25519 - - chmod 600 ~/.ssh/id_ed25519 - - ssh-keyscan -t ed25519 $(echo ${GITOPS_REPO} | sed 's/.*@\([^:]*\).*/\1/') >> ~/.ssh/known_hosts 2>/dev/null || true - # Configurar git - - git config --global user.email "ci@gitlab.local" - - git config --global user.name "GitLab CI" - script: - - echo "Updating GitOps repo with image ${IMAGE_NAME}:${CI_COMMIT_SHA}" - # Clonar repo GitOps - - git clone ${GITOPS_REPO} gitops - - cd gitops - # Atualizar tag da imagem no deployment - - | - if [ -f apps/node-bugado/deployment.yaml ]; then - sed -i "s|image:.*node-bugado.*|image: ${IMAGE_NAME}:${CI_COMMIT_SHA}|g" apps/node-bugado/deployment.yaml - git add apps/node-bugado/deployment.yaml - git commit -m "Deploy node-bugado ${CI_COMMIT_SHA:0:8} - - Pipeline: ${CI_PIPELINE_URL} - Commit: ${CI_COMMIT_SHA} - Author: ${CI_COMMIT_AUTHOR}" - git push - echo "GitOps repo updated successfully" - else - echo "WARNING: apps/node-bugado/deployment.yaml not found" - echo "Please create the GitOps structure first" - exit 1 - fi - only: - - main - - master - tags: - - kubernetes - when: on_success - needs: - - build - -# ============================================================================= -# NOTAS -# ============================================================================= -# -# Para configurar as variáveis: -# -# 1. GITOPS_REPO: -# - Vá em Settings → CI/CD → Variables -# - Adicione: GITOPS_REPO = git@git.kube.quest:usuario/gitops-demo.git -# -# 2. DEPLOY_KEY: -# - Gere uma chave: ssh-keygen -t ed25519 -f deploy-key -N '' -# - Adicione a chave PÚBLICA no repo GitOps: Settings → Repository → Deploy Keys -# - Marque "Grant write permissions to this key" -# - Adicione a chave PRIVADA como variável: DEPLOY_KEY = -# - Marque como "Protected" e "Masked" -# -# ============================================================================= diff --git a/aula-11/node-bugado/k8s/deployment.yaml b/aula-11/node-bugado/k8s/deployment.yaml index 0dcd30c..0f658b3 100644 --- a/aula-11/node-bugado/k8s/deployment.yaml +++ b/aula-11/node-bugado/k8s/deployment.yaml @@ -27,7 +27,8 @@ spec: containers: - name: node-bugado # IMPORTANTE: Esta linha é atualizada automaticamente pelo Gitea Actions - image: gitea.kube.quest/depaula/node-bugado:latest + # Substitua GITEA_HOST pelo hostname do seu Gitea (ex: gitea.kube.quest) + image: GITEA_HOST_PLACEHOLDER/depaula/node-bugado:latest ports: - containerPort: 3000 name: http diff --git a/aula-13/images/devops-toolbox/.gitlab-ci.yml b/aula-13/images/devops-toolbox/.gitlab-ci.yml deleted file mode 100644 index bdb3fa8..0000000 --- a/aula-13/images/devops-toolbox/.gitlab-ci.yml +++ /dev/null @@ -1,77 +0,0 @@ -# ============================================================================= -# Pipeline CI: DevOps Toolbox (eStargz + GZIP) -# ============================================================================= -# Constrói imagem em ambos os formatos para benchmark -# ============================================================================= - -stages: - - build - - push - -variables: - REGISTRY: gitea.kube.quest - IMAGE_NAME: factory/devops-toolbox - DOCKER_HOST: tcp://docker:2376 - DOCKER_TLS_CERTDIR: "/certs" - DOCKER_TLS_VERIFY: 1 - DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client" - -# ----------------------------------------------------------------------------- -# Build eStargz (lazy pulling) -# ----------------------------------------------------------------------------- -build-estargz: - stage: build - image: docker:27-dind - services: - - docker:27-dind - before_script: - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $REGISTRY - - docker buildx create --use --name multiarch --driver docker-container - script: - - | - docker buildx build \ - --platform linux/arm64,linux/amd64 \ - --output type=image,name=${REGISTRY}/${IMAGE_NAME}:latest,push=true,compression=estargz,force-compression=true,oci-mediatypes=true \ - --cache-from type=registry,ref=${REGISTRY}/${IMAGE_NAME}:cache \ - --cache-to type=registry,ref=${REGISTRY}/${IMAGE_NAME}:cache,mode=max \ - . - rules: - - if: $CI_COMMIT_BRANCH == "main" - -# ----------------------------------------------------------------------------- -# Build GZIP (tradicional, para benchmark) -# ----------------------------------------------------------------------------- -build-gzip: - stage: build - image: docker:27-dind - services: - - docker:27-dind - before_script: - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $REGISTRY - - docker buildx create --use --name multiarch --driver docker-container - script: - - | - docker buildx build \ - --platform linux/arm64,linux/amd64 \ - --output type=image,name=${REGISTRY}/${IMAGE_NAME}:gzip,push=true,compression=gzip,oci-mediatypes=true \ - --cache-from type=registry,ref=${REGISTRY}/${IMAGE_NAME}:cache \ - . - rules: - - if: $CI_COMMIT_BRANCH == "main" - -# ----------------------------------------------------------------------------- -# Tag como versão -# ----------------------------------------------------------------------------- -push-tags: - stage: push - image: docker:27-cli - services: - - docker:27-dind - before_script: - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $REGISTRY - script: - - docker buildx imagetools create -t ${REGISTRY}/${IMAGE_NAME}:v1 ${REGISTRY}/${IMAGE_NAME}:latest - rules: - - if: $CI_COMMIT_BRANCH == "main" - needs: - - build-estargz diff --git a/aula-13/images/large-test/.gitlab-ci.yml b/aula-13/images/large-test/.gitlab-ci.yml deleted file mode 100644 index 69f96fc..0000000 --- a/aula-13/images/large-test/.gitlab-ci.yml +++ /dev/null @@ -1,38 +0,0 @@ -stages: - - build - -variables: - REGISTRY: gitea.kube.quest - IMAGE_NAME: factory/large-test - -build: - stage: build - image: docker:27-dind - services: - - docker:27-dind - variables: - DOCKER_TLS_CERTDIR: "" - DOCKER_HOST: tcp://docker:2375 - before_script: - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - - docker buildx create --use --name builder --driver docker-container - script: - # Build eStargz (lazy pulling) - - echo "Building eStargz version..." - - | - docker buildx build \ - --output type=image,name=${REGISTRY}/${IMAGE_NAME}:latest,push=true,compression=estargz,force-compression=true,oci-mediatypes=true \ - . - - # Build GZIP tradicional - - echo "Building GZIP version..." - - | - docker buildx build \ - --output type=image,name=${REGISTRY}/${IMAGE_NAME}:gzip,push=true,compression=gzip,oci-mediatypes=true \ - . - - - echo "Images pushed:" - - echo " - ${REGISTRY}/${IMAGE_NAME}:latest (eStargz ~1.5GB)" - - echo " - ${REGISTRY}/${IMAGE_NAME}:gzip (GZIP ~1.5GB)" - tags: - - kubernetes diff --git a/aula-13/k8s/postgresql/deployment.yaml b/aula-13/k8s/postgresql/deployment.yaml index 92e39c6..ae435b4 100644 --- a/aula-13/k8s/postgresql/deployment.yaml +++ b/aula-13/k8s/postgresql/deployment.yaml @@ -35,7 +35,8 @@ spec: containers: - name: postgresql # Imagem da Container Factory (eStargz) - image: gitea.kube.quest/factory/postgresql:17 + # Substitua GITEA_HOST pelo hostname do seu Gitea (ex: gitea.kube.quest) + image: GITEA_HOST_PLACEHOLDER/factory/postgresql:17 imagePullPolicy: IfNotPresent ports: diff --git a/aula-13/pipelines/postgresql/.gitlab-ci.yml b/aula-13/pipelines/postgresql/.gitlab-ci.yml deleted file mode 100644 index 5561727..0000000 --- a/aula-13/pipelines/postgresql/.gitlab-ci.yml +++ /dev/null @@ -1,183 +0,0 @@ -# ============================================================================= -# GitLab CI/CD Pipeline - PostgreSQL Container Factory -# ============================================================================= -# -# Build de imagem PostgreSQL customizada em formato eStargz. -# Push para registry.kube.quest com lazy pulling habilitado. -# -# Requisitos: -# - GitLab Runner com Docker-in-Docker (aula-11) -# - BuildKit habilitado -# -# Uso: -# 1. Criar grupo 'factory' no GitLab -# 2. Criar projeto 'postgresql' dentro do grupo -# 3. Copiar Dockerfile, postgresql.conf e este .gitlab-ci.yml -# 4. Push para main - pipeline roda automaticamente -# -# ============================================================================= - -stages: - - build - - test - - push - -variables: - # Registry do GitLab (aula-10) - REGISTRY: ${CI_REGISTRY} - IMAGE_NAME: ${CI_PROJECT_PATH} - POSTGRES_VERSION: "17" - - # BuildKit para suporte a eStargz - DOCKER_BUILDKIT: "1" - BUILDKIT_PROGRESS: plain - - # Docker-in-Docker TLS connection - DOCKER_HOST: tcp://docker:2376 - DOCKER_TLS_CERTDIR: "/certs" - DOCKER_CERT_PATH: "/certs/client" - DOCKER_TLS_VERIFY: "1" - -# ============================================================================= -# BUILD - Construir imagem em formato eStargz -# ============================================================================= -build: - stage: build - image: docker:24 - services: - - docker:24-dind - before_script: - # Aguardar Docker daemon estar pronto - - until docker info; do sleep 1; done - # Login no registry - - docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY} - # Configurar buildx com driver docker (usa daemon existente) - - docker buildx create --name estargz-builder --driver docker --use || true - - docker buildx inspect --bootstrap - script: - - echo "Building ${IMAGE_NAME}:${POSTGRES_VERSION}-${CI_COMMIT_SHA:0:8} with eStargz compression" - # Build com formato eStargz - - | - docker buildx build \ - --output type=image,name=${REGISTRY}/${IMAGE_NAME}:${POSTGRES_VERSION}-${CI_COMMIT_SHA:0:8},push=true,compression=estargz,force-compression=true,oci-mediatypes=true \ - --label "org.opencontainers.image.revision=${CI_COMMIT_SHA}" \ - --label "org.opencontainers.image.created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ - --label "org.opencontainers.image.source=${CI_PROJECT_URL}" \ - --build-arg POSTGRES_VERSION=${POSTGRES_VERSION} \ - . - rules: - - if: $CI_COMMIT_BRANCH == "main" - - if: $CI_COMMIT_TAG - tags: - - kubernetes - - docker - -# ============================================================================= -# TEST - Testar imagem construída -# ============================================================================= -test: - stage: test - image: docker:24 - services: - - docker:24-dind - before_script: - - until docker info; do sleep 1; done - - docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY} - script: - - echo "Testing PostgreSQL image..." - - # Iniciar container de teste - - | - docker run -d --name pg-test \ - -e POSTGRES_PASSWORD=testpassword \ - -e POSTGRES_DB=testdb \ - ${REGISTRY}/${IMAGE_NAME}:${POSTGRES_VERSION}-${CI_COMMIT_SHA:0:8} - - # Aguardar inicialização (30s max) - - | - for i in $(seq 1 30); do - if docker exec pg-test pg_isready -U postgres -d testdb 2>/dev/null; then - echo "PostgreSQL ready!" - break - fi - echo "Waiting for PostgreSQL... ($i/30)" - sleep 1 - done - - # Verificar healthcheck - - docker exec pg-test pg_isready -U postgres -d testdb - - # Testar conexão e queries básicas - - docker exec pg-test psql -U postgres -d testdb -c "SELECT version();" - - docker exec pg-test psql -U postgres -d testdb -c "SHOW shared_buffers;" - - docker exec pg-test psql -U postgres -d testdb -c "SHOW max_connections;" - - # Testar criação de tabela - - docker exec pg-test psql -U postgres -d testdb -c "CREATE TABLE test (id serial PRIMARY KEY, name text);" - - docker exec pg-test psql -U postgres -d testdb -c "INSERT INTO test (name) VALUES ('test');" - - docker exec pg-test psql -U postgres -d testdb -c "SELECT * FROM test;" - - docker exec pg-test psql -U postgres -d testdb -c "DROP TABLE test;" - - # Cleanup - - docker stop pg-test && docker rm pg-test - - echo "All tests passed!" - needs: - - build - rules: - - if: $CI_COMMIT_BRANCH == "main" - - if: $CI_COMMIT_TAG - tags: - - kubernetes - - docker - -# ============================================================================= -# PUSH - Tag como versão e latest -# ============================================================================= -push: - stage: push - image: docker:24 - services: - - docker:24-dind - before_script: - - until docker info; do sleep 1; done - - docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY} - - docker buildx create --name estargz-builder --driver docker --use || true - - docker buildx inspect --bootstrap - script: - - echo "Tagging and pushing final images..." - - # Re-tag como versão (17) - - | - docker buildx build \ - --output type=image,name=${REGISTRY}/${IMAGE_NAME}:${POSTGRES_VERSION},push=true,compression=estargz,force-compression=true,oci-mediatypes=true \ - --label "org.opencontainers.image.revision=${CI_COMMIT_SHA}" \ - --label "org.opencontainers.image.created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ - . - - # Re-tag como latest - - | - docker buildx build \ - --output type=image,name=${REGISTRY}/${IMAGE_NAME}:latest,push=true,compression=estargz,force-compression=true,oci-mediatypes=true \ - --label "org.opencontainers.image.revision=${CI_COMMIT_SHA}" \ - --label "org.opencontainers.image.created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ - . - - # Build versão GZIP (para benchmark) - - | - docker buildx build \ - --output type=image,name=${REGISTRY}/${IMAGE_NAME}:${POSTGRES_VERSION}-gzip,push=true,compression=gzip,oci-mediatypes=true \ - --label "org.opencontainers.image.revision=${CI_COMMIT_SHA}" \ - --label "org.opencontainers.image.created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ - . - - - echo "Images pushed:" - - echo " - ${REGISTRY}/${IMAGE_NAME}:${POSTGRES_VERSION} (eStargz)" - - echo " - ${REGISTRY}/${IMAGE_NAME}:${POSTGRES_VERSION}-gzip (tradicional)" - - echo " - ${REGISTRY}/${IMAGE_NAME}:latest (eStargz)" - needs: - - test - rules: - - if: $CI_COMMIT_BRANCH == "main" - tags: - - kubernetes - - docker diff --git a/aula-15/demo-app/tracing.js b/aula-15/demo-app/tracing.js index 0127691..b634f52 100644 --- a/aula-15/demo-app/tracing.js +++ b/aula-15/demo-app/tracing.js @@ -6,7 +6,7 @@ const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc') const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-grpc'); const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics'); -const otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://otel-collector.monitoring:4317'; +const otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://otel-collector-opentelemetry-collector.monitoring:4317'; const serviceName = process.env.OTEL_SERVICE_NAME || 'demo-app'; const traceExporter = new OTLPTraceExporter({