LINUX.ORG.RU
решено ФорумAdmin

Gitlab + Docker Registry

 ,


1

2

Есть 2 машинки ubuntu 18.04, на одной gitlib omnibus последний, на второй, соответственно, докер с запущенным контейнером реестра. Надо связать эти два сервиса, пользовался офф. документацией.

По сертификатам: есть 1 сертификат wildcard для *.domain.com, он же и используется для гитлаба по адресу tempgitlab.domain.com, он же и используется реестром. Плюс:

A certificate keypair is required for GitLab and the Container Registry to communicate securely.

openssl req -nodes -newkey rsa:4096 -keyout registry-auth.key -out registry-auth.csr -subj "/CN=gitlab-issuer"
openssl x509 -in registry-auth.csr -out registry-auth.crt -req -signkey registry-auth.key -days 3650

Реестр запускается как-то так:

docker run -d --restart=always -p 443:443 --name registry -v /home/ubuntu/certs:/certs   -v /etc/gitlab/registry-certs:/etc/gitlab/registry-certs   -e REGISTRY_AUTH_TOKEN_REALM=https://tempgitlab.domain.com/jwt/auth   -e REGISTRY_AUTH_TOKEN_SERVICE=container_registry   -e REGISTRY_AUTH_TOKEN_ISSUER=gitlab-issuer   -e REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE=/etc/gitlab/registry-certs/registry-auth.crt   -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt   -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key   --name docker-registry   registry:2

Конфиг гитлаба

registry_external_url 'https://registry.domain.com/'
gitlab_rails['registry_enabled'] = true
gitlab_rails['registry_host'] = "registry.domain.com"
gitlab_rails['registry_port'] = "443"
# gitlab_rails['registry_path'] = "/var/opt/gitlab/gitlab-rails/shared/registry"
registry['internal_key'] = "-----BEGIN RSA PRIVATE KEY-----\nMi............."
gitlab_rails['registry_api_url'] = "https://registry.domain.com:443"
gitlab_rails['registry_key_path'] = "/etc/gitlab/registry-certs/registry-auth.key"
gitlab_rails['registry_issuer'] = "gitlab-issuer"

В итоге я могу авторизовываться в реестре используя креды от гитлаба. Всё работает отлично, пушить могу только если у меня в этом репозитории есть права.

А вот гитлаб при обращении к реестру испытывает дискомфорт, если зайти на страницу с проектом, а оттуда > Registry, то в браузере будет ошибка 500, вместо страницы с моими залитыми образами.

Собственно лог в докере :

2018/12/22 10:35:26 http: TLS handshake error from 192.168.78.131:43818: remote error: tls: unknown certificate authority

Лог в гитлабе

Completed 500 Internal Server Error in 58ms (ActiveRecord: 3.1ms | Elasticsearch: 0.0ms)

Faraday::SSLError (SSL_connect returned=1 errno=0 state=error: certificate verify failed):
  lib/container_registry/client.rb:21:in `repository_tags'
  app/models/container_repository.rb:38:in `manifest'
  app/models/container_repository.rb:43:in `tags'
  app/models/container_repository.rb:55:in `has_tags?'
  lib/gitlab/metrics/instrumentation.rb:159:in `block in has_tags?'
  lib/gitlab/metrics/method_call.rb:34:in `measure'
  lib/gitlab/metrics/instrumentation.rb:159:in `has_tags?'
  app/controllers/projects/registry/repositories_controller.rb:46:in `block (2 levels) in ensure_root_container_repository!'
  app/controllers/projects/registry/repositories_controller.rb:45:in `tap'
  app/controllers/projects/registry/repositories_controller.rb:45:in `block in ensure_root_container_repository!'
  app/controllers/projects/registry/repositories_controller.rb:42:in `tap'
  app/controllers/projects/registry/repositories_controller.rb:42:in `ensure_root_container_repository!'
  lib/gitlab/i18n.rb:55:in `with_locale'
  lib/gitlab/i18n.rb:61:in `with_user_locale'
  app/controllers/application_controller.rb:427:in `set_locale'
  lib/gitlab/middleware/multipart.rb:101:in `call'
  lib/gitlab/request_profiler/middleware.rb:14:in `call'
  ee/lib/gitlab/jira/middleware.rb:15:in `call'
  lib/gitlab/middleware/go.rb:17:in `call'
  lib/gitlab/etag_caching/middleware.rb:11:in `call'
  lib/gitlab/middleware/rails_queue_duration.rb:22:in `call'
  lib/gitlab/metrics/rack_middleware.rb:15:in `block in call'
  lib/gitlab/metrics/transaction.rb:53:in `run'
  lib/gitlab/metrics/rack_middleware.rb:15:in `call'
  lib/gitlab/middleware/read_only/controller.rb:40:in `call'
  lib/gitlab/middleware/read_only.rb:16:in `call'
  lib/gitlab/middleware/basic_health_check.rb:25:in `call'
  lib/gitlab/request_context.rb:20:in `call'
  lib/gitlab/metrics/requests_rack_middleware.rb:27:in `call'
  lib/gitlab/middleware/release_env.rb:10:in `call'

