в docker, GitLab

GitLab CI: Часть 2, специальные образы


В первой статье цикла о настройке GitLab Continuous Integration (GitLab CI) мы упоминали о неких специфических docker-образах, которые будут использоваться в нашем конкретном примере при сборке проекта.

Давайте разберемся, зачем они нам нужны, что это за образы и изучим инструкции в их Dockerfil’ах!

В официальной документации по настройке GitLab CI есть такая строка:

GitLab CI allows you to use Docker Engine to build and test docker-based projects

Так как действительно удобно упаковывать приложение для тестирования или деплоя в docker-контейнер, мы просто обязаны использовать эту возможность! Собственно, именно поэтому при регистрации раннера в предыдущей статье мы указали тип docker (--executor docker) и запускаем раннер в привилегированном режиме (--docker-privileged).

Далее нам необходимо в конфигурационном файле .gitlab-ci.yml (рассматривать который мы будем в следующей статье) указать docker-образ, в котором будут происходить все шаги нашего CI и подключить еще один служебный образ (service).

Со служебным образом должно быть все просто: в официальной документации рекомендуют использовать образ docker:dind, где dind расшифровывается как docker-in-docker. Все бы хорошо, но конкретно в нашем случае используются самоподписанные SSL-сертификаты (о том как их сгенерировать читайте здесь), поэтому нам нужно «встроить» в образ docker:dind свой корневой самоподписанный сертификат.

Для корректной работы с локальным Docker Registry при использовании самоподписанных SSL-сертификатов необходимо добавить корневой сертификат в каталог /etc/docker/certs.d/registry.gitlab.lc:5000 на всех хостах (в т. ч. docker-контейнерах), которые будут взаимодействовать с Registry. Если каталога /etc/docker/ нет, тогда можно добавить корневой сертификат в каталог /usr/local/share/ca-certificates/ (для Ubuntu) и выполнить команду:

update-ca-certificates -f

Наш корневой SSL-сертификат называется ca.crt и находится в каталоге с Dockerfile, в котором описаны инструкции для сборки служебного образа (на замену образу docker:dind). Содержимое Dockerfile следующее:

FROM docker:dind

RUN mkdir -p /etc/docker/certs.d/registry.gitlab.lc\:5000
COPY .ca.crt /etc/docker/certs.d/registry.gitlab.lc\:5000/ca.crt
COPY .ca.crt /usr/local/share/ca-certificates/ca.crt
RUN update-ca-certificates -f

VOLUME /var/lib/docker
EXPOSE 2375

ENTRYPOINT ["dockerd-entrypoint.sh"]
CMD []

Для сборки образа, находясь в каталоге с Dockerfile, запускаем команду:

docker build -t registry.gitlab.lc:5000/develop/ed:my-docker-dind .

Второй необходимый нам образ должен включать в себя docker-compose (очень удобно управлять всеми контейнерами, описав их конфигурацию в одном файле) и ssh-клиент (пригодится в будущем для деплоя образа). Инструкции в Dockerfile выглядят так:

FROM docker:1.13

RUN apk add --no-cache py-pip bash openssh-client
RUN pip install docker-compose
RUN if [ ! -d /root/.ssh ]; then mkdir -p /root/.ssh; fi \
 && echo -e "Host *\n StrictHostKeyChecking no\n UserKnownHostsFile=/dev/null\n" >/root/.ssh/config

Собираем образ командой:

docker build -t registry.gitlab.lc:5000/develop/ed:tmaier-dc-ssh .

Пушим только что собранные образы в локальный Docker Registry:

docker push registry.git.labs.lc:5000/develop/ed

В дальнейшем в конфигурационном файле .gitlab-ci.yml для использования данных образов необходимо добавить следующие строки:

image: registry.gitlab.lc:5000/develop/ed:tmaier-dc-ssh
services:
  - registry.gitlab.lc:5000/develop/ed:my-docker-dind
...

но подробнее об этом мы поговорим в следующей статье.

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

