Jenkins entwined with deployment and pragmatism

22
Novadex GmbH 2013. All rights reserved, also regarding any disposal, exploita>on, reproduc>on, edi>ng, distribu>on, as well as in the event of applica>ons for industrial property rights. Jenkins entwined with deployment and pragma>sm Eric Ritchie DevOps Engineer Novadex +49 (0) 7142 / 7889050 [email protected]

description

Jenkins (to name just one CI tool) is a central pillar of agile development and does a terrific job of automating the project build process. Providing a reliable deployment path to a cluster of servers is something that it does less well and forms the challenge being faced by many today. In this talk Novadex GmbH, a leader in cloud based customer communication management, will demonstrate their pragmatic solution to this challenge which uses the toolkit provided by Zend Server

Transcript of Jenkins entwined with deployment and pragmatism

Page 1: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Jenkins  entwined  with  deployment    and  pragma>sm  

   

 Eric  Ritchie  DevOps  Engineer  Novadex      +49  (0)  7142  /  788905-­‐0  [email protected]          

Page 2: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Eric  Ritchie  bids  you  welcome!  

20/11/13   2  

§  currently  working  as  DevOps  Engineer  and    System  Administrator  at  Novadex  GmbH  

§  a  Zend  Framework  and  PHP  ZCE  &  MySQL  DBA  

§  a  Linux  System  Administrator  with  18  years  experience  

§  a  PHP  developer  since  version  3.0.18  (or  so)  

§  known  to  speak  at  a  conference  or  two    

Never  heard  of  him?  Aside  from  looking  like  this,  he  is:  

Page 3: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

LeaerMaschine:  Custom-­‐tailored  Communica>on  

   

Personalized  data  stream    Cross-­‐Channel  Output  

Collabora>on  

Portal  Op>on  Campaign  management  

CRM  integra>on  

Content  management  E-­‐commerce  integra>on  

Data  protec>on  Security  

20/11/13   3  

Page 4: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

What  I  read  in  a  book  once…  

20/11/13   4  

„DevOPs  should  aim  for  10  deployments  per  day“  

Page 5: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Novadex’s  key  tool:  Jenkins  

20/11/13   5  

§  Great  for  Con?nuous  Integra?on  

§  Can  hide  complex  processes  behind  a  nice  buDon  

§  Deployment  remains  one  of  those  complex  processes  §  Requires  a  lot  of  scrip>ng/manual  work  §  This  risks  our  deployment  goal  

Page 6: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

An  example  of  that  scrip>ng  

20/11/13   6  

 <target  name="package">                  <echo  message="...using  UPSTREAM_BUILD_NUMBER  received  from  triggering  job  for  packagenaming.  UPSTREAM_BUILD_NUMBER  is  [${UPSTREAM_BUILD_NUMBER}]"/>                    <!-­‐-­‐  leaermaschine-­‐complete  packaging  -­‐-­‐>                    <!-­‐-­‐  wipe  the  dir  from  possible  previous  copy  opera>on  -­‐-­‐>                  <delete  includeemptydirs="true">                          <fileset  dir="${package.contents.basedir}"  includes="**/*"/>                          <fileset  dir="${package.basedir}/DEBIAN"  includes="**/*"/>                  </delete>                    <!-­‐-­‐  prepare  debian  control  file  -­‐-­‐>                  <copy  todir="${package.basedir}/DEBIAN"  overwrite="true">                          <fileset  file="resource/package/test/control"/>                          <filterset  begintoken="[["  endtoken="]]">                                  <filter  token="version"  value="${UPSTREAM_BUILD_NUMBER}-­‐1"/>                                  <filter  token="name"  value="leaermaschine-­‐complete"/>                                  <filter  token="depends"  value=""/>                                  <filter  token="descrip>on"  value="Complete  Leaermaschine  applica>on"/>                          </filterset>                  </copy>                    <!-­‐-­‐  copy  pos>nstalla>on  script  -­‐-­‐>                  <copy  file="${basedir}/resource/package/test/pos>nst_lm"  tofile="${package.basedir}/DEBIAN/pos>nst"/>                  <chmod  file="${package.basedir}/DEBIAN/pos>nst"  perm="775"/>                    <copy  todir="${package.contents.basedir}">                          <fileset  dir="${export.basedir}">                                  <snip>                          </fileset>                  </copy>                    <exec  executable="sudo"  dir="${working.basedir}"  failonerror="true">                          <arg  line="sudo  dpkg  -­‐b  ${package.basedir}  ${dist.basedir}/leaermaschine-­‐complete_${UPSTREAM_BUILD_NUMBER}-­‐1_all.deb"/>                  </exec>          </target>  

Page 7: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Deployment  v1.x?  

20/11/13   7  

§  Applica?on  bundled  into  a  .deb  package  §  As  shown  on  the  previous  slide  (yeah,  that’s  what  it  did)  §  Shell  scrip>ng  available  for  in  deployment  manipula>ons  

§  SCP’d  to  target  machine,  installed  via  SSH  exec    §  Need  to  set  up  SSL  cer>ficates  to  allow  password  free  access  

Page 8: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Problems?  

20/11/13   8  

§  Who  is  comfortable  with  bash  shell  scrip?ng?  

§  What  happens  when  something  goes  wrong?    §  Ever  tried  to  roll  back  a  copied  .deb  package  in  a  hurry?  

§  Not  really  all  that  cluster  friendly  §  Ok,  we  have  Chef/Puppet  if  we  like  overkill  

§  Disk  cluDer  §  Each  version  of  the  .deb  package  is  cached    

§  Need  to  grant  unlimited  access  to  live  servers,  argh!  §  Remember  that  SSL  cer>ficate  we  installed?    

§  What  if  we  need  to  support  Red  Hat  also?  §  Hypothe>cal  in  the  case  of  Novadex,  but  s>ll  a  valid  problem.  

Page 9: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Enter  Zend  Server  deployment  (and  me)  

20/11/13   9  

Cluster/Cloud  ready,  plaxorm  agnos>c,  PHP  scrip>ng  and  version  handling  with  integrated  roll  back.  

Yes,  I  used  to  work  for  Zend  ;)  

Page 10: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Tale  of  the  liale  known  tool:  zs-­‐manage  

20/11/13   10  

§  We  all  have  heard  about  the  Web  API,  right?  §  You  may  be  forgiven  for  thinking  it  is  a  new  thing  

§  We  have  had  command  line  deployment  tools  since  day  one    §  But  nobody  knew  about  them,  which  is  a  pity  

§  zs-­‐manage  has  many  advantages  §  Can  leverage  all  deployment  features  §  Does  not  rely  on  SSL  cer>ficates  for  security  §  Same  commands  for  local/cluster/cloud  deployment  

§  But  beware,  there  are  some  caveats  §  Pragma>sm  to  follow...  

Page 11: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Let’s  empower  Jenkins…  

20/11/13   11  

 <!-­‐-­‐  retrieve  the  app.id  for  the  applica>on,  specified  by  app.name.  may  be  empty  if  app  hasn't  already  deployed    -­‐-­‐>                  <exec  executable="bash"  dir="${basedir}"  outputproperty="app.id"  errorproperty="err"  failonerror="true">                          <arg  value="-­‐c"  />                          <arg  value="/usr/local/zend/bin/zs-­‐manage  app-­‐get-­‐status                                  -­‐N  ${zs.api.name}                                  -­‐U  ${zs.url}                                  -­‐K  ${zs.api.key}  2&gt;&amp;1  |  grep  &quot;APPINFO\\s.*${app.name}.*&quot;  |  awk  '{print  $2}'"  />                  </exec>                  <if>                    <equals  arg1="${app.id}"  arg2=""  />                    <then>                        <echo  message="Couldn't  determine  app.id  for  app.name  '${app.name}'  -­‐  preparing  ini>al  deployment  of  applica>on  ..."  />                          <!-­‐-­‐  deploy  applica>on  via  zend  server  command  -­‐-­‐>                          <exec  executable="/usr/local/zend/bin/zs-­‐manage"  dir="/tmp"  failonerror="true">                                  <arg  line="app-­‐deploy                                          -­‐u  &quot;NDX_ENV=${zs.ndx.env}&quot;                                          -­‐c                                          -­‐b  hap://${app.name}/                                          -­‐a  ${app.name}                                          -­‐p  ${zs.package.des>na>ondir}/${zs.package.name}                                          -­‐N  ${zs.api.name}                                          -­‐K  ${zs.api.key}                                          -­‐U  ${zs.url}"  />                          </exec>                    </then>                    <else>                          <echo  message="app.name  '${app.name}',  app.id  is  ${app.id}  -­‐  preparing  the  update  of  applica>on  ..."  />                          <!-­‐-­‐  update  applica>on  via  zend  server  command  -­‐-­‐>                          <exec  executable="/usr/local/zend/bin/zs-­‐manage"  dir="/tmp"  failonerror="true">                                  <arg  line="app-­‐update                                          -­‐u  &quot;NDX_ENV=${zs.ndx.env}&quot;                                          -­‐i  ${app.id}                                          -­‐p  ${zs.package.des>na>ondir}/${zs.package.name}                                          -­‐N  ${zs.api.name}                                          -­‐K  ${zs.api.key}                                          -­‐U  ${zs.url}"  />                          </exec>                    </else>                  </if>  

Page 12: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Crea>ng  the  package  to  be  deployed  

20/11/13   12  

