Введение — какую проблему решаем

При использовании GitLab CI/CD с Kubernetes возникает необходимость видеть связку между логами и конкретными CI job'ами или pipeline'ами. Это особенно полезно для отладки и мониторинга. Однако по умолчанию логи из подов не содержат этих связующих метаданных.

В данной статье мы покажем, как можно передавать метки job_idpipeline_idproject_name и другие из GitLab Runner в систему логирования VictoriaLogs с помощью Promtail и систему мониторинга VictoriaMetrics.

Почему используем VictoriaLogs, а не Loki

  • Мгновенный полнотекстовый поиск по любым полям логов (включая высококардинальные, такие как job_id или pipeline_id), без необходимости предварительной настройки схемы. В Loki подобные запросы требуют осторожного управления метками и могут приводить к резкому росту потребления памяти.

  • Экономия ресурсов: колоночное хранение как ClickHouse с автоматическим сжатием сокращает объём данных на диске в 5–10 раз по сравнению с Loki, а также ускоряет аналитические запросы.

  • Простота запросов: интуитивный язык LogsQL удобен для фильтрации, агрегации и анализа, тогда как LogQL в Loki часто требует сложных конструкций для базовых задач.

  • Производительность: типовые запросы выполняются до 1000x быстрее, чем в Loki, благодаря оптимизированным алгоритмам индексации и отсутствию накладных расходов распределённых систем.

Регистрация GitLab Runner в gitlab.com

Перед установкой runner'а необходимо зарегистрировать его в GitLab:

  1. Перейдите в репозиторий GitLab.

  2. Откройте Settings -> CI/CD -> Runners.

  3. Выключите общие раннеры

  4. Скопируйте registration token.

Этот токен понадобится для регистрации раннера в вашем Kubernetes-кластере.

Установка Kubernetes

Установка kubernetes через terraform

git clone https://github.com/patsevanton/gitlab-job-labels-to-victorialogs
export YC_FOLDER_ID='ваш folder_id'
terraform init
terraform apply

Установка VictoriaLogs

helm repo add vm https://victoriametrics.github.io/helm-charts/
helm repo update

helm upgrade --install victorialogs vm/victoria-logs-single \
  --namespace victorialogs --create-namespace \
  --values victorialogs-values.yaml

После установки, victorialogs будет доступен по адресу http://victorialogs.apatsev.org.ru

Установка victoria-metrics-k8s-stack

Добавим Helm репозиторий и установим VictoriaMetrics stack:

helm repo add vm https://victoriametrics.github.io/helm-charts/
helm repo update

helm upgrade --install vmks vm/victoria-metrics-k8s-stack \
  --namespace vmks --create-namespace \
  --values vmks-values.yaml

В vmks-values.yaml указано что kube-state-metrics, разрешая экспорт всех метрик ([*]), связанных с подами (pods).

kube-state-metrics:
  metricLabelsAllowlist:
    - pods=[*]

Подробности в values kube-state-metrics и victoria-metrics-k8s-stack: https://github.com/prometheus-community/helm-charts/blob/main/charts/kube-state-metrics/values.yaml#L397 https://github.com/VictoriaMetrics/helm-charts/blob/master/charts/victoria-metrics-k8s-stack/values.yaml#L975C1-L975C19

После установки, Grafana будет доступна по адресу http://grafana.apatsev.org.ru

Получение пароля grafana для admin юзера

kubectl get secret vmks-grafana -n vmks -o jsonpath='{.data.admin-password}' | base64 --decode

Установка Promtail

helm upgrade --install promtail grafana/promtail \
  --namespace promtail --create-namespace \
  --values promtail-values.yaml

Файл конфигурации Promtail promtail-values.yaml:

tolerations:
  - operator: Exists
    effect: NoSchedule
config:
  clients:
    - url: http://victorialogs-victoria-logs-single-server.victorialogs.svc.cluster.local:9428/insert/loki/api/v1/push?_msg_field=msg
  snippets:
    pipelineStages:
      - cri: {}
      - labeldrop:
          - filename
          - node_name
    extraRelabelConfigs:
      - action: keep
        source_labels:
          - __meta_kubernetes_namespace
        regex: gitlab-runner
      - action: replace
        source_labels:
          - __meta_kubernetes_pod_label_job_id
        target_label: job_id
      - action: replace
        source_labels:
          - __meta_kubernetes_pod_label_job_name
        target_label: job_name
      - action: replace
        source_labels:
          - __meta_kubernetes_pod_label_pipeline_id
        target_label: pipeline_id
      - action: replace
        source_labels:
          - __meta_kubernetes_pod_label_project_id
        target_label: project_id
      - action: replace
        source_labels:
          - __meta_kubernetes_pod_label_project_name
        target_label: project_name

