Продолжаю разбираться с GitLab. Установил docker runner для сборки и тестирования тестового проекта «hello». И внезапно возник вопрос — а как это работает? В общих чертах понятно, но как более детально?

В pipeline я добавил команду sleep на 30 минут, которая задержит выполнение и даст провести кое-какие эксперименты:

build:
  stage: build
  image: alpine:latest
  tags:
    - build
  script:
    - cat /etc/os-release
    - sleep 1800

Ищем PID процесса

Теперь на сервере, где запущен этот runner, находим процесс:

ps aux | grep sleep

Получился такой вывод:

root      909153  0.0  0.0   1612     8 ?        S    00:07   0:00 sleep 1800

909153 — PID процесса. Посмотреть командную строку можно так:

cat /proc/909153/cmdline
# вывод:
sleep1800

Однако аргументы в ней перечислены через нулевой символ, и поэтому плохо читаются. Это можно исправить 2 способами:

# 1 способ
cat /proc/PID/cmdline | tr '\000' ' '
# 2 способ
cat /proc/PID/cmdline | xargs -0 echo
# вывод:
sleep 1800

Хорошо, теперь нужно найти всю цепочку родителей. Делается так:

pstree -sg 909153
# Вывод
systemd(1)───containerd-shim(909074)───sh(909099)───sh(909099)───sleep(909099)

Ищем билд-контейнер

Теперь попробуем найти контейнер, в котором запущена эта команда. Для этого я определил функцию, которую сохранил в ~/.zshrc. Также будет работать способ: просто вставить в терминал.

# Определение контейнера по PID процесса в системе (ps aux | grep php-fpm, например)
pidcont(){SCAN_PID=`pstree -sg $1 | head -n 1 | grep -Po 'shim\([0-9]+\)---.*?\(\K[^)]*'`; docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Name}}' | grep "${SCAN_PID}"}

Затем вызываем:

pidcont 909153

Этот скрипт взят из enSO и доработал регулярку. Вывод:

909099, /runner-1osnsbqh-project-6-concurrent-0-73b16fd95f3e5d07-build-2

Рассматриваем билд-контейнер

Отлично, теперь у нас есть название контейнера.

Посмотрим, что выдаст эта команда:

docker inspect runner-1osnsbqh-project-6-concurrent-0-73b16fd95f3e5d07-build-2

Из интересного — делаются docker volume, которые монтируются в /cache и /build. Можно посмотреть переменные окружения (CI_* и другие).

Входим в контейнер:

docker exec -it runner-1osnsbqh-project-6-concurrent-0-73b16fd95f3e5d07-build-2 sh

Смотрим процессы:

# ps
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh
   10 root      0:00 /bin/sh
   13 root      0:00 sleep 1800
   20 root      0:00 sh
   26 root      0:00 ps

Теперь мы находимся внутри контейнера, в котором происходит сборка, и можем делать что угодно! Например, посмотреть все переменные окружения:

# cat /proc/1/environ | tr '\000' ' '
# вывод (сокращен)
FF_USE_WINDOWS_LEGACY_PROCESS_STRATEGY=true FF_SCRIPT_SECTIONS=false FF_POSIXLY_CORRECT_ESCAPES=false CI_BUILD_ID=20 ...

Затем я перешел в каталог «build», где происходит сборка проекта. Там оказался ожидаемый каталог «hello» и в добавок к нему — «hello.tmp»:

.
├── hello
│   ├── README.md
│   └── docker-compose.yml
└── hello.tmp
    ├── CI_SERVER_TLS_CA_FILE
    └── git-template
        └── config

В этом tmp-каталоге находится сертификат и конфигурация git. Ничего интересного.

Под конец я убил основной sleep: kill 13. Это привело с завершению работы контейнера, а в GitLab высветилось сообщение:

ERROR: Job failed: exit code 143

gitlab-ctl

Напоследок — немного об этой команде. GitLab у меня запущен в докер-контейнере. Что именно там работает было секретом для меня. Конечно, можно посмотреть сорцы. Я сделал проще:

# Входим в контейнер
docker-compose exec gitlab bash
# Запускаем получение статусов
gitlab-ctl status
run: gitaly: (pid 291) 829684s; run: log: (pid 340) 829681s
run: gitlab-kas: (pid 524) 829672s; run: log: (pid 545) 829669s
run: gitlab-workhorse: (pid 752) 829620s; run: log: (pid 635) 829651s
run: logrotate: (pid 162536) 1689s; run: log: (pid 270) 829695s
run: nginx: (pid 638) 829648s; run: log: (pid 653) 829645s
run: postgresql: (pid 422) 829678s; run: log: (pid 434) 829675s
run: puma: (pid 548) 829666s; run: log: (pid 557) 829663s
run: redis: (pid 274) 829690s; run: log: (pid 288) 829687s
run: registry: (pid 770) 829620s; run: log: (pid 696) 829639s
run: sidekiq: (pid 561) 829660s; run: log: (pid 576) 829659s
run: sshd: (pid 31) 829706s; run: log: (pid 30) 829706s

Таким способом получаем список всех компонентов.

От debitos

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *