Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Docker в docker для сборки в docker

Docker в docker для сборки в docker

Iskander (Alex) Sharipov

January 05, 2019
Tweet

More Decks by Iskander (Alex) Sharipov

Other Decks in Programming

Transcript

  1. Продукт X: переход к микросервисам Величайший враг прячется там, где

    вы будете меньше всего его искать. Гай Юлий Цезарь
  2. REST REST REST сокеты Структура продукта X (до перехода на

    Docker) Монолит на PHP Монолит на PHP Frontend Микросервис на Go Микросервис на Node.js SPA iframe
  3. REST REST REST сокеты Структура продукта X (в скором будущем)

    Монолит на PHP Монолит на PHP Frontend Микросервис на Go Микросервис на Node.js SPA SPA Микросервис на Go Микросервис на Go Микросервис на Go Микросервис на Go Микросервис на Node.js iframe iframe SPA Микросервис на Go
  4. Build X Service X Frontend X Service Y Frontend Y

    Service Z Container x:v1.2.3 Container y:??? Container z:???
  5. Резюмируя Не надо ограничиваться унификацией развёртывания образов  Подумайте об

    унификации сборки контейнеров из git  Используйте docker, чтобы упростить разработку
  6. Сборка: make + docker build docker build -t {branch.buildNo} .

    docker push {branch.buildNo} Makefile build: dep ensure go build -o ... ... Dockerfile FROM debian ADD ... /go/bin/outyet ENTRYPOINT /go/bin/outyet EXPOSE 8080 make build Сервис на Go
  7. Сборка: только docker build https://blog.golang.org/docker docker build -t {branch.buildNo} .

    docker push {branch.buildNo} Dockerfile FROM golang ADD . /go/src/.../outyet RUN go install .../outyet ENTRYPOINT /go/bin/outyet EXPOSE 8080 Сервис на Go
  8. Сборка: multi-stage docker build https:// blog.codeship.com/building-minimal-docker-c ontainers-for-go-applications/ docker build -t

    {branch.buildNo} . docker push {branch.buildNo} Dockerfile FROM golang:alpine as builder COPY . $GOPATH/src/outyet WORKDIR $GOPATH/src/outyet RUN go build -o /go/bin/outyet FROM scratch COPY --from=builder /go/bin/outyet /go/bin/outyet ENTRYPOINT ["/go/bin/outyet"] Сервис на Go
  9. Нюансы сборки из scratch Проблемы:  У вас нет пакетного

    менеджера и командной оболочки  У вас нет SSL сертификатов (нельзя выполнять https запросы)  У вас нет данных о часовых поясах (tzdata) Решения: 1. github.com/jeremyhuiskamp/golang-docker-scratch 2. использовать alpine
  10. Добавим трудностей  Пусть фронтенд будет сложным SPA  Установка

    зависимостей через npm install  Сборка через npm run dist  Запуск модульных тестов и linter через npm run test
  11. Сборка: добавляем frontend docker build -t {branch.buildNo} . docker push

    {branch.buildNo} Dockerfile FROM node:11-alpine as frontend COPY ./www /usr/src/www RUN npm install && npm run dist FROM golang:alpine as builder COPY . $GOPATH/src/outyet WORKDIR $GOPATH/src/outyet RUN go build -o /go/bin/outyet FROM scratch COPY --from=builder /go/bin/outyet /go/bin/outyet COPY –from=frontend /usr/src/www/dist/ /go/bin/outyet/www ENTRYPOINT ["/go/bin/outyet"] Сервис на Go
  12. Добавим трудностей  Пусть фронтенд будет сложным SPA  Установка

    зависимостей через npm install  Сборка через npm run dist  Запуск модульных тестов и linter через npm run test  Пусть фронтенд лежит в отдельном репозитории А в чём проблема? git submodule add [email protected]/frontend
  13. Немного о сабмодулях Измени подмодуль в ветке A Как возненавидеть

    свою работу Измени подмодуль в ветке B Сделай merge Ты ещё считаешь, что git submodule – это круто? Да! Нет
  14. Сборка: добавление frontend через скрипт docker build -t {branch.buildNo} .

    docker push {branch.buildNo} Dockerfile FROM node:11-alpine as frontend COPY ./www /usr/src/www RUN npm install && npm run dist if ! [ -d ${DIR} ]; then git clone ${REPO} ${DIR} fi cd ${DIR} git reset --hard git clean -fdx git fetch origin git checkout origin/${BRANCH} Скрипт обновления frontend Сервис на Go
  15. Сборка: docker-контейнер с frontend docker build -t {branch.buildNo} . --build-

    arg "FRONT=harbour.x.com/frontend:$ {BRANCH.BUILD_NO}" docker push {branch.buildNo} Dockerfile ARG FRONT=nil FROM ${FRONT} as frontend FROM golang:alpine as builder COPY . $GOPATH/src/outyet WORKDIR $GOPATH/src/outyet RUN go build -o /go/bin/outyet FROM scratch Сервис на Go Фронтенд docker build -t {branch.buildNo} . docker push {branch.buildNo}
  16. Резюмируя Для каждого микросервиса: 1. Использовать multi-stage docker builds +

    build args 2. Конфигурировать сервис CI для сбороки frontend, сборки сервиса и развёртывания продукта по цепочке
  17. Согласованный deploy kustomize Container x:v1.2.3 Container x:TASK-981 Container x:master Container

    x:v1.2.4 Кто выбирает версии контейнеров? Где хранятся конфиги kustomize и k8s?
  18. Согласование версий: подход от 2GIS Service X Frontend X Service

    Y Frontend Y Service Z Монорепозиторий: Service X Frontend X Service Y Fronten Y Service Z https://youtu.be/RSTHex_rKBU Подход к Continuous Deployment в микросервисной архитектуре / Алексей Баитов (2ГИС) Container x:v1.2.3 Container y:v2.0.19 Container z:master Сервис деплоя на Python С конфигами на Python
  19. Наше решение: X Platform Великие дела надо совершать, а не

    обдумывать их бесконечно. Гай Юлий Цезарь
  20. Схема сборки Скрипт на Bash Запускает в Docker контейнере скрипт

    на Python3 X Platform bin x-platform src сервис сервис k8s … x-platform.yml x-platform.py Скрипт на Python3 ~600 строк Читает x-platform.yml Выполняет сборку и деплой
  21. Схема сборки … services: zbackend: dir: src/zbackend git: remote: [email protected]/zbackend

    reference: origin/master dockerBuilder: image: builders/zbackend:newest workdir: /go/src/x/zbackend docker: image: zbackend scripts: build: - make build test: - make test X Platform bin x-platform src сервис сервис k8s … x-platform.yml x-platform.py
  22. Схема сборки docker pull "${XBUILDER_IMAGE}" >/dev/null docker run --rm \

    --volume /var/run/docker.sock:/var/run/docker.sock \ --user $USER_ID:$DOCKER_GROUP_ID \ --volume /etc/passwd:/etc/passwd:ro \ --volume /etc/group:/etc/group:ro \ --volume ${SSH_DIR}:${SSH_DIR}:ro \ --volume ${KUBE_DIR}:${KUBE_DIR}:ro \ -e "CACHE_DIR=$CACHE_DIR" \ --volume "$CACHE_DIR":/app/cache \ --volume "$PLATFORM_DIR":/usr/src/app \ -e "PLATFORM_DIR=$PLATFORM_DIR" \ -w /usr/src/app \ "${XBUILDER_IMAGE}" /usr/src/app/bin/x-platform.py "$@" X Platform bin x-platform src сервис сервис k8s … x-platform.yml x-platform.py
  23. Контейнеры для сборки контейнеров Каталог с контейнерами для сборки контейнеров

    X Platform bin x-update-builder builders zbackend zfrontend k8s x-platform.yml x-platform.py Dockerfile Файл описания контейнера-сборщика Исходников нет Только база + apt-get Скрипт для сборки контейнеров, собирающего контейнеры x-update-builder zbackend
  24. Тег образа – это sha-1 последнего коммита Схема сборки x-platform

    build --services zbackend Обновление репозитория Сборка Unit тесты docker build docker push <sha-1> docker push <branch> В реестре или локально есть образ с таким sha-1? docker pull <sha-1> Нет Да
  25. Плюсы X Platform как системы сборки контейнеров  Не требует

    монорепозитория  Тегирует образ по sha-1 коммита  Быстрая локальная сборка  Быстрая сборка на сервере  Относительно прост в реализации: 600 строк на Python, 2-3 недели разработки
  26. Резюмируя  Свой велосипед – это хорошо, если его код

    минималистичен, а выгоды от автоматизации много  Положите свой велосипед в Docker
  27. Что такое Dapp  https://flant.github.io/dapp/  Открытый проект компании Flant

     Написан на Go  Выполняет сборку образов и согласованный deploy  Умеет работать с моно- и мультирепозиториями  Умеет кешировать все шаги сборки всех контейнеров  Умеет тегировать контейнеры по sha-1 коммита, по ветке, по номеру билда
  28. Резюмируя  Используйте dapp как выбор по умолчанию для автоматизации

    CI  Пишите свой скрипт, если dapp не подходит  Не полагайтесь на TeamCity, Gitlab CI, Buildbot – они by design не рассчитаны на микросервисы и Docker