Как Vagrant и
Chef ускорили
разработку в
несколько раз
Тимур Батыршин
Cinarra Systems
Обо мне
Инженер по эксплуатации в
Cinarra Systems
• Тимур Батыршин
• timur@cinarra.com
• @erthad
Cinarra Systems
• Молодая международная
компания
• Строим платформу для
мобильной рекламы
Ситуация год назад
• Инфраструктурой еще
никто не занимается
• Более 10 сильносвязанных
компонентов приложения
• Много конфигов
• Тесты зависят от данных
Проблемы
• Долгий деплой
• Сложность конфигурации
• Создание окружений
• Синхронизация тестовых
окружений
• Воспроизводимость
Chef
http://chef.io
Шаблоны Chef
• Плохо работают для часто
меняющихся конфигов
• Много лишней работы
для большого числа
параметров
Augeas
http://augeas.net
Augeas
$	
  cat	
  /etc/nginx/nginx.conf	
  
user	
  www-­‐data;	
  
worker_processes	
  4;	
  
events	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  multi_accept	
  on;	
  
}	
  
http	
  {	
  
	
   sendfile	
  on;	
  
	
   tcp_nopush	
  on;	
  
	
   tcp_nodelay	
  on;	
  
	
  	
  	
  	
  	
  	
  	
  	
  gzip	
  on;	
  
}
Augeas
$	
  augtool	
  print	
  /files/etc/nginx/nginx.conf	
  
/files/etc/nginx/nginx.conf	
  
/files/etc/nginx/nginx.conf/user	
  =	
  "www-­‐data"	
  
/files/etc/nginx/nginx.conf/worker_processes	
  =	
  "4"	
  
/files/etc/nginx/nginx.conf/events	
  
/files/etc/nginx/nginx.conf/events/multi_accept	
  =	
  "on"	
  
/files/etc/nginx/nginx.conf/http	
  
/files/etc/nginx/nginx.conf/http/sendfile	
  =	
  "on"	
  
/files/etc/nginx/nginx.conf/http/tcp_nopush	
  =	
  "on"	
  
/files/etc/nginx/nginx.conf/http/tcp_nodelay	
  =	
  "on"	
  
/files/etc/nginx/nginx.conf/http/gzip	
  =	
  "on"	
  
Augeas (ресурс Chef)
augeas_template	
  "/etc/cinarra/cate/cate.conf"	
  do	
  
	
  	
  template	
  "/etc/cinarra/cate/cate.conf.sample"	
  
	
  	
  lens	
  "IniFile"	
  
	
  	
  parameters(	
  
	
  	
  	
  	
  "CATE/logging_lev"	
  =>	
  node.cate.log_level,	
  
	
  	
  	
  	
  "CATE/cmgw_host"	
  =>	
  node.cate.cmgw_host,	
  
	
  	
  	
  	
  "CATE/csync_host"	
  =>	
  node.cate.csync_host,	
  
	
  	
  	
  	
  "CATE/csync_port"	
  =>	
  node.cate.csync_port	
  
	
  	
  )	
  
	
  	
  notifies	
  :run,	
  "execute[supervisorctl	
  restart	
  cate]"	
  
end	
  
Augeas
$	
  cat	
  /etc/cinarra/cate/cate.conf.sample	
  
[CATE]	
  
instance_id	
  =	
  1	
  
logging_lev	
  =	
  6	
  
cate_thread_n	
  =	
  2	
  
cmgw_host	
  =	
  127.0.0.1	
  
cmgw_num	
  =	
  2	
  
csync_enabled	
  =	
  true	
  
csync_host	
  =	
  127.0.0.1	
  
csync_port	
  =	
  1234	
  
Augeas
$	
  cat	
  /etc/cinarra/cate/cate.conf	
  
[CATE]	
  
instance_id	
  =	
  1	
  
logging_lev	
  =	
  3	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  #	
  cate.log_level	
  =	
  3	
  
cate_thread_n	
  =	
  2	
  
cmgw_host	
  =	
  10.0.0.2	
  	
  	
  	
  	
  	
  #	
  cate.cmgw_host	
  =	
  10.0.0.2	
  
cmgw_num	
  =	
  2	
  
csync_enabled	
  =	
  true	
  
csync_host	
  =	
  10.0.0.3	
  	
  	
  	
  	
  #	
  cate.csync_host	
  =	
  10.0.0.3	
  
csync_port	
  =	
  1234	
  	
  	
  	
  	
  	
  	
  	
  	
  #	
  cate.csync_port	
  =	
  nil	
  
Плюсы Augeas
• Всеми конфигами
управляем единообразно
• Поддерживает почти все
форматы конфигов
• Строгий — встроенная
валидация синтаксиса
• Можно расширять
Минусы Augeas
• Расширять сложно
• Плохо работает с
нестрогими форматами
• Форматов обычно мало —
теряет смысл
Vagrant
http://vagrantup.com
Образ сервера
• Jenkins ежедневно
собирает AMI при
помощи Packer
• Публикует Vagrant box в
нашем репозитории
Vagrant
Vagrant box
• Packer создает его, если
указан постпроцессор
• Кладем файл .box на
локальный HTTP
• Обновляем JSON с
информацией о версиях
Vagrant box
$	
  cat	
  ~/.vagrant.d/boxes/cinarra-­‐VAGRANTSLASH-­‐baseami-­‐
daily-­‐1.2/1.0.174/aws/Vagrantfile	
  
Vagrant.configure("2")	
  do	
  |config|	
  
	
  	
  config.vm.provider	
  "aws"	
  do	
  |aws|	
  
	
  	
  	
  	
  aws.region_config	
  "eu-­‐west-­‐1",	
  ami:	
  "ami-­‐fb384f8c"	
  
	
  	
  end	
  
end	
  
vagrant box update
Vagrant ищет JSON на
http://vagrantcloud.com/box_name	
  
ubuntu/precise64	
  ⟶	
  	
  
http://vagrantcloud.com/ubuntu/
precise64	
  
Vagrant box
{	
  "name":	
  "orgname/baseami",	
  
	
  	
  "description":	
  "Our	
  brand	
  new	
  vagrant	
  box",	
  
	
  	
  "versions":	
  [	
  
	
  	
  	
  	
  {	
  "version":	
  "1.0.1",	
  
	
  	
  	
  	
  	
  	
  "providers":	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  {	
  "name":	
  "aws",	
  "url":	
  "http://
www.example.com/boxes/orgname/baseami/1.0.1/
packer_amazon-­‐ebs_aws.box"	
  }]},	
  
	
  	
  	
  	
  {	
  "version":	
  "1.0.2",	
  
	
  	
  	
  	
  	
  	
  "providers":	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  {	
  "name":	
  "aws",	
  "url":	
  "http://
www.example.com/boxes/orgname/baseami/1.0.2/
packer_amazon-­‐ebs_aws.box"	
  }]}	
  
]}
Vagrant box
• Переопределяем
VAGRANT_SERVER_URL
• Сервер должен отдавать
тип “application/json”
Разработчику
#	
  Делается	
  один	
  раз	
  при	
  добавлении	
  box-­‐а	
  
export	
  	
  
	
  	
  VAGRANT_SERVER_URL="http://www.example.com/boxes"	
  
vagrant	
  box	
  add	
  orgname/baseami	
  
#	
  Перед	
  работой	
  каждый	
  день	
  
vagrant	
  box	
  update	
  
vagrant	
  up	
  
#	
  После	
  работы	
  
vagrant	
  destroy
Jenkins
http://jenkins-ci.org
Jenkins job
Проблемы
• Параметры разбросаны
по всей конфигурации
• Кнопка “Advanced”
• Сложно менять сразу
несколько сборок
• Работать в UI медленно
Jenkins job
Сборка без checkout
Сборка без checkout
В остальном — обычная
сборка
Jenkins job
Центральная сборка
Центральная сборка
• Задает дополнительные
параметры
• Checkout всех git repo
• Запускает сборки с
нужными параметрами
• Достает и публикует
тесты и артефакты
Jenkins job
Вызов сборки
Другие варианты
• Правка config.xml
• Jenkins API
• Workflow plugin

https://wiki.jenkins-ci.org/display/JENKINS/Workflow+Plugin
• Build Flow plugin

https://wiki.jenkins-ci.org/display/JENKINS/Build+Flow+Plugin
• Job DSL plugin

https://wiki.jenkins-ci.org/display/JENKINS/Job+DSL+Plugin
Workflow plugin
echo	
  "Building	
  in	
  ${env.BASEDIR}"	
  
