Содержание

Разворачиваем локальный Gitlab

Собственно в загаловке все сказано, а как это сделать можно прочитать в статье…

1 Добавляем новый контейнер LXD

Создаем отдельное хранилище:

1
lxc storage create gitlab zfs size=50GB

Копируем нужный образ ОС в локальное хранилище. В моем случае это Ubuntu 20.04

1
lxc image copy ubuntu:20.04/amd64 local: --alias=ubuntu2004

Создаем сам контейнер:

1
lxc init ubuntu2004 gitlab-server --storage=gitlab --profile=default

Переопределяем сетевой адаптер контейнера, чтобы он смотрел в нашу сеть через мост:

1
lxc config device add gitlab-server eth0 nic nictype=bridged parent=br0 name=eth0

Добавляем немного привилегий, чтобы внутри контейнера мог работать Docker:

1
lxc config set gitlab-server security.nesting true

Запускаем наш новоиспеченный контейнер:

1
lxc start gitlab-server

Далее запускаем bash в нашем контейнере и оказываемся в косоли ОС контейнера

1
lxc exec gitlab-server bash

2 Установка Gitlab

Далее мы действуем идем по описаной производителем схеме и делаем следющее:

1
2
3
sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates tzdata perl
sudo apt-get install -y postfix

Postfix я установил в режиме Local only, т.к. ни с какими внешними почтовыми серверами мне связь не нужна и оставил то доменное имя которое он мне предлогал, а именно то которое прописано в /etc/hostname и пошел дальше:

1
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash

И, собственно, устанавливаем сам Gitlab, где вместо https://gitlab.example.com указываем тот адрес по которому у нас будет откликаться наш Gitlab:

1
sudo EXTERNAL_URL="https://gitlab.example.com" apt-get install gitlab-ee

После этого того как установка прошла нам необходимо сменить пароль пользователя root (он же Administrator), который можно подсмотреть в файле /etc/gitlab/initial_root_password. Для этого заходим в браузере в наш Gitlab, в правом верхнем углу жмем на красивую аватарку и идем в Edit Profile->Password, вводим пароль который мы подсмотрели и два раза наш новый, затем жмем “Save password”. Готово!

3 Настройка после установки

3.1 Установка Docker Engine

Следуя инструкции производителя, которую можно посмотреть тут, мы понимаем, что нам бы еще не помешало настроить все что относится к CI/CD. Лично мне эта тема очень нравится и начнем с настройки runner’а, но runner мне нужен для сборки docker-контейнеров, т.ч. сначала установим его. Как говорится в официальной документации - удалим все лишнее, если оно есть

1
sudo apt-get remove docker docker-engine docker.io containerd runc

Установим все что нам может понадобиться для установки:

1
2
3
4
5
6
7
sudo apt-get update
sudo apt-get install \
   apt-transport-https \
   ca-certificates \
   curl \
   gnupg \
   lsb-release

Установим gpg-ключ для репозитория docker’а:

1
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

Добавим сам репозиторий:

1
2
3
echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Ну и собственно установим сам docker:

1
2
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

Так же хотелось бы чтобы я мог общаться с docker-engine без sudo, для этого я добавлю своего пользователя в группу docker

1
2
sudo groupadd docker
sudo usermod -aG docker hansom

3.2 Установка gitlab-runner

Далее перейдем к установке самого runner’a. Офицальная документация говорит что надо бы это делать на отдельных машинах, но у меня сервер только один и я буду ставить все на нем:

1
2
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo -E apt-get install gitlab-runner

Теперь нам нужно зарегистрировать наш раннер в gitlab’e. Для этого в браузере заходим в административный раздел и открываем раздел Overview->Runners, откуда мы будем брать registration token, затем консоли bash выполняем:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
sudo gitlab-runner register \
  --non-interactive \
  --url "https://gitlab.exampe.com/" \
  --registration-token "сюда вставляем наш токен" \
  --executor "docker" \
  --docker-image alpine:latest \
  --description "docker-runner" \
  --tag-list "docker,aws" \
  --run-untagged="true" \
  --locked="false" \
  --access-level="not_protected"

Если все правильно, то обновив страницу в браузере, мы должны увидеть наш gitlab-runner. После этого необходимо внести некоторые измененмя в файл натроек gitlab-runner’a. А именно: добавить привелегированный режим для запуска докера, это нужно чтобы работал docker:dind, и прописать монтирование docker.sock. Должно получиться примерно так:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
concurrent = 1
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "Main Runner"
  url = "http://gitlab.example.com/"
  token = "Token1Token2Token3"
  executor = "docker"

  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "ubuntu:20.04"
    privileged = true
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
    shm_size = 0