Если честно, уже крыша едет от этих сертификатов, может кто сталкивался, или может я упускаю что-то очевидное?


Нет доверия

Имхо, в гитлабе нужно каким-нибудь образом указать на то, что сертификат (который у тебя самоподписанный) - валидный. Собственно, ошибка об отсутствии доверия и говорит.

Demacr ()
Install Custom Public Certificates:
Generate the PEM or DER encoded public certificate from your private key certificate.
Copy the public certificate file only into the /etc/gitlab/trusted-certs directory.
Run gitlab-ctl reconfigure.
Demacr ()
Ответ на: комментарий от Demacr

Но скорее всего тебе сюда.

Насколько я помню, такая ошибка была, если бы я использовал самоподписанный или неопознанный сертификат для самого реестра, а не для его связи с гитлабом. для REGISTRY_HTTP_TLS_CERT, а не для REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE

и это у докера, при попытке соединиться с реестром.

Generate the PEM or DER encoded public certificate from your private key certificate.Copy the public certificate file only into the /etc/gitlab/trusted-certs directory. Run gitlab-ctl reconfigure.

не помогло. ну, как.. cat domain.key > domain.pem && cat domain.crt >> domain.pem и переместил в эту директорию. ошибка на месте

Wulf ()
Последнее исправление: Wulf (всего исправлений: 1)

Напиши в гитлабовскую поддержку.
Может подскажут. :)

blackst0ne ★★★★★ ()

Я правильно понимаю, что ты не используешь встроенный в гитлаб реестр, а пытаешься прикрутить внешний?

deadNightTiger ★★★★ ()
Ответ на: комментарий от deadNightTiger

Ага…

Чот как-то все запутано. Но спасибо.

Deleted ()

Если чо, у меня так и неполучилось отпилить и вынести registry из контейнера gitlab. Буду рад если у тебя получится, отпишись тогда.

BigAlex ★★★ ()
Ответ на: комментарий от Deleted

Судя по тому конфигу - там юзеры подготовлены заранее. А мне необходимо, чтобы не просто была авторизация по юзерам гитлаба (а там вообще лдап), но и чтобы можно было заливать образы только в те проекты, в которые есть доступ. И это уже работает.

Wulf ()

Вообще, может это натолкнёт на мысль. Похоже, дело не в самоподписанном сертификате.

openssl s_client -connect registry.domain.com:443 CONNECTED(00000003) depth=0 OU = Domain Control Validated, OU = PositiveSSL Wildcard, CN = *.domain.com verify error:num=20:unable to get local issuer certificate verify return:1 depth=0 OU = Domain Control Validated, OU = PositiveSSL Wildcard, CN = *.domain.com verify error:num=21:unable to verify the first certificate verify return:1

Wulf ()
Ответ на: комментарий от Wulf

Там ещё

No client certificate CA names sent Peer signing digest: SHA384 Server Temp Key: ECDH, P-256, 256 bits

Wulf ()
Ответ на: комментарий от BigAlex

к слову, всё работает у меня. Сейчас занят чутка своими штуками, нужно ещё zabbix агент настроить, бэкапы, выставить наружу и связать с нетестовым гитлабом. Потом, если интересно, могу тут описать конфигурацию

Wulf ()
Ответ на: комментарий от inkyspot

Docker Registry

Docker Registry - реестр образов в привязкой к нашему gitlab.domain.com

Сертификаты

Для работы реестра используется наш wildcard сертификат + key-pair для общения реестра с гитлабом.

$ openssl req -nodes -newkey rsa:4096 -keyout registry-auth1.key -out registry-auth1.csr -subj "/CN=gitlab-issuer" 
$ openssl x509 -in registry-auth1.csr -out registry-auth1.crt -req -signkey registry-auth1.key -days 3650
$  ls /home/regadmin/certs
registry.domain.com.crt  registry.domain.com.key  registry-auth1.crt

VM, nginx