parallel	
  cnrMain:	
  {	
  
	
  	
  echo	
  "Building	
  cnr-­‐main"	
  
	
  	
  dir("cnr-­‐main")	
  {	
  
	
  	
  	
  	
  gitCheckout(	
  
	
  	
  	
  	
  	
  	
  "https://github.com/cinarra/cnr-­‐main.git",	
  
	
  	
  	
  	
  	
  	
  "remotes/origin/${CNR_BRANCH}",	
  
	
  	
  	
  	
  	
  	
  CNR_CREDENTIALS,	
  CNR_BUILD_TAG	
  
	
  	
  	
  	
  )	
  
	
  	
  	
  	
  sh	
  "make	
  clean	
  deb"	
  
	
  	
  	
  	
  archive	
  includes:	
  "**/*.deb",	
  fingerprint:	
  true	
  
	
  	
  }	
  
},	
  cnrCWS:	
  {	
  
	
  	
  	
  	
  	
  	
  echo	
  "Building	
  cnr-­‐cws"	
  
	
  	
  	
  	
  	
  	
  .	
  .	
  .	
  .	
  .	
  .	
  .	
  .	
  .	
  .	
  .	
  
}
Workflow plugin
Плюсы:
• Храним в Git
• Меняем все сборки сразу
• Легче читать и
отслеживать логику
Workflow plugin
Минусы:
• Пока сыроват
• Не совместим со многими
плагинами
Общий план
Github deb AMI
Devs
Tests
Prod
Preprod
Staging Chef
Vagrant
Спасибо!
Мы ищем программистов
Тимур Батыршин:
• timur@cinarra.com
• @erthad
• http://slideshare.net/erthad