4 Настройка Gitlab Docker Registry (вариант 1: с использованием SSL-сертификатов)

Теперь нам нужна поддержка Docker Registry в Gitlab'e, чтобы мы могли в CI/CD Pipeline осуществзять сборку образов через “Docker in Docker” сервис, так чтобы они публиковались в соответствующем разделе прокекта в котором данная функциональность используется.

Для начала создадим сам т.н. реестр (registry) docker контейнеров. Для этого сначала сгенерируем самоподписанные сертификаты и ключи SSL. Хоть и основной домен у меня работает через HTTP, но и для него создадим сертификат тоже (на всякий случай):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
mkdir -p certs
openssl req \
  -subj '/C=RU/ST=Chelyaninsk/L=Chelyabinsk/O=Gitlab station/OU=gitlab/CN=User Name/emailAddress=your@mal.ru' \
  -newkey rsa:4096 -nodes -sha256 -keyout certs/gitlab.example.com.key \
  -addext "subjectAltName = DNS:gitlab.example.com" \
  -x509 -days 36525 -out certs/example.domain.com.crt
openssl req \
  -subj '/C=RU/ST=Chelyaninsk/L=Chelyabinsk/O=Gitlab station registry/OU=gitlab/CN=User Name/emailAddress=your@mal.ru' \
  -newkey rsa:4096 -nodes -sha256 -keyout certs/registry.example.com.key \
  -addext "subjectAltName = DNS:registry.example.com" \
  -x509 -days 36525 -out certs/registry.example.com.crt
sudo mkdir -p /etc/gitlab/ssl
sudo cp -v -f certs/gitlab.example.com.* /etc/gitlab/ssl/
sudo cp -v -f certs/registry.example.com.* /etc/gitlab/ssl/
sudo cp -v -f /var/opt/gitlab/registry/certs/registry.example.com.crt
sudo chown root:root /etc/gitlab/ssl/gitlab.example.com.*
sudo chown root:root /etc/gitlab/ssl/registry.example.com.*
sudo chown registry:registry /var/opt/gitlab/registry/certs/registry.example.com.crt
sudo chmod 600 /etc/gitlab/ssl/gitlab.example.com.*
sudo chmod 600 /etc/gitlab/ssl/registry.example.com.*
sudo chmod 644 /var/opt/gitlab/registry/certs/registry.example.com.crt

После этого можно поправить файл конфигурации /etc/gitlab/gitlab.rb, в котором нас интересуют секции “Container Registry settings” и “Registry NGINX”:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
################################################################################
## Container Registry settings
################################################################################

registry_external_url 'https://registry.example.com'
gitlab_rails['registry_enabled'] = true
gitlab_rails['registry_host'] = "registry.example.com"
gitlab_rails['registry_port'] = "5050"
gitlab_rails['registry_api_url'] = "http://localhost:5000"
gitlab_rails['registry_issuer'] = "omnibus-gitlab-issuer"

################################################################################
## Registry NGINX
################################################################################

registry_nginx['enable'] = true
registry_nginx['listen_port'] = 5050

Все остальное в этих разделах оставляем закомментированым. Сохраняем изменения и применяем конфигурацию:

1
sudo gitlab-ctl reconfigure

После этих манипуляций можно убедиться, что гитлаб слушает нужные нам порты выполнив комманду ss -l4n . В полученом списке мы должны увидеть среди прочих такие строки:

1
2
3
4
5
Netid                  State                   Recv-Q                  Send-Q                                       Local Address:Port                                   Peer Address:Port                 Process
...
tcp                    LISTEN                  0                       511                                                0.0.0.0:5050                                        0.0.0.0:*
tcp                    LISTEN                  0                       128                                              127.0.0.1:5000                                        0.0.0.0:*
...

Теперь, когда API заработало, можно подключить к нему сам реестр. Для этого создадим файл docker-compose.yml со следующим содержимым:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
version: '2'
services:
  gitlabregistry:
    restart: always
    image: registry:latest
    ports:
      - 5005:5000
    volumes:
      - /var/opt/gitlab/gitlab-rails/shared/registry:/var/lib/registry
      - /var/opt/gitlab/registry:/root/newcerts
    environment:
      - REGISTRY_LOG_LEVEL=info
      - REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/registry
      - REGISTRY_AUTH_TOKEN_REALM=https://registry.example.com/jwt/auth
      - REGISTRY_AUTH_TOKEN_SERVICE=container_registry
      - REGISTRY_AUTH_TOKEN_ISSUER=omnibus-gitlab-issuer
      - REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE=/root/newcerts/registry.example.com.crt
      - REGISTRY_STORAGE_DELETE_ENABLED=true

