Практика CI на основе GitLab

GitLab
Практика CI на основе GitLab

В этой статье описывается архитектура и возможности GitLab CI, а также анализируется его роль в практике DevOps. Путем анализа технических деталей Docker. В Docker подробно описываются методы и оптимизации CI, выполненные в производственной среде, включая, помимо прочего, хранилища образов, чтобы добиться повышения производительности в несколько раз. В этом совместном использовании в качестве примера используется GitLab Community Edition 11.0.4 edb037c. Почему стоит выбрать GitLab CI?

Познакомьтесь с GitLab CI Что такое Gitlab Ci?GitLab CI — это базовая функция CI/CD, добавленная GitLab для повышения своей роли в разработке программного обеспечения и улучшения концепции DevOps. Его можно легко интегрировать в процесс разработки программного обеспечения. Полные конвейеры CI/CD можно определить через GitLab CI. Преимущество
  • GitLab CI по умолчанию включен в GitLab, а наш код размещается с помощью GitLab, что упрощает интеграцию.

  • Фронтенд-интерфейс GitLab CI красивее и его легче принять.

  • Включает журналы сборки в реальном времени для удобного отслеживания

  • Используя архитектуру C/S, его можно масштабировать по горизонтали, при этом производительность не пострадает.

  • Настроен с использованием YAML, любой может легко использовать его

ключевое понятие Pipeline Конвейер эквивалентен задаче сборки, которая может содержать несколько процессов, таких как установка зависимостей, компиляция, тестирование, развертывание и т. д. Любая фиксация или мерж-реквест может запустить Pipeline. StagesСтадия представляет собой стадию сборки, процесс, упомянутый выше.
  • Все этапы выполняются по порядку, то есть когда один этап завершен, начинается следующий этап

  • Если какой-либо этап завершается сбоем, следующие этапы никогда не будут выполнены, а конвейер выйдет из строя.

  • Только когда все этапы будут завершены, PIPELINE завершится успешно.

JobsJob — это задача в Stage.
  • Задания на одном этапе будут выполняться параллельно

  • Если какое-либо задание завершается сбоем, то происходит сбой Stage и сбой Pipeline.

  • Когда все задания на одном этапе выполняются успешно, этап считается успешным.

Хорошо, основные концепции были представлены вам. Вы можете обнаружить, что понятия, упомянутые выше, не упоминают фактический исполнитель этой задачи. Где выполняется задача?GitLab RunnerRunner — это фактическая реализация тех задач, которые можно запускать в системах MacOS/Linux/Windows. Используйте разработку Golang. Также можно развернуть в Kubernetes. регистр
docker run --rm -t -i -v /path/to/config:/etc/gitlab-runner --name gitlab-runner gitlab/gitlab-runner register \  --executor "docker" \  --docker-image alpine:3 \  --url "https://gitlab.com/" \  --registration-token "PROJECT_REGISTRATION_TOKEN" \  --description "docker-runner" \  --tag-list "dev" \  --run-untagged \  --locked="true"скопировать код
Приведенный выше пример — это регистрация Runner в качестве контейнера, конечно, вы также можете запустить его непосредственно на физической машине. Регистрация на физической машине работает почти так же, как и в контейнере.
sudo gitlab-runner register \  --non-interactive \  --url "https://gitlab.com/" \  --registration-token "PROJECT_REGISTRATION_TOKEN" \  --executor "docker" \  --docker-image alpine:3 \  --description "docker-runner" \  --tag-list "docker,aws" \  --run-untagged \  --locked="false" \скопировать код
(Этот код взят из официальной документации) Далее давайте рассмотрим типы бегунов, чтобы мы могли различать их при использовании. тип
  • Поделился: бегун проходит рабочие места от всех неназначенных проектов

  • Группа: Runner запускает задания из всех неназначенных проектов в своей группе.

  • Конкретно: Runner запускает задания из назначенных проектов.

  • Заблокировано: Runner не может быть назначен другим проектам

  • Приостановлено: Runner не получит новых заданий

настроитьПрежде всего, внешний слой является глобальной конфигурацией. По умолчанию будет:
concurrent = 1check_interval = 0скопировать код
эти двое. Сравнивать нужно следующие:Глобальная конфигурация
  • concurrent: количество параллелизма, 0 не ограничено.

  • sentry_dsn: связанные с Sentry исключения могут быть собраны в Sentry.

  • Listay_address: раскрывает метрики для мониторинга прометея.

Executor
  • Shell

  • Docker (на этот раз общий контент)

  • Docker Machine и Docker Machine SSH (автомасштабирование)

  • Parallels

  • VirtualBox

  • SSH

  • Кубернетес (рекомендуется)

Подробный докер в докере

ОбзорDocker В Docker, называемом dind, при использовании GitLab CI часто можно использовать для сервисной части. dind означает, что контейнер Docker или демон Docker фактически работает в Docker. На самом деле, если вы просто выполняете команды Docker в Docker, вы можете установить бинарный файл. Но если вы хотите запустить демон Docker (например, вам нужно выполнить информацию о докере) или доступ к любому устройству запрещен. Docker предоставляет две очень важные опции — привилегированную и —устройство в команде запуска.Другие опции, такие как —cap-add и —cap-drop, также связаны с разрешениями, но сегодня они не в центре внимания. Таблица. Опция --device позволяет нам получить доступ к указанному устройству без опции --privived, например, docker run --device=/dev/sda:/dev/xvdc --rm -it ubuntu fdisk /dev/xvdc Но это это только ограниченные разрешения Мы знаем, что техническая реализация Docker на самом деле основана на изоляции ресурсов CGroup, но --device недостаточно, чтобы позволить нам иметь достаточно разрешений в контейнере для завершения запуска демона Docker. Примерно в 2013 году в Docker была добавлена ​​опция --privived, позволяющая запускать контейнеры внутри контейнеров. Хотя первоначальная идея --privated заключалась в том, чтобы сделать контейнерную разработку более удобной, у некоторых людей могут возникнуть некоторые недоразумения при ее использовании. Иногда мы можем просто захотеть иметь возможность нормально создавать образы внутри контейнера или взаимодействовать с демоном Docker, например с образами Docker и другими командами. Ну, dind нам на самом деле не нужен, нам нужен Docker Out Of Docker, то есть dood, когда мы его используем, мы фактически монтируем docker.sock в контейнер. Например, используйте следующую команду:
sudo docker run --rm -ti -v /var/run/docker.sock:/var/run/docker.sock taobeier/docker /bin/shскопировать код
В контейнере могут быть обычные образы Docker и другие операции, которые следует учитывать при работе с контейнером, которые будут влиять на демон Docker на хосте.

Как добиться

  • Создавайте группы и пользователей и добавляйте пользователей в группу. Используйте команды groupadd и useradd.

  • Обновите файлы subuid и subgid, чтобы настроить новых пользователей и группы в файлах /etc/subgid и /etc/subuid. subuid и subgid указывают, какие подчиненные идентификаторы разрешено использовать пользователю.

  • Затем вам нужно смонтировать /sys/kernel/security как тип securityfs, вы можете использовать команду mountpoint для проверки точки монтирования /sys/kernel/security Если это не точка монтирования, используйте mount -t securityfs none /sys/kernel /security для монтирования. Если он не монтируется успешно, вы можете проверить, не препятствует ли SELinux или AppArmor такому поведению. Для получения подробных сведений о проблемах безопасности здесь вы можете обратиться к Linux Модули безопасности (LSM).

  • Затем разрешите команде dockerd запустить демон, dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2375 для прослушивания демона docker на порту 2375. .

Простой способВы можете напрямую использовать образ docker:dind из официального репозитория образов Docker, но во время выполнения вам нужно указать параметр --privived. практика КИ