RootConf 2015: Как Vagrant и Chef ускорили разработку в несколько раз

  • 1.
    Как Vagrant и Chefускорили разработку в несколько раз Тимур Батыршин Cinarra Systems
  • 2.
    Обо мне Инженер поэксплуатации в Cinarra Systems • Тимур Батыршин • timur@cinarra.com • @erthad
  • 3.
    Cinarra Systems • Молодаямеждународная компания • Строим платформу для мобильной рекламы
  • 4.
    Ситуация год назад •Инфраструктурой еще никто не занимается • Более 10 сильносвязанных компонентов приложения • Много конфигов • Тесты зависят от данных
  • 5.
    Проблемы • Долгий деплой •Сложность конфигурации • Создание окружений • Синхронизация тестовых окружений • Воспроизводимость
  • 6.
  • 7.
    Шаблоны Chef • Плохоработают для часто меняющихся конфигов • Много лишней работы для большого числа параметров
  • 8.
  • 9.
    Augeas $  cat  /etc/nginx/nginx.conf   user  www-­‐data;   worker_processes  4;   events  {                  multi_accept  on;   }   http  {     sendfile  on;     tcp_nopush  on;     tcp_nodelay  on;                  gzip  on;   }
  • 10.
    Augeas $  augtool  print  /files/etc/nginx/nginx.conf   /files/etc/nginx/nginx.conf   /files/etc/nginx/nginx.conf/user  =  "www-­‐data"   /files/etc/nginx/nginx.conf/worker_processes  =  "4"   /files/etc/nginx/nginx.conf/events   /files/etc/nginx/nginx.conf/events/multi_accept  =  "on"   /files/etc/nginx/nginx.conf/http   /files/etc/nginx/nginx.conf/http/sendfile  =  "on"   /files/etc/nginx/nginx.conf/http/tcp_nopush  =  "on"   /files/etc/nginx/nginx.conf/http/tcp_nodelay  =  "on"   /files/etc/nginx/nginx.conf/http/gzip  =  "on"  
  • 11.
    Augeas (ресурс Chef) augeas_template  "/etc/cinarra/cate/cate.conf"  do      template  "/etc/cinarra/cate/cate.conf.sample"      lens  "IniFile"      parameters(          "CATE/logging_lev"  =>  node.cate.log_level,          "CATE/cmgw_host"  =>  node.cate.cmgw_host,          "CATE/csync_host"  =>  node.cate.csync_host,          "CATE/csync_port"  =>  node.cate.csync_port      )      notifies  :run,  "execute[supervisorctl  restart  cate]"   end  
  • 12.
    Augeas $  cat  /etc/cinarra/cate/cate.conf.sample   [CATE]   instance_id  =  1   logging_lev  =  6   cate_thread_n  =  2   cmgw_host  =  127.0.0.1   cmgw_num  =  2   csync_enabled  =  true   csync_host  =  127.0.0.1   csync_port  =  1234  
  • 13.
    Augeas $  cat  /etc/cinarra/cate/cate.conf   [CATE]   instance_id  =  1   logging_lev  =  3                      #  cate.log_level  =  3   cate_thread_n  =  2   cmgw_host  =  10.0.0.2            #  cate.cmgw_host  =  10.0.0.2   cmgw_num  =  2   csync_enabled  =  true   csync_host  =  10.0.0.3          #  cate.csync_host  =  10.0.0.3   csync_port  =  1234                  #  cate.csync_port  =  nil  
  • 14.
    Плюсы Augeas • Всемиконфигами управляем единообразно • Поддерживает почти все форматы конфигов • Строгий — встроенная валидация синтаксиса • Можно расширять
  • 15.
    Минусы Augeas • Расширятьсложно • Плохо работает с нестрогими форматами • Форматов обычно мало — теряет смысл
  • 16.
  • 17.
    Образ сервера • Jenkinsежедневно собирает AMI при помощи Packer • Публикует Vagrant box в нашем репозитории Vagrant
  • 18.
    Vagrant box • Packerсоздает его, если указан постпроцессор • Кладем файл .box на локальный HTTP • Обновляем JSON с информацией о версиях
  • 19.
    Vagrant box $  cat  ~/.vagrant.d/boxes/cinarra-­‐VAGRANTSLASH-­‐baseami-­‐ daily-­‐1.2/1.0.174/aws/Vagrantfile   Vagrant.configure("2")  do  |config|      config.vm.provider  "aws"  do  |aws|          aws.region_config  "eu-­‐west-­‐1",  ami:  "ami-­‐fb384f8c"      end   end  
  • 20.
    vagrant box update Vagrantищет JSON на http://vagrantcloud.com/box_name   ubuntu/precise64  ⟶     http://vagrantcloud.com/ubuntu/ precise64  
  • 21.
    Vagrant box {  "name":  "orgname/baseami",      "description":  "Our  brand  new  vagrant  box",      "versions":  [          {  "version":  "1.0.1",              "providers":  [                  {  "name":  "aws",  "url":  "http:// www.example.com/boxes/orgname/baseami/1.0.1/ packer_amazon-­‐ebs_aws.box"  }]},          {  "version":  "1.0.2",              "providers":  [                  {  "name":  "aws",  "url":  "http:// www.example.com/boxes/orgname/baseami/1.0.2/ packer_amazon-­‐ebs_aws.box"  }]}   ]}
  • 22.
    Vagrant box • Переопределяем VAGRANT_SERVER_URL •Сервер должен отдавать тип “application/json”
  • 23.
    Разработчику #  Делается  один  раз  при  добавлении  box-­‐а   export        VAGRANT_SERVER_URL="http://www.example.com/boxes"   vagrant  box  add  orgname/baseami   #  Перед  работой  каждый  день   vagrant  box  update   vagrant  up   #  После  работы   vagrant  destroy
  • 24.
  • 25.
  • 26.
    Проблемы • Параметры разбросаны повсей конфигурации • Кнопка “Advanced” • Сложно менять сразу несколько сборок • Работать в UI медленно
  • 27.
  • 28.
  • 29.
    Сборка без checkout Востальном — обычная сборка
  • 30.
  • 31.
  • 32.
    Центральная сборка • Задаетдополнительные параметры • Checkout всех git repo • Запускает сборки с нужными параметрами • Достает и публикует тесты и артефакты
  • 33.
  • 34.
  • 35.
    Другие варианты • Правкаconfig.xml • Jenkins API • Workflow plugin
 https://wiki.jenkins-ci.org/display/JENKINS/Workflow+Plugin • Build Flow plugin
 https://wiki.jenkins-ci.org/display/JENKINS/Build+Flow+Plugin • Job DSL plugin
 https://wiki.jenkins-ci.org/display/JENKINS/Job+DSL+Plugin
  • 36.
    Workflow plugin echo  "Building  in  ${env.BASEDIR}"   parallel  cnrMain:  {      echo  "Building  cnr-­‐main"      dir("cnr-­‐main")  {          gitCheckout(              "https://github.com/cinarra/cnr-­‐main.git",              "remotes/origin/${CNR_BRANCH}",              CNR_CREDENTIALS,  CNR_BUILD_TAG          )          sh  "make  clean  deb"          archive  includes:  "**/*.deb",  fingerprint:  true      }   },  cnrCWS:  {              echo  "Building  cnr-­‐cws"              .  .  .  .  .  .  .  .  .  .  .   }
  • 37.
    Workflow plugin Плюсы: • Хранимв Git • Меняем все сборки сразу • Легче читать и отслеживать логику
  • 38.
    Workflow plugin Минусы: • Покасыроват • Не совместим со многими плагинами
  • 39.
    Общий план Github debAMI Devs Tests Prod Preprod Staging Chef Vagrant
  • 40.
    Спасибо! Мы ищем программистов ТимурБатыршин: • timur@cinarra.com • @erthad • http://slideshare.net/erthad