Ir para o conteúdo principal

GitLab-managed Kubernetes resources

O que é GitLab-managed Kubernetes resources

É uma funcionalidade do GitLab Agent for Kubernetes que permite ao GitLab criar e gerenciar recursos Kubernetes de forma automática e centralizada, fora do pipeline de CI/CD, sem que cada projeto precise se preocupar com isso.

A ideia é simples: o GitLab Agent (o agentk rodando no cluster) lê templates YAML de um repositório Git e os aplica automaticamente no cluster quando determinadas condições acontecem, como a criação ou atualização de um Environment.


Como funciona na prática

O mecanismo possui três peças principais.

1. O arquivo config.yaml do agente

Ele habilita o gerenciamento automático de recursos para um grupo.

# k8s-agents/.gitlab/agents/sites-k8s-0/config.yaml

- id: marcosxavier
  access_as:
    ci_job: {}
  resource_management:
    enabled: true

Isso diz ao agente:

Quando qualquer projeto do grupo marcosxavier criar ou atualizar um Environment, recursos Kubernetes gerenciados poderão ser aplicados automaticamente.


2. O arquivo environment_templates/default.yaml

Esse arquivo define quais recursos serão criados no cluster.

objects:
  - kind: Namespace
    metadata:
      name: 'gl-{{ .project.id }}'

  - kind: RoleBinding
    metadata:
      name: 'gitlab-ci-{{ .project.id }}'
      namespace: 'gl-{{ .project.id }}'
    roleRef:
      kind: ClusterRole
      name: admin
    subjects:
      - kind: Group
        name: 'gitlab:project_env:{{ .project.id }}:{{ .environment.slug }}'

apply_resources: on_start
delete_resources: never

As variáveis abaixo são preenchidas automaticamente pelo GitLab:

Variável Exemplo
{{ .project.id }} 1568
{{ .environment.slug }} producao

Você não define esses valores manualmente.

O GitLab substitui pelos valores reais do projeto durante a execução.


3. O bloco environment no .gitlab-ci.yml

É ele que dispara todo o mecanismo.

environment:
  name: producao

  kubernetes:
    agent: dtr/k8s-agents:sites-k8s-0

    managed_resources:
      enabled: true

    dashboard:
      namespace: gl-$CI_PROJECT_ID

Quando o job de deploy inicia e declara esse Environment, o GitLab Agent detecta o evento e aplica automaticamente o template definido em environment_templates/default.yaml.

Antes mesmo do primeiro kubectl apply, já existirão:

Namespace:   gl-1568
RoleBinding: gitlab-ci-1568

O que o default.yaml cria para o meditation-timer

Considerando:

CI_PROJECT_ID = 1568
environment.slug = producao

O agente cria:

Recurso Nome Finalidade
Namespace gl-1568 Isola todos os recursos do projeto
RoleBinding gitlab-ci-1568 Concede permissões administrativas namespaced ao CI Job

Quem recebe as permissões?

O RoleBinding aponta para:

gitlab:project_env:1568:producao

Essa identidade:

  • Não é um usuário real.
  • Não é uma ServiceAccount.
  • Não existe fisicamente no cluster.

É uma identidade virtual criada pelo GitLab Agent quando o pipeline executa usando:

access_as:
  ci_job: {}

O Kubernetes reconhece essa identidade através do mecanismo de impersonation do Agent.


Resultado prático

O pipeline consegue executar comandos como:

kubectl apply
kubectl set image
kubectl rollout status

Sem precisar de:

  • kubeconfig manual
  • ServiceAccount dedicada
  • token Kubernetes salvo em variável CI
  • certificado armazenado no GitLab

Toda a autenticação passa pelo GitLab Agent.


Como isso se encaixa no pipeline atual

O job de deploy possui verificações explícitas:

script:
  # Confirma que o namespace foi criado.

  - kubectl get namespace "$KUBE_NAMESPACE"

  # Confirma que o job possui RBAC.

  - test "$(kubectl auth can-i create rolebindings ...)" = "yes"

Essas verificações funcionam como um health check.

Se o Namespace ou RBAC não existirem, o deploy falha imediatamente.


Aplicação dos manifests

Depois das verificações:

kubectl apply -f k8s/

São aplicados:

deployment.yaml
service.yaml
ingress.yaml

Nenhum deles possui:

metadata:
  namespace:

hardcoded.

O namespace é informado pelo pipeline:

--namespace="$KUBE_NAMESPACE"

Isso evita conflitos e reaproveita os mesmos manifests em diferentes ambientes.


Qual a diferença entre GitLab-managed resources e Helm?

Embora ambos atuem em Kubernetes, eles resolvem problemas diferentes.

GitLab-managed Kubernetes resources

Responsável por:

  • Namespace
  • RBAC
  • ResourceQuota
  • LimitRange
  • Labels
  • Annotations
  • Recursos de suporte ao ambiente

Ele prepara o terreno para a aplicação.

Não sabe nada sobre a aplicação em si.


Helm

Responsável pela aplicação.

Gerencia:

  • Deployments
  • Services
  • Ingresses
  • ConfigMaps
  • Secrets
  • PVCs
  • Outros manifests da aplicação

Utiliza:

Chart.yaml
values.yaml
templates/

e é executado através de:

helm upgrade --install

Também oferece:

  • versionamento
  • rollback
  • parametrização
  • múltiplos ambientes

Situação atual do meditation-timer

Atualmente o projeto utiliza:

GitLab-managed resources
+
kubectl apply

Sem Helm.

Isso faz sentido porque o projeto possui poucos manifests:

Deployment
Service
Ingress

e apenas um ambiente principal.


Quando Helm começaria a valer a pena?

Quando surgirem cenários como:

  • staging e produção
  • múltiplos namespaces
  • muitos parâmetros configuráveis
  • necessidade frequente de rollback
  • reutilização entre projetos

Nesses casos Helm simplifica bastante o gerenciamento.


Arquitetura considerada ideal

GitLab-managed resources
        │
        ├─► Namespace
        ├─► RBAC
        ├─► Quotas
        └─► Infraestrutura básica

Helm / ArgoCD
        │
        ├─► Deployment
        ├─► Service
        ├─► Ingress
        ├─► ConfigMap
        └─► Secrets

No cenário atual da UFSC, o ArgoCD está sendo avaliado justamente para assumir essa segunda camada.


Resumo visual do fluxo completo

push no GitLab
      │
      ▼
pipeline dispara
      │
      ├─► job build
      │      │
      │      └─► docker build
      │             +
      │         docker push
      │
      └─► job deploy
              │
              ├─► environment: producao
              │
              ▼
      GitLab Agent detecta evento
              │
              ▼
      environment_templates/default.yaml
              │
              ├─► Namespace gl-1568
              │
              └─► RoleBinding gitlab-ci-1568
              │
              ▼
      kubectl apply -f k8s/
              │
              ├─► Deployment
              ├─► Service
              └─► Ingress
              │
              ▼
      kubectl set image
              │
              ▼
      kubectl rollout status

O GitLab-managed resources atua antes do deploy da aplicação.

Ele prepara o ambiente para que o pipeline possa fazer o deploy com segurança e sem credenciais Kubernetes armazenadas manualmente.