§  We  have  a  choice  §  Zend  Studio  -­‐  a  manual  process  §  zdpack  -­‐  Zend  standard  §  zip  -­‐  needs  no  introduc>on  

§  Novadex  have  used  zip  at  ?mes  §  But  currently  use  the  following  code  

               <exec  executable="/usr/local/zend/bin/zdpack"  dir="${working.basedir}"  failonerror="true">                          <!-­‐-­‐  NOTE:  name  of  the  created  package  is  the  name  specified  in  deployment.xml  name-­‐tag  -­‐-­‐>                          <arg  line="pack                                  -­‐-­‐src-­‐dir=${package.contents.basedir}                                  -­‐-­‐scripts-­‐dir=${basedir}/resource/zs_deploy_new/scripts                                  -­‐-­‐package-­‐descriptor=${working.basedir}/deployment.xml                                  -­‐-­‐output-­‐dir=${working.basedir}"  />                  </exec>                  <!-­‐-­‐  rename  created  package  to  reflect  version  of  package  contents  -­‐-­‐>                  <move  file="${working.basedir}/${app.name}.zpk"  tofile="${working.basedir}/${zs.package.name}"  overwrite="true"/>                    <!-­‐-­‐  copy  the  new  package  from  temp  loca>on  to  package  directory  -­‐-­‐>                  <copy  file="${working.basedir}/${zs.package.name}"  todir="${zs.package.des>na>ondir}"  overwrite="true"/>  

Page 13: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Sadly,  size  does  maaer  

20/11/13   13  

§  You  don’t  leave  your  doors  unlocked  when  you  leave  home  §  Most  admins  are  equally  careful  with  their  servers  

§  Web  API  could  be  an  aDack  vector    §  Which  is  why  Zend  take  steps  to  secure  it  §  Web  API  calls  must  be  signed  with,  amongst  other  informa>on,  a  >mestamp  

§  To  help  prevent  replay  aDacks,  calls  must  complete  within  300  seconds  §  This  security  feature  can  shoot  us  in  the  foot  §  In  short,  the  network  speed  determines  our  maximum  packet  size  

Page 14: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Working  around  the  size  issue  

20/11/13   14  

§  No  perfect  solu?ons,  yet  §  I  am  working  on  Zend  ;)  

§  But  we  can  apply  some  pragma?sm  §  Package  can  be  broken  into  sub-­‐packages  §  Zend  Deployment  has  a  new  Library  feature,  use  it  §  Pull  instead  of  push  §  Upgrade  the  pipe  §  Time  travel  §  Or,  emulate  the  GUI  

Page 15: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Our  solu>on    

20/11/13   15  

 <echo  message="copying  ${zs.package.name}  to  ${remote.hostname}"  />                  <scp  file="${zs.package.des>na>ondir}/${zs.package.name}"                          todir="${remote.user}@${remote.hostname}:${remote.dir}"                          keyfile="${remote.keyfile}"                  />                    <echo  message="app.name  '${app.name}',  app.id  is  '${app.id}'  -­‐  preparing  the  update  of  applica>on  ..."  />                  <!-­‐-­‐  execute  zs-­‐manage  locally  on  host  where  package  should  be  deployed!  -­‐-­‐>                  <sshexec                          host="${remote.hostname}"                          username="${remote.user}"                          keyfile="${remote.keyfile}"                          command="/usr/local/zend/bin/zs-­‐manage  app-­‐update  -­‐u  &quot;NDX_ENV=${zs.ndx.env}&quot;  -­‐i  ${app.id}                                                                        -­‐p  ${remote.dir}/${zs.package.name}  -­‐N  ${zs.api.name}  -­‐K  ${zs.api.key}  -­‐U  ${remote.webapi.url}"                  />  

GUI  emula?on:  It  works  for  us  

Just  remember:  SCP/SSH  may  not  be  allowed  by  your  opera>ons  team.                                                              You  may  need  another  solu>on  !   !  

Page 16: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Memory  and  lots  of  it  

20/11/13   16  

§  Ques?on:  Where  does  all  this  deployment  data  go?  §  Hint:  The  WebAPI  is  part  of  the  GUI  

§  The  GUI  allocates  memory  equivalent  to  three  ?mes  the  packet  size    §  Since  the  data  is  loaded,  copied  and  finally  unpacked  (don’t  ask)  

§  Where  is  the  GUI’s  memory  limit  configured?  §  Not  in  the  GUI,  that  would  spoil  the  fun  ;)  §  Can  you  guess?  

Answer:    The  memory_limit  variable  in:  /usr/local/zend/gui/lighapd/etc/php-­‐fcgi.ini  

Page 17: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Aaack  of  the  cluster  

20/11/13   17  

§  Zend  deployment  can  be  hard  to  synchronise  §  In  other  words,  you  cannot  guarantee  when  all  nodes  will  run  the    

same  version  of  the  applica>on  