Практика бегунаПосмотрите на конфигурацию раздела Runner:
[[runners]]  name = "docker"  url = "https://gitlab.example.com/"  token = "TOKEN"  limit = 0  executor = "docker"  builds_dir = ""  shell = ""  environment = ["ENV=value", "LC_ALL=en_US.UTF-8"]  clone_url = "http://172.17.0.4"скопировать код
По сетевым причинам clone_url можно настроить как доступный адрес, чтобы настроенный адрес использовался при клонировании кода. Фактический запрос: http://gitlab-ci-token:TOKEN@172.17.0.4/namespace/project.git. Взгляните еще раз на конфигурацию runners.docker, эта часть повлияет на фактическую работу Docker:
[runners.docker]  host = ""  hostname = ""  tls_cert_path = "/home/tao/certs"  image = "docker"  dns = ["8.8.8.8"]  privileged = false  userns_mode = "host"  devices = ["/dev/net/tun"]  disable_cache = false  wait_for_services_timeout = 30  cache_dir = ""  volumes = ["/data", "/home/project/cache"]  extra_hosts = ["other-host:127.0.0.1"]  services = ["mongo", "redis:3"]  allowed_images = ["go:*", "python:*", "java:*"]скопировать код
DNS, Privileged, extra_hosts, более важные службы, особенно при создании различных сетевых условий, требуют особого внимания. Что касается конфигурации устройств, начиная с уже упомянутого общего доступа Comin, разрешенных_изображений, то делается ограничение. Несколько вышеперечисленных элементов конфигурации, используемые студентами Docker, должны быть просты для понимания. Смотрим пункты конфигурации Services:
image: registry.docker-cn.com/taobeier/dockervariables:  DOCKER_DRIVER: overlay2    # overlay2 is best bug need kernel >= 4.2services:  - name: registry.docker-cn.com/taobeier/docker:stable-dind    alias: dockerstages:  - build  - deploybuild_and_test:  stage: build  tags:    - build  script:    # change repo    #- sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories    # 使用默认官方源 apk 耗时 7min 30s.  修改后 耗时 18s    - ping -c 1 docker    - ping -c 1 registry.docker-cn.com__taobeier__docker    - ipaddr    - apk add --no-cache py-pip     # 使用默认耗时 1 min 15s.  修改后耗时 43s    - pip install -i https://mirrors.ustc.edu.cn/pypi/web/simple docker-compose    - docker-compose up -d    - docker-compose run --rm web pytest -s -v tests/test_session.pydeploy:  image: "registry.docker-cn.com/library/centos"  stage: deploy  tags:    - deploy  script:    # install ssh client    - 'ssh-agent || (yum install -y openssh-clients)'    # run ssh-agent    - eval $(ssh-agent -s)    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null    # create ssh dir    - mkdir -p ~/.ssh    - chmod 700 ~/.ssh    # use ssh-keyscan to get key    - ssh-keyscan -p $SSH_PORT $DEPLOY_HOST >> ~/.ssh/known_hosts    - chmod 644 ~/.ssh/known_hosts    # - ssh -p $SSH_PORT $DEPLOY_USER@$DEPLOY_HOST ls    - rm -rf .git    - scp -r -P $SSH_PORT . $DEPLOY_USER@$DEPLOY_HOST:~/we/скопировать код
Суть Services заключается в использовании Docker'овской --link, давайте посмотрим, как это работает:Как работают исполнители Docker
  • Создайте сервис-контейнер (образ уже настроен в сервисе)

  • Создайте контейнер кеша (сохраните уже настроенный том в config.toml и Dockerfile для сборки образа)

  • Создайте контейнер сборки и контейнер службы для Link

  • Запустите контейнер сборки и отправьте скрипт задания в контейнер.

  • Скрипт для выполнения задания

  • Код оформления заказа: /builds/имя-группы/имя-проекта/

  • Выполните шаги, определенные в .gitlab-ci.yml

  • Проверьте код состояния после выполнения скрипта, если он не равен 0, сборка завершится неудачно.

  • Удаление сборочных и сервисных контейнеров