vSphere. Nginx слушает на 443 порту и направляет все запросы внутрь на контейнер, который слушает на 5000 порту. Реестр выставлен наружу через наш прокси, следовательно, на прокси сервере тоже есть запись в nginx’e. При этом сертификата wildcard на прокси недостаточно. Заставить работать контейнер таким способом не удалось, поэтому сертификаты подключены и в nginx на сервере реестра. Иметь в виду при обновлении.

Контейнер

Запущен докер-контейнер реестра при помощи docker-compose up -d (в домашней директории лежит файл docker-compose.yml)

$ more docker-compose.yml
version: '3.2'
services:
  registry:
    restart: always
    image: registry:2
    ports:
      - 5000:5000
    volumes:
      - /home/regadmin/certs:/certs
      - "/home/regadmin/registry/storage:/var/lib/registry:rw"
      - "/home/regadmin/registry/conf/config.yml:/etc/docker/registry/config.yml:rw"
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "3"
    network_mode: bridge

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

$ more /home/regadmin/registry/conf/config.yml
version: 0.1
log:
  level: error
  fields:
    service: registry
storage:
  filesystem:
    rootdirectory: /var/lib/registry
  delete:
    enabled: true
http:
  addr: :5000
auth:
  token:
    autoredirect: false 
    realm: https://gitlab.domain.com/jwt/auth
    service: container_registry
    issuer: gitlab-issuer
    rootcertbundle: /certs/registry-auth1.crt

Cron (очистка, бэкапы)

Ежедневно на 7 утра в кроне настроено выполнение скрипта /root/backup.sh Этот скрипт чистит реестр от мусора (это unmarked blobs) Если в гитлабе кто-то удаляет образ, то он остаётся на сервере реестра, но очищаются линки, указывающие что данный образ (хранящийся в blobs) связан с таким-то репозиторием на gitlabe. И при отсутствии этих линков, реестр считает эти блобы мусорными. Очистка происходит при помощи команды:

$ docker exec -t regadmin_registry_1 /bin/registry garbage-collect /etc/docker/registry/config.yml

Так же скрипт удаляет свои же старые логи, пакует storage директорию и складывает бэкапы на удаленный сервер и чистит старые локальные бэкапы. Локально бэкапы хранятся в директории /home/backup

Gitlab

Конфигурация

/etc/gitlab/gitlab.rb
   gitlab_rails['gitlab_default_projects_features_container_registry'] = true
   registry_external_url 'https://registry.domain.com'
   gitlab_rails['registry_enabled'] = true
   gitlab_rails['registry_host'] = "registry.domain.com"
   gitlab_rails['registry_api_url'] = "https://registry.domain.com/"
   gitlab_rails['registry_key_path'] = "/etc/gitlab/registry-auth1.key"
   gitlab_rails['registry_issuer'] = "gitlab-issuer"
   registry['internal_key'] = "-----BEGIN PRIVATE KEY-----\nMIICAQCjmfuqT......SExyWhYoh0pmM=\n-----END PRIVATE KEY-----" #При каждом выполнении gitlab-ctl reconfigure, указанный выше registry-auth1.key перезаписывается. Поэтому? нужно его содержимое указать тут в одну строчку, заменяя разрывы строки на \n
   registry['enable'] = false  #Выключает встроенный контейнер реестра

Логи

Если происходят ошибки, нам пригодятся:

  • Лог гитлаба. На гитлабе /var/log/gitlab/gitlab-rails/production.log
  • Лог работы скрипта выше. На реестре /var/log/registry/*
  • Лог контейнера реестра. На реестре # tail -f docker inspect --format='{{.LogPath}}' regadmin_registry_1

Вывод последней команды докер пишет в файл /var/lib/docker/containers/container-id/container-id-json.log Если контейнер удалять и запускать заново, соответственно id будет меняться. Так же, настроена ротация для логов, которые создает докер. (и в частности, этого файла) Таким образом, максимальный размер файла 100мб, при превышении этого лимита он создаёт файлы container-id-json.log.1 и container-id-json.log.2 соответственно. Потом они перезаписываются. Максимально - 3 файла логов по 100 мб. Эти параметры прописаны в config.yml, как можно было заметить выше.

Wulf ()
Ответ на: комментарий от Wulf

это документация, которую я описывал для внутренней вики, если что, спрашивайте. Там вроде как не совсем ясно описал момент, директории /regadmin/registry/conf/ и /regadmin/registry/storage и файл /regadmin/registry/conf/config.yml были созданы предварительно

Wulf ()
Последнее исправление: Wulf (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.