§  An  extreme  case  is  the  “run  once”  node  §  Database  migra>ons  are  usually  performed  here,  so  deployment  is  slower  

§  This  caused  problems  with  our  “In  maintenance”  page  §  Time  for  some  extreme  pragma>sm…  

Page 18: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

I  am  a  Job  Queue  fan…  so  I  wrote  this  

20/11/13   18  

//  Sanity  check  if  (!class_exists('ZendJobQueue')){          logger("Job  Queue  seems  to  be  disabled!");          exit(1);  }    if  (getenv("ZS_RUN_ONCE_NODE")  ==  1)  {          $name  =  DEPLOYMENT_JOB_BASENAME.$appCurrentVersion;          $queue  =  new  ZendJobQueue();                    //  Before  scheduling  our  job,  just  make  sure  that  it  has  not  been  scheduled  before          $total  =  null;          $jobArray  =  $queue-­‐>getJobsList(array('name'  =>  $name),  $total);          if  ($total  !=  0)  {                  foreach($jobArray  AS  $job)  {                          $queue-­‐>removeJob($job['id']);                  }          }                    //  Schedule  the  job  script  to  run  a  long  >me  in  the  future  (since  we  don't  really  need  it  to  run)          $runAt  =  date('Y-­‐m-­‐d  H:i:s',  strto>me('+7  days'));                    $semaphoreJobId  =  $queue-­‐>createHapJob('hap://www.google.de/search?q=dummy',                                                                                                                                                                            array(),  array('name'  =>  $name,  'schedule_?me'  =>  $runAt));          if  (!$semaphoreJobId)  {                  logger("Semphore  job  was  not  accepted  in  the  queue!");                  exit(1);          }  }  

Page 19: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

…and  this  at  the  end  of  the  script  

20/11/13   19  

if  (getenv("ZS_RUN_ONCE_NODE")  ==  1)  {          //  We  are  the  RUN  ONCE  script  so  clear  the  semaphore          $queue-­‐>removeJob($semaphoreJobId);  }  else  {          //  We  are  not  the  RUN  ONCE  script  so  wait  for  it  to  clear  the  semaphore          $queue  =  new  ZendJobQueue();            $total  =  1;          $status  =  ZendJobQueue::JOB_STATUS_PENDING  |  ZendJobQueue::JOB_STATUS_SCHEDULED;          while  ($total  !=  0)  {                  $jobArray  =  $queue-­‐>getJobsList(array('name'  =>  $name,  'status'  =>  $status),  $total);                  sleep(1);          }  }  

We  now  plan  to  use  an  Nginx,  that  spontaneously  appeared  in  our  architecture,  to  set  our  maintenance  page.  Nevertheless,  it  was  s>ll  a  cool  idea  ;)  

Page 20: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

Finding  out  what  is  happening  

20/11/13   20  

§  So  far  so  good,  but  we  s?ll  don’t  have  true  integra?on  §  Jenkins  has  no  liale*  visibility  over  the  deployment  process  

§  We  can  log  the  output  of  our  deployment  scripts  §  But  these  are  not  available  to  Jenkins  §  We  can  make  them  available  to  the  GUI,  at  least,  by  adding  the  paths  to  the  

GUI_AVAILABLE_LOGS  table  in  the  Zend  Server  database  §  More  convenient,  but  we  s>ll  need  to  go  check  the  GUI  a�er  each  deployment  

*  Last  minute  slide  hack  

Page 21: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

WebAPI  to  the  rescue…  again  

20/11/13   21  

§  Features  added  to  the  WebAPI  allow  registered  logs  to  be  remotely  read  §  logsReadLines  §  logsGetLogfile  

§  We  can  finally  integrate  log  output  into  our  Jenkins  reports    

§  Just  a  few  problems  §  Finding  the  “run  once”  node    §  These  methods  are  not  implemented  in  zs-­‐manage  (yet)  §  Wri>ng  the  code  (I  haven’t  had  the  >me  yet)  

Page 22: Jenkins entwined with deployment and pragmatism

Novadex  GmbH  2013.  All  rights  reserved,  also  regarding  any  disposal,  exploita>on,  reproduc>on,  edi>ng,  distribu>on,  as  well  as  in  the  event  of  applica>ons  for  industrial  property  rights.    

www.novadex.com    

www.leaermaschine.com  

Please  scan  this    …and  tell  me  where  it  goes  

 Honestly,  marke>ng  wouldn’t  tell  me!  

Thank  you  very  much  for  your  aaen>on  

20/11/13   22  

Eric  Ritchie  DevOps  Engineer  hDps://joind.in/9926    

+49  (0)  7142  /  788905-­‐0  [email protected]    

     Novadex  GmbH    Stuagarter  Straße  59  74321  Bie>gheim-­‐Bissingen  Germany