Частный зеркальный источникДля аутентификации пользователя требуется gitlab Runner 1.8 или более поздняя версия, выполняемая вручную на Runner между 0.6 и 1.8. Версия Runner должна иметь собственный компьютер. По умолчанию, если для доступа к репозиторию образов требуется аутентификация, GitLab Runner будет использовать переменную DOCKER_AUTH_CONFIG в качестве учетных данных аутентификации. Примечание. DOCKER_AUTH_CONFIG — это полные учетные данные для аутентификации в Docker, то есть содержимое нашего файла ~/.docker/config.json должно быть согласованным, например:
{     "auths": {         "registry.example.com": {             "auth": "5oiR5piv5byg5pmL5rab"         }     } }скопировать код
Простой способ заключается в том, что мы запускаем источник частного изображения для входа в систему на локальном сервере / сервере.После успешного входа в систему скопируйте содержимое файла ~/.docker/config.json непосредственно в качестве значения нашей переменной. Или echo -n 'username:password' |base64, чтобы таким образом получить содержимое auth, собрать его в соответствующий формат и записать в value configuration GitLab. Оптимизация производительности CI в производственных средах

1. Используйте отечественные источники для ускорения образов контейнеров. Например: используйте официальный сервис ускорения образов Docker China https://registry.docker-cn.com Конечно, различные компании также предоставляют услуги по ускорению образов. 2. Используйте частный репозиторий изображений. Например, Docker Registry или Harbour, мы используем Harbour в качестве частного реестра. По сетевым причинам, если по умолчанию используется официальный образ, 1. Официальный образ не может быть сброшен 2. Установка пакета в официальный образ занимает много времени 3. При смене источника каждый Dockerfile нужно сделать то же самое. Конечно, мы не можем с этим согласиться. Итак, мы построили свой собственный имидж. Сборка alpine linux из BusyBox использует частные источники и на их основе создает другие нужные нам образы. Пользователям больше не нужно самостоятельно менять источник. После завершения этой операции время, необходимое для установки py-pip во время выполнения CI (для установки docker-compose и зависимостей нашего сервиса), сократилось с 3 минут 30 до 18 секунд. Здесь нужно сказать, почему мы строим образ с нуля, а не на основе официального образа. В основном, чтобы уменьшить размер изображения и быстрее адаптироваться к нашим потребностям. Точно так же мы создали базовые образы Docker, Python/Maven и другие образы, все из которых по умолчанию используют наши частные источники, и пользователям не нужно обращать внимание на смену источников при их использовании, что снижает умственную нагрузку пользователей. 3. Стандартизируйте Dockerfile, уменьшите количество ненужных установок зависимостей и уменьшите размер образа. Фактически, в сочетании с вышеперечисленными частями, мы напрямую создаем наш базовый образ, такой как Docker/Alpine/Maven, и напрямую меняем исходный код по умолчанию. Это не только удобно в использовании, но и уменьшает количество зеркальных слоев. 4. Разделить задание, указать Runner по тегу и выполнять какие-то действия без сильных зависимостей параллельно разными Runner'ами. Легко распределять давление. 5. Используя Cache, при построении CI большинство изображений не сильно меняются, поэтому использование Cache может удвоить скорость CI. 6. Ямы с которыми можно столкнуться, как было сказано ранее, в сервисе могут использоваться различные сервисы, будь то dind или MySQL Redis и т.д. Но если бы мы все оптимизировали, используя наши частные источники, мы бы нашли проблему. Поскольку GitLab CI по умолчанию использует docker:dind, служба фактически выбирает хост с именем Docker и порт 2375. При использовании частных зеркальных источников, таких как:
services:            - name: registry.docker-cn.com/taobeier/docker:stable-dindскопировать код
Что является хозяином этого сервиса? Хостом этого сервиса на самом деле станет register.docker-cn.com__taobeier__docker, тогда GitLab Runner не сможет его найти, и задание не выполнится. Есть два решения, одно из них — добавить переменную.
variables:            DOCKER_HOST: "tcp://registry.docker-cn.com__taobeier__docker:2375"скопировать код
Но этот путь очень хлопотный, никто не может до конца вспомнить, что он встречает/превращает в _ неизбежные проблемы. Тогда есть второй способ:
services:            - name: registry.docker-cn.com/taobeier/docker:stable-dind             alias: dockerскопировать код
Добавьте псевдоним. Этот метод редко используется в настоящее время, ведь первый способ встречается в Интернете, но этот способ самый простой. вопросы и ответы