Установка GitLab Runner через Helm:

helm repo add gitlab https://charts.gitlab.io
helm repo update

export RUNNER_TOKEN="glrt-xxx.xxxxx"  # экспортируйте gitlab-runner токен

helm upgrade --install gitlab-runner gitlab/gitlab-runner \
  --namespace gitlab-runner --create-namespace \
  --values gitlab-runner-values.yaml \
  --set-string runnerToken="$RUNNER_TOKEN"

Пример gitlab-runner-values.yaml:

gitlabUrl: "https://gitlab.com/"
runners:
  config: |
    [[runners]]
      [runners.kubernetes]
        helper_cpu_request = "250m"
        helper_memory_limit = "512Mi"
        [runners.kubernetes.pod_labels]
          "job_name" = "${CI_JOB_NAME_SLUG}"
          "job_id" = "${CI_JOB_ID}"
          "project_name" = "${CI_PROJECT_NAME}"
          "project_id" = "${CI_PROJECT_ID}"
          "pipeline_id" = "${CI_PIPELINE_ID}"
metrics:
  enabled: true
  serviceMonitor:
    enabled: true
service:
  enabled: true
rbac:
  create: true

Проверка, что у pod есть label

Запустите сборку на этом раннере и проверьте label Должно быть примерно так

kubectl get pod -n gitlab-runner --show-labels | grep -E '(job_name|job_id|project_name|project_id|pipeline_id)'
runner-sijwob5yi-project-69309276-concurrent-0-7hr533es   2/2     Running   0          16s     ...,job_id=9895041344,job_name=deploy-job,pipeline_id=1796027502,pod=runner-sijwob5yi-project-69309276-concurrent-0,project_id=69309276,project_name=gitlab-for-job-labels-to-victorialogs
runner-sijwob5yi-project-69309276-concurrent-0-pfirp5t5   2/2     Running   0          49s     ...,job_id=9895041322,job_name=unit-test-job,pipeline_id=1796027502,pod=runner-sijwob5yi-project-69309276-concurrent-0,project_id=69309276,project_name=gitlab-for-job-labels-to-victorialogs
runner-sijwob5yi-project-69309276-concurrent-1-85wx1m9n   2/2     Running   0          44s     ...,job_id=9895041335,job_name=lint-test-job,pipeline_id=1796027502,pod=runner-sijwob5yi-project-69309276-concurrent-1,project_id=69309276,project_name=gitlab-for-job-labels-to-victorialog

Отображение failed строк в логах с фильтрацией по job_id

Failed строка появляется не в pod runner-xxx-project-yyy-concurrent-0-zzz, а в pod gitlab-runner-xxx-yyy. Вот issue. Поэтому для отображения failed строк при падении job необходимо использовать after_script с проверкой $CI_JOB_STATUS. Пример gitlab-ci.yaml:

image: alpine:latest
stages:
  - build
  - test
  - deploy
build-job:
  stage: build
  script:
    - echo "$CI_JOB_ID"
    - exit 1
  allow_failure: true
  after_script:
    - |
      if [ "$CI_JOB_STATUS" != "success" ]; then
        echo "ERROR: Job failed: command terminated with non-zero exit code"
      fi

Просмотр как это выглядит в VictoriaLogs

  1. Зайдите в UI VictoriaLogs (обычно на /select/) или подключитесь к Grafana.

  2. Выполните запросы с фильтрацией по job_idpipeline_id, например:

pipeline_id: "1809184207" job_id: "9984945726"

или

{job_id="9984945726",pipeline_id="1809184207"}

Теперь вы можете фильтровать логи по job, pipeline и другим CI-метаданным, что значительно упрощает отладку и мониторинг процессов.

Grafana Dashboard

Импортируйте дашборд dashboard.json В Grafana будут видны метки, переданные из GitLab Runner (job_idpipeline_id и т.д.). Выглядит вот так: 

Удаление через terraform

terraform destroy

Исходный код

Исходный код находится здесь https://github.com/patsevanton/gitlab-job-labels-to-victorialogs/tree/main

Заключение

Теперь вы можете легко отслеживать, какие логи/метрики относятся к какому pipeline и job'у. Использование VictoriaLogs позволяет справляться с большим объемом уникальных меток. Этот подход хорошо масштабируется и обеспечивает гибкую, но мощную систему обсервабилити для CI/CD процессов в Kubernetes. С добавлением всего нескольких строк в конфигурацию вы получаете мощный инструмент для мониторинга и отладки CI/CD pipeline'ов.

Telegram канал:

Подписывайтесь на мой telegram канал https://t.me/notes_devops_engineer