Запускаем наше хранилище (registry) docker-контейнеров:

1
docker-compose up -d

Если все нормально, то вывод команды docker ps должен выглядеть примерно так:

1
2
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS                                       NAMES
7199ee1fbb76   registry:latest   "/entrypoint.sh /etc…"   5 minutes ago    Up 5 minutes    0.0.0.0:5005->5000/tcp, :::5005->5000/tcp   registry_gitlabregistry_1

Следующим шагом будет установка нашего сертификата (можно сразу обоих) в хранилище корневых сертификатов, чтобы при выполнении команды docker login gitlab.example.com:5050 не возникало ошибки подобного вида:

1
2
Couldn't execute POST against https://hostname.tld/api/v4/jobs/request:
  Post https://hostname.tld/api/v4/jobs/request: x509: certificate signed by unknown authority

Для Linux:

1
2
3
4
sudo cp -v examle.example.com.crt /usr/local/share/ca-certificates/
sudo cp -v registry.example.com.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates --fresh
sudo systemctl restart docker.service

В Windows нужно открыть файл каждого сертификата с помощю приложения “Мастер импорта сертификатов”, который скопирует их в хранилище сертификатов. Делаем следующие шаги:

  • Расположение хранилища: Локальный компьютер -> Далее
  • Хранилище: Поместить сертификаты в следующее хранилище->Обзор->Доверенные корневые центры сертификации->OK->Далее
  • Завершение мастера импорта сертификатов: Готово

Данную процедуру будет необходимо выполнять на каждом новом хосте, который будет подключаться к нашему docker registry впервые. Проверяем подключение, выполнив docker login gitlab.example.com:5050. Псоле чего мы должны увидеть следующее:

1
2
3
4
5
6
7
Username: username
Password:
WARNING! Your password will be stored unencrypted in /home/username/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

5 Настройка Gitlab Docker Registry (вариант 2: insecure-registies)

Это вариант менее секьюрный (оно может и не надо в рамках локальной сети), но проще в обращении. Он подразумевает отсутствие шифрования в канале обмена “docker engine” и “gitlab-api”

Генерируем ключ для общения gitlab-api с docker registry

1
2
3
4
5
6
7
8
9
mkdir -p certs
openssl req \
  -subj '/C=RU/ST=Chelyaninsk/L=Chelyabinsk/O=Gitlab station registry/OU=gitlab/CN=User Name/emailAddress=your@mal.ru' \
  -newkey rsa:4096 -nodes -sha256 -keyout certs/registry.example.com.key \
  -addext "subjectAltName = DNS:registry.example.com" \
  -x509 -days 36525 -out certs/registry.example.com.crt
sudo cp -v -f /var/opt/gitlab/registry/certs/registry.example.com.crt
sudo chown registry:registry /var/opt/gitlab/registry/certs/registry.example.com.crt
sudo chmod 644 /var/opt/gitlab/registry/certs/registry.example.com.crt

Конфигурация gitlab’a /etc/gitlab/gitlab.rb будет выглядет так:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
################################################################################
## Container Registry settings
##! Docs: https://docs.gitlab.com/ee/administration/container_registry.html
################################################################################

registry_external_url 'http://registry.example.com'
gitlab_rails['registry_enabled'] = true
gitlab_rails['registry_host'] = "registry.example.com"
gitlab_rails['registry_api_url'] = "http://localhost:5000"
gitlab_rails['registry_issuer'] = "omnibus-gitlab-issuer"

Все остальное в этом разделе и “Registry NGINX” остается закоментированым.

Применяем конфигурацию gitlab:

1
sudo gitlab-ctl reconfigure

Процедура запуска реестра docker’a идентична первому варианту.

Чтобы не получать сообщение от докера во время выполнения команы docker login registry.example.com о том что “от HTTPS сервиса получен HTTP ответ” надо содать файл /etc/docker/daemon.json со следующим содержимым:

1
2
3
{
  "insecure-registries" : ["registry.example.com"]
}

Так нужно будет делать на всех машинах где установлен докер, но плюс в том, что не нужно таскать за собой сертификаты и заниматься их установкой

На этом пожалуй все. Если все сделать правильно, то сюрпризов быть не должно.