В: Вы упомянули, что все зависимости предоставляются как сервисы, каким образом? Например, как сделать зависимость Python сервисом? A: Зависимости на основе служб в основном относятся к таким вещам, как DB/MySQL/Reids. Или dind фактически предоставляет службу TCP на порту 2375. Для зависимостей Python я рекомендую создать повторно исходный образ Python. При установке зависимостей это займет намного меньше времени. Другими словами, вы можете использовать папку venv виртуальной среды в качестве кеша при определении конвейера, и последующие установки также будут проверять это, чтобы избежать ненужных установок.В: Извините, почему вы используете GitLab CI вместо Jenkins Pipeline? О: Основная причина — это те аспекты, о которых я упоминал. Интеграция лучше, интерфейс красив и элегантен, и им легко пользоваться (его могут использовать все люди с разрешениями на запись в хранилище, просто создайте .gitlab-ci.yml и настройте Runner для его использования). Под другим углом посмотрим на проблему использования Jenkins.Настройка Jenkins для проекта фактически отделена от кода GitLab.Есть две части.Когда пользователи (или наши разработчики) их используют,у них должно быть две платформы , И в большинстве случаев разрешения Дженкинса не освобождаются. Для пользователя это равносильно черному ящику. Какова возможная проблема? Когда сборка терпит неудачу, только эксплуатация и техническое обслуживание знают, что произошло, но НИОКР ничего не могут сделать, потому что нет разрешения. В настоящее время преимущества использования GItLab более заметны: конфигурация находится в репозитории кода, а конфигурация с использованием YAML очень проста. Если есть какие-либо проблемы, пожалуйста, проверьте и измените его напрямую.Вопрос: О проблеме очистки бегуна, после долгого использования машина бегуна производит много контейнеров кеша, как его очистить. Можете ли вы автоматически очистить его в задаче? A: Это относительно простое. Во-первых, если ваш контейнер кэширован подтвержден, каждый контейнер кеша на самом деле назван, непосредственно нажав имя кэша и удаляет его. Если вы не уверены, если это полезно, то вы можете удалить его напрямую, потому что Docker Excuretor создается после создания сервисного контейнера, создавая контейнер кэширования. Если вы удалите его, это просто снова создает. Если вы хотите очистить его в миссии, я не сделал соответствующую практику, после того, как я практикую, посмотрим, есть ли элегантный путь.В: Будут ли следующие настройки Maven's.xml как быть? Локальный репозиторий Maven это? О: Мы создали частное зеркало Maven, по умолчанию зеркало — это частное использование нашего частного источника. Для проекта пользователю не нужно беспокоиться о том, находится ли репозиторий конфигурации settings.xml.В: В CD-решении от GitLab приватный ключ трамплинной машины нужно настроить в переменной при деплое, если этот проект разрабатывается для всего отдела компании, как защитить этот приватный ключ? A: Вы можете использовать секретную переменную для записи в нее закрытого ключа, (но администратор проекта имеет разрешение на просмотр переменной) для разработки веб-сервера (на самом деле вам нужно только выставить IP-порт и т.д. on) Перейдите к процессу Запрос на выполнение CI, сервер оценивает источник (например, при выполнении CI будут некоторые определенные переменные, чтобы судить, действительно ли это запрос CI), а затем возвращает закрытый ключ.В: Для каких типов проектов подходит GitLab CI? Это все еще относительно мало в стране? A: В настоящее время в Китае он все еще относительно мал (по сравнению с Jenkins) На самом деле, пока проект нуждается в CI, он подходит. Практический учебный лагерь проекта Kubernetes

Практическое обучение проекту Kubernetes начнется в Шэньчжэне 17 августа 2018 года, и вы освоите Kubernetes за 3 дня..Это обучение включает в себя: введение в Docker, образ Docker, сеть, хранилище, безопасность контейнеров; архитектуру Kubernetes, концепции проектирования, общие объекты, сеть, хранилище, сетевую изоляцию, обнаружение сервисов и балансировку нагрузки; основные компоненты Kubernetes, модули, подключаемые модули, микросервисы. , Cloud Native, Kubernetes Operator, Cluster Disaster Recovery, Helm и т. д. Нажмите на картинку ниже, чтобы просмотреть подробности.