Tags: distorhead/dapp
Tags
Deploy в Kubernetes На данный момент в Dappfile можно было лишь указывать правила сборки образов через директивы dimg, dimg_group. Теперь появилась возможность описывать правила установки этих образов в кластер kubernetes. \## Какие примитивы поддерживаются В Dappfile определяется набор app-ов. Можно определить либо 1 неименованный app, либо несколько именованных. Каждый app преобразуется в 1 kubernetes Deployment, в котором запускается 1 или несколько Pod'ов с 1 контейнером. Количество Pod'ов регулируется директивой `deployment.app.scale`. Директива `deployment.app.expose` используется, чтобы открыть сетевой доступ к приложению. Например: ```ruby deployment do app do expose do node_port port(80) { tcp } end end end ``` Такая конфигурация приведет к созданию контейнера в Pod'е Deployment, слушающего 80 порт. Также будет создан kubernetes Service с типом NodePort, связанный с Pod'ом данного app. \## Процесс деплоя Команда `dapp deployment apply <repo> [--image-version IMAGE_VERSION]` применит новую или обновленную конфигурацию и дождется состояния готовности для каждого app. Процесс ожидания построен на периодическом опросе состояния объекта. Команда периодически выводит информацию от kubernetes ресурсов, связанных с app, пока не будет достигнуто состояние готовности. Если удалить из Dappfile app и применить конфигурацию, то из kubernetes будут удалены все ресурсы (Deployment, Service), связанные с данным app. Команды очистки kubernetes от следов данного dapp пока не предусмотрено. \## Поднятие тестового окружения в minikube Команда `dapp deployment minikube setup`: * Запустит minikube. * Создаст в кластере docker registry. * Запустит на хост-системе forwarder для возможности загружать образы с хост-системы в кластер minikube. Во всех командах, где необходимо указывать docker-repo параметром, поддерживается специальный макро-параметр :minikube, который автоматом разворачивается в сетевой путь до docker-registry + имя dapp: `localhost:5000/<dapp-name>`. Таким образом, чтобы собрать и запустить образ локально в minikube используются следующие команды: ```ruby dapp deployment minikube setup dapp dimg build dapp dimg push :minikube dapp deployment apply :minikube ``` \## Kubernetes namespace В Dappfile можно описывать разные параметры для разных kubernetes namespace. По умолчанию будет использоваться namespace default. С помощью директивы `deployment.namespace`, `deployment.app.namespace` происходит определение namespace и в ruby-блоке для этих директив можно переопределить или задать впервые другие параметры деплоя, которые будут использованы только при деплое в данный namespace. Например: ```ruby deployment do namespace 'production' do environment("ENV" => "PRODUCTION") end app do namespace 'development' do expose { port(9000) } end end end ``` Чтобы применить конфигурацию для определенного namespace — указывается переменная окружения `DAPP_NAMESPACE=production dapp deployment apply :minikube`, или параметр-cli `dapp deployment apply --namespace=development`. \## Переменные окружения Переменные окружения для передачи в Deployment можно указывать следующими способами: * В Dappfile директивой `deployment.environment`, `deployment.app.environment`. * Из переменных окружения системы, где запустили dapp при условии, что * Имя переменной начинается на префикс `DAPP_DEPLOYMENT_` — этот префикс будет отрезан и в Deployment попадет переменная с оставшимся именем * Имя переменной начинается на префикс `DAPP_DEPLOYMENT_<NAMESPACE-CAMELCASED>_` — такие переменные будут использованы, только при деплое в соответствующий namespace, префикс будет отрезан. \## Секретные переменные окружения Имеется возможность задать секретное значение прямо в Dappfile. Для этого: * Генерируется секретный ключ командой `dapp deployment secret key generate` * Шифруется требуемое значение командой (в DAPP_SECRET_KEY указывается 128 битный ключ, который был сгенерирован или придуман в формате hex): ``` $ DAPP_SECRET_KEY=cb52a49c0ed3d3ceb1d6338b6f76868b dapp deployment secret generate mypassword 1000d14c86e1a814ff6515903d6ba4f233b0696648ddea018f4072483265eb059678 ``` * В Dappfile с помощью директивы `deployment.secret_environment`, `deployment.app.secret_environment` указывается имя переменной и зашифрованное значение. * При вызове команды `dapp deployment apply ...` указывается переменная окружения DAPP_SECRET_KEY с тем же ключом и значения всех секретных переменных будут расшифрованы при создании и обновлении ресурсов в kubernetes. \## Bootstrap job Если перед первым деплоем приложения или всего dapp необходимо выполнить какую-то команду — этой цели служат директивы: * `deployment.bootstrap` — запускается 1 раз при первом деплое данного dapp * `deployment.app.bootstrap` — запускается 1 раз при первом деплое данного app Bootstrap может быть использован для первичного создания схемы БД: ```ruby deployment do bootstrap do dimg 'some-image' run 'some', 'common', 'bootstrap', 'command' end app 'rails' do dimg 'rails' bootstrap do run '/bin/bash', '-c', 'rake db:create' end end end ``` При запуске этого job происходит создание отдельного Pod'а и контейнера в kubernetes и ожидание результатов его выполнения. Используемый образ либо наследуется из app, либо должен быть определен явно директивой `deployment.bootstrap.dimg`. \## Before apply job Если перед деплоем новой версии приложения надо запустить команду, например для проведения миграций в БД (упрощенный вариант, не заморачиваясь с корректностью такой операции): ```ruby deployment do app 'web' do dimg 'rails' before_apply_job.run '/bin/bash', '-c', 'rake db:migrate' end end ``` Такой job будет запускаться при каждом вызове команды `dapp deployment apply ...`. Аналогично bootstrap job, при запуске этого job происходит создание отдельного Pod'а и контейнера в kubernetes и ожидание результатов его выполнения. \## Настройки подключения к kubernetes api Dapp использует настройки kubectl из `~/.kube/config`. * Настройки пользователя берутся из первого попавшегося пользователя `users`. * Настройки кластера берутся из первого попавшегося кластера `clusters`. Такой способ настройки является временным и вероятно будет изменен в последующих версиях на указание настроек подключения через Dappfile. \## Полный пример Dappfile для rails-приложения ```ruby dimg_group do dimg 'mysql' do docker.from 'sameersbn/mysql:latest' end dimg 'rails' do docker.from 'rails:5' git('https://github.com/alexey-igrychev/test_rails_project.git').add.to('/app') shell.setup.run 'cd /app', 'bundle install' docker.workdir '/app' docker.entrypoint '/bin/bash' docker.cmd '-c', 'rails s' end end deployment do app 'mysql-server' do dimg 'mysql' environment DB_USER: 'dbuser', DB_PASS: 'dbpass', DB_NAME: 'appdb' expose.port(3306) end environment APP_DEVELOPMENT_DATABASE_URL: 'mysql2://dbuser:dbpass@dapp-mysql-server-service/appdb' app 'rails' do dimg 'rails' expose do node_port port(3000) end bootstrap.run '/bin/bash', '-c', 'rake db:create' before_apply_job.run '/bin/bash', '-c', 'rake db:migrate' end end ```
Возможность создавать symlink'и в артефактах и git-артефактах * Переделан механизм копирования файлов артефакта на использование rsync. * Symlink'и копируются "как есть", чтобы они работали в директории назначения — надо использовать относительные пути. * Убрано ограничение на спец. символы в именах файлов в артефакте. * Теоретически повышена производительность для больших артефактов (не проверено). * Поддержка symlink-ов на стадии g_a_archive * Добавление из rugged в архив через TarWriter * Для этого поставлено ограничение на rubygems '=> 2.5.0'
Возможность создавать symlink'и в артефактах * Переделан механизм копирования файлов артефакта на использование rsync. * Symlink'и копируются "как есть", чтобы они работали в директории назначения — надо использовать относительные пути. * Убрано ограничение на спец. символы в именах файлов в артефакте. * Теоретически повышена производительность для больших артефактов (не проверено). * Исправлена ошибка при использовании docker 17.04.0 (backport из 0.10)
Директива stage_dependencies доведена до рабочего состояния Расчет контрольной суммы содержимого файлов, указанных в stage_dependencies. По факту считается сумма не от содержимого файлов, а от: * патчей, который приводит к актуальному содержимому файлов; * имен файлов; * прав доступа к файлам. Помимо этого были изменены: * GitRepo::Own.patches, GitRepo::Own.diff умеют выдавать патчи до workdir. * Модуль GitArtifactDependencies, который устанавливал параметры-коммиты для GitArtifact::stage_depenencies удален. * На данный момент GitArtifact::stage_depenencies может сам разрулить ситуацию, когда используется dev_mode для локального repo. dev_mode остается в нерабочем состоянии для git-артефактов, добавляемых в артефакт.
PreviousNext