11 Комментария

  1. статья так себе, автор упомянул служебный образ, но зачем он нужен, как его создать и т.д. не понятно, зато про сертификаты расписано хот отбавляй. Специальные образ — это контейнер или образ? очень мало понятного

    • В таком случае прочтите статью внимательнее — там сказано, что один образ (my-docker-dind) создается только потому, что у нас используются самоподписанные сертификаты (берем стандартный образ и пихаем в него наши сертификаты). Второй образ (tmaier-dc-ssh) — также об этом написано — должен включать в себя docker-compose и ssh-клиент. Более того, в статье даже написано ЗАЧЕМ эти два инструмента нужны:

      docker-compose (очень удобно управлять всеми контейнерами, описав их конфигурацию в одном файле) и ssh-клиент (пригодится в будущем для деплоя образа)

      Как создать docker-образы — из Dockerfil’ов, которые приведены в статье. Там даже есть готовые команды для сборки (build) этих образов, единственное что нужно указать свой docker-registry и имя образа…

      Ну и раз непонятна разница между контейнером и образом, то стоить почитать документацию — эти две сущности нельзя путать, так как КОНТЕЙНЕР запускается из ОБРАЗА.

      А про сертификаты действительно много написано (и не только в этой статье) — дело в том, что при использовании «самодельных» сертификатов в настройке Gitlab + Gitlab CI грабли ожидают на каждом шагу…

  2. root@vm-27223a44:/opt/gitlab-with-registry# cat docker-compose.yml
    version: '2'
    services:
    redis:
    container_name: gitlab-redis
    restart: always
    image: sameersbn/redis:latest
    command:
    - --loglevel warning
    volumes:
    - /srv/redis:/var/lib/redis:Z
    networks:
    - domen

    postgresql:
    container_name: gitlab-postgres
    restart: always
    image: sameersbn/postgresql
    volumes:
    - /srv/postgresql:/var/lib/postgresql:Z
    environment:
    - DB_USER=gitlab
    - DB_PASS=password
    - DB_NAME=gitlabhq_production
    - DB_EXTENSION=pg_trgm
    networks:
    - itamit

    gitlab:
    container_name: gitlab
    restart: always
    image: sameersbn/gitlab
    depends_on:
    - redis
    - postgresql
    ports:
    - "10080:80"
    - "10022:22"
    volumes:
    - /srv/gitlab/data:/home/git/data:Z
    - /srv/gitlab/logs:/var/log/gitlab
    - /srv/certs:/certs
    environment:
    - DEBUG=false

    - SMTP_USER=gitlab.domen@gmail.com
    - SMTP_PASS=gitlab.domen

    - DB_ADAPTER=postgresql
    - DB_HOST=postgresql
    - DB_PORT=5432
    - DB_USER=gitlab
    - DB_PASS=password
    - DB_NAME=gitlabhq_production

    - REDIS_HOST=redis
    - REDIS_PORT=6379

    - GITLAB_SSH_PORT=10022
    - GITLAB_PORT=10080
    - GITLAB_HOST=gitlab.domen.com

    - NGINX_SERVER_NAMES_HASH_BUCKET_SIZE=36

    - GITLAB_SIGNUP=false
    - GITLAB_SIGNIN=true
    - GITLAB_BACKUPS=daily

    - GITLAB_SECRETS_SECRET_KEY_BASE=neraterandomstringstasdasdghjfkajfhsakjfhk234hkwdjhfdskjfhsdkjf
    - GITLAB_SECRETS_OTP_KEY_BASE=dfjdsafjsaglhjsdlkfjghsldfghjdslfjghsldfghjsldjfhgsldkjfhglsjdfghdslfghjldsjfhgdsljfghdsljfghsldjfghdsljghf
    - GITLAB_SECRETS_DB_KEY_BASE=superrandomsecret

    - GITLAB_REGISTRY_ENABLED=true
    - GITLAB_REGISTRY_HOST=registry.domen.com
    - GITLAB_REGISTRY_PORT=5000
    - GITLAB_REGISTRY_API_URL="https://registry.domen.com:5000/"
    - GITLAB_REGISTRY_KEY_PATH=/certs/registry-auth.key
    - SSL_REGISTRY_CERT_PATH=/certs/registry.crt
    - SSL_REGISTRY_KEY_PATH=/certs/registry.key
    networks:
    domen:
    aliases:
    - gitlab.domen.com

    registry:
    container_name: docker-registry
    restart: always
    image: registry
    volumes:
    - /srv/gitlab/shared/registry:/registry
    - /srv/certs:/certs
    environment:
    - REGISTRY_LOG_LEVEL=info
    - REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/registry
    - REGISTRY_AUTH_TOKEN_REALM=http://gitlab.domen.com:10080/jwt/auth
    - REGISTRY_AUTH_TOKEN_SERVICE=container_registry
    - REGISTRY_AUTH_TOKEN_ISSUER=gitlab-issuer
    - REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE=/certs/registry-auth.crt
    - REGISTRY_STORAGE_DELETE_ENABLED=true
    - REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt
    - REGISTRY_HTTP_TLS_KEY=/certs/registry.key
    ports:
    - "0.0.0.0:5000:5000"
    networks:
    domen:
    aliases:
    - registry.domen.com

    gitlab-runner:
    container_name: gitlab-runner
    image: gitlab/gitlab-runner:latest
    volumes:
    - /srv/gitlab-runner/data:/home/gitlab_ci_multi_runner/data
    - /srv/gitlab-runner/config:/etc/gitlab-runner
    - /var/run/docker.sock:/var/run/docker.sock:rw
    environment:
    - CI_SERVER_URL=http://gitlab.domen.com:10080/ci
    restart: always
    dns: 191.211.154.232

    networks:
    domen:

    • Контейнер postgresql у вас находится в отдельной сети:
      networks:
      - itamit

      Зачем? И если это действительно нужно, то в конце файла не хватает этой сети:
      networks:
      domen:

      Переменная NGINX_SERVER_NAMES_HASH_BUCKET_SIZE=36 у меня не используется, но наверно вы знаете для чего ее добавили

      В моем примере registry это поддомен для gitlab, а не отдельный домен, как у вас. Обратите внимание:

      - GITLAB_HOST=git.labs.lc

      - GITLAB_REGISTRY_HOST=registry.git.labs.lc

      • Спасибо за помощь, проблема оказалась в правах на папку где лежали сертификаты, у кого будет аналогичный случай копайте в ту сторону. Сейчас и вкладка в браузере registry открывается (раньше было 500) и docker login — Login Succeeded (раньше выдавало 401)

  3. Приветствую!

    при пуше в регистри вываливает 401

    root@vm-27223a44:/opt/gitlab-with-registry# docker push registry.domen.com:5000/develop/ed
    The push refers to a repository [registry.domen.com:5000/develop/ed]
    b9232644c625: Preparing
    f64d51e79a7f: Preparing
    2f22d1523268: Preparing
    0c767a02edef: Preparing
    ed4d19134a53: Preparing
    03c5b040ca5b: Waiting
    2eb0ae7a2fab: Waiting
    9ff289d1f1a5: Waiting
    f2616e914895: Waiting
    fb6deff65958: Waiting
    817541f90638: Waiting
    d5f8e269843d: Waiting
    5cbee39fac7f: Waiting
    6dfaec39e726: Waiting
    denied: access forbidden

    root@vm-27223a44:/opt/gitlab-with-registry# curl -i https://registry.domen.com:5000/v2/
    HTTP/2 401
    content-type: application/json; charset=utf-8
    docker-distribution-api-version: registry/2.0
    www-authenticate: Bearer realm=»http://gitlab.domen.com:10080/jwt/auth»,service=»container_registry»
    x-content-type-options: nosniff
    content-length: 87
    date: Fri, 22 Dec 2017 11:39:17 GMT

    {«errors»:[{«code»:»UNAUTHORIZED»,»message»:»authentication required»,»detail»:null}]}

    root@vm-27223a44:/opt/gitlab-with-registry# curl -i https://registry.domen.com:5000/
    HTTP/2 200
    cache-control: no-cache
    content-type: text/plain; charset=utf-8
    content-length: 0
    date: Fri, 22 Dec 2017 11:40:06 GMT

    все делалось по вашему примеру, прошу помочь что не так?

        • Читать статью о настройке gitlab + registry
          https://letsclearitup.com.ua/bash/gitlab-gitlab-ci-docker-registry-s-pomoshhyu-docker-compose.html

          как вариант, выполните на хост-машине команды добавления сертификатов:

          cp /certs/* /usr/local/share/ca-certificates/
          update-ca-certificates --fresh

          В будущем, на каждом компьютере, который будет подключаться к вашему локальному docker registry из консоли (для скачивания/загрузки образов), необходимо корневой сертификат (в данном примере rootCA.pem) положить в каталог

          /etc/docker/certs.d/< FQDN_ИМЯ_РЕДЖИСТРИ >:5000/
          и перезапустить сервис docker

          • Это все уже сделано и статья заюзана +100500 раз и коммент с такой рекомендацией я видел и сделал
            —————————
            root@vm-27223a44:/opt/gitlab-with-registry# docker info
            Containers: 5
            Running: 5
            Paused: 0
            Stopped: 0
            Images: 26
            Server Version: 17.09.1-ce
            Storage Driver: overlay2
            Backing Filesystem: extfs
            Supports d_type: true
            Native Overlay Diff: true
            Logging Driver: json-file
            Cgroup Driver: cgroupfs
            Plugins:
            Volume: local
            Network: bridge host macvlan null overlay
            Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
            Swarm: inactive
            Runtimes: runc
            Default Runtime: runc
            Init Binary: docker-init
            containerd version: 06b9cb35161009dcb7123345749fef02f7cea8e0
            runc version: 3f2f8b84a77f73d38244dd690525642a72156c64
            init version: 949e6fa
            Security Options:
            seccomp
            Profile: default
            Kernel Version: 4.9.0-4-amd64
            Operating System: Debian GNU/Linux 9 (stretch)
            OSType: linux
            Architecture: x86_64
            CPUs: 12
            Total Memory: 3.989GiB
            Name: vm-27223a44
            ID: V6PP:4LG4:A4AS:QU3C:KHGS:TVD7:RDXC:FNUL:PBWC:MHPV:44E7:7N5V
            Docker Root Dir: /var/lib/docker
            Debug Mode (client): false
            Debug Mode (server): false
            Registry: https://index.docker.io/v1/
            Experimental: false
            Insecure Registries:
            registry.domen.com:5000
            127.0.0.0/8
            Live Restore Enabled: false

            WARNING: No swap limit support
            ——————

            root@vm-27223a44:/opt/gitlab-with-registry# docker ps
            CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
            119119e71796 sameersbn/gitlab «/sbin/entrypoint….» 23 hours ago Up About an hour 443/tcp, 0.0.0.0:10022->22/tcp, 0.0.0.0:10080->80/tcp gitlab
            e596c6d82360 registry «/entrypoint.sh /e…» 24 hours ago Up About an hour 0.0.0.0:5000->5000/tcp docker-registry
            5e4fdce245f4 sameersbn/redis:latest «/sbin/entrypoint….» 24 hours ago Up About an hour 6379/tcp gitlab-redis
            f4502fdee4ca gitlab/gitlab-runner:latest «/usr/bin/dumb-ini…» 24 hours ago Up About an hour gitlab-runner
            131f2fc7edd9 sameersbn/postgresql «/sbin/entrypoint.sh» 24 hours ago Up About an hour 5432/tcp gitlab-postgres
            ———————————-

            root@vm-27223a44:/opt/gitlab-with-registry# ls /etc/docker/certs.d/registry.domen.com\:5000/
            ca.crt rootCA.pem
            ————————————

            root@vm-27223a44:/opt/gitlab-with-registry# ls /srv/certs/
            make_certs.sh registry-auth.crt registry-auth.csr registry-auth.key registry.crt registry.csr registry.key rootCA.key rootCA.pem rootCA.srl
            ——————