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

De desarrollo a Producción con Docker

pbruna
October 25, 2014

De desarrollo a Producción con Docker

Presentación sobre Docker dada en RubyConfAr 2014

pbruna

October 25, 2014
Tweet

More Decks by pbruna

Other Decks in Technology

Transcript

  1. Voy a programar algo en 3 meses pero creo que

    no debería usar Perl ni Bash
  2. Lecciones del deploy • Ruby 1.8.2? • Debo usar RVM!!!

    • RVM ya no la lleva, ahora es RBENV/CHRUBY • Puppet no lo hace más fácil • Estoy haciendo el Deploy en CentOS 6, pero • CentOS 7 está por salir… ¿todo de nuevo? • Cómo escalará? - Porque así pensamos • Yosemite!!! —- Ahora ni en dev funciona
  3. Docker, Containers, and the Future of Application Delivery Why docker

    | OSCON 2013 by Docker http://www.slideshare.net/dotCloud/why-docker2bisv4
  4. ¿Por qué Docker? • Boostraps más rápidos para nuestros productos

    • Entornos de desarrollo realmente portables • Mucho, pero mucho más liviano que una VM • Si funciona en desarrollo, funciona en producción
  5. Como uso Docker Linux $ yum install docker $ apt-get

    install docker Mac OS X y Windows (si también Windows) https://github.com/boot2docker/boot2docker
  6. Docker API REST docker se comunica con su API REST

    $  docker  info   Containers:  41   Images:  192   Storage  Driver:  aufs    Root  Dir:  /mnt/sda1/var/lib/docker/aufs    Dirs:  274   Execution  Driver:  native-­‐0.2   ...   Sockets:  [unix:///var/run/docker.sock  tcp://0.0.0.0:2375]   Username:  pbruna   Registry:  [https://index.docker.io/v1/]   $  _ https://docs.docker.com/reference/api/docker_remote_api_v1.15/
  7. Docker API REST docker se comunica con su API REST

    $  curl  -­‐X  GET  http://192.168.59.103:2375/info   {"Containers":37,"Debug":1,"Driver":"aufs","DriverStatus": [["Root  Dir”,"/mnt/sda1/var/lib/docker/aufs"], ["Dirs","212"]],"ExecutionDriver":"native-­‐0.2","IPv4Forwar ding":1,"Images":138,"IndexServerAddress":"https:// index.docker.io/v1/","InitPath":"/usr/local/bin/ docker","InitSha1":"","KernelVersion":"3.15.3-­‐ tinycore64","MemoryLimit":1,"NEventsListener":0,"NFd": 11,"NGoroutines":10,"Sockets":["unix:///var/run/ docker.sock","tcp://0.0.0.0:2375"],"SwapLimit":1}   $  _ https://docs.docker.com/reference/api/docker_remote_api_v1.15/
  8. Mi flujo de trabajo con Docker 1. Seleccionar imagen base

    2. Se personaliza la imagen (Fork): Dockerfile 3. Construimos la nueva imagen: docker build 4. Push de la imagen a Docker Hub 5. Dockerizo aplicación: Dockerfile 6. Construyo container (!= imagen) 7. Paso a producción
  9. 2. Fork de la imagen  1|  #  Mi  imagen  base

     para  mis  aplicaciones  Rails  >=4    2|  FROM  phusion/passenger-­‐ruby21:0.9.14    3|  MAINTAINER  Patricio  Bruna  <[email protected]>    4|    5|  #  Acceso  SSH  con  llave    6|  ADD  pbruna-­‐ssh-­‐key.pub  /tmp/your_key    7|  RUN  cat  /tmp/your_key  >  /root/.ssh/authorized_keys  &&  rm  -­‐f  /tmp/your_key    8|    9|  #  Instalamos  Rails  con  las  gems  que  mas  uso   10|  ADD  Gemfile  /home/app/   11|  ADD  Gemfile.lock  /home/app/   12|  WORKDIR  /home/app/   13|  RUN  bundle  install   14|   15|#  Clean  up  APT  when  done.   16|  RUN  apt-­‐get  clean  &&  rm  -­‐rf  /var/lib/apt/lists/*  /tmp/*  /var/tmp/* Cada orden genera un commit cada commit afecta el cache
  10. 2. Fork de la imagen  1|  #  Mi  imagen  base

     para  mis  aplicaciones  Rails  >=4    2|  FROM  phusion/passenger-­‐ruby21:0.9.14    3|  MAINTAINER  Patricio  Bruna  <[email protected]>    4|    5|  #  Acceso  SSH  con  llave    6|  ADD  pbruna-­‐ssh-­‐key.pub  /tmp/your_key    7|  RUN  cat  /tmp/your_key  >  /root/.ssh/authorized_keys  &&  rm  -­‐f  /tmp/your_key    8|    9|  #  Instalamos  Rails  con  las  gems  que  mas  uso   10|  WORKDIR  /home/app/   11|  ADD  Gemfile  /home/app/   12|  ADD  Gemfile.lock  /home/app/   13|  ADD  .bashrc  /home/app/   14|   15|  RUN  bundle  install   16|#  Clean  up  APT  when  done.   17|  RUN  apt-­‐get  clean  &&  rm  -­‐rf  /var/lib/apt/lists/*  /tmp/*  /var/tmp/*
  11. 2. Fork de la imagen  1|  #  Mi  imagen  base

     para  mis  aplicaciones  Rails  >=4    2|  FROM  phusion/passenger-­‐ruby21:0.9.14    3|  MAINTAINER  Patricio  Bruna  <[email protected]>    4|    5|  #  Acceso  SSH  con  llave    6|  ADD  pbruna-­‐ssh-­‐key.pub  /tmp/your_key    7|  RUN  cat  /tmp/your_key  >  /root/.ssh/authorized_keys  &&  rm  -­‐f  /tmp/your_key    8|    9|  #  Instalamos  Rails  con  las  gems  que  mas  uso   10|  WORKDIR  /home/app/   11|  ADD  Gemfile  /home/app/   12|  ADD  Gemfile.lock  /home/app/   13|  RUN  bundle  install   14|   15|  ADD  .bashrc  /home/app/   16|#  Clean  up  APT  when  done.   17|  RUN  apt-­‐get  clean  &&  rm  -­‐rf  /var/lib/apt/lists/*  /tmp/*  /var/tmp/*
  12. 3. Construyo la imagen y la publico en el registry

    (hub.docker.com) [pbruna@home]  docker  build  -­‐t=“pbruna/rubyconfar-­‐rails:0.1”  .  
  13. 5. Dockerizar la aplicación FROM  pbruna/rubyconfar-­‐rails   MAINTAINER  Patricio  Bruna

     <[email protected]>   RUN  rm  -­‐f  /etc/service/nginx/down   RUN  mkdir  -­‐p  /home/app/rubyconfar   RUN  mkdir  -­‐p  /etc/service/delayed_job   WORKDIR  /home/app/rubyconfar   ADD  Gemfile  /home/app/rubyconfar/   ADD  Gemfile.lock  /home/app/rubyconfar/   RUN  bundle  install   #  Aprovechamos  el  Cache  de  Docker   ADD  config/folio-­‐nginx.conf  /etc/nginx/sites-­‐enabled/rubyconfar-­‐nginx.conf   ADD  config/folio-­‐nginx-­‐env.conf  /etc/nginx/main.d/rubyconfar-­‐env.conf   ADD  scripts/delayed_job.sh  /etc/service/delayed_job/run   ADD  .  /home/app/rubyconfar   ENV  RAILS_ENV  production   RUN  rake  db:migrate   RUN  rake  db:seed   RUN  rake  tmp:create   RUN  chown  9999:9999  -­‐R  /home/app/rubyconfar   EXPOSE  80   CMD  ["/sbin/my_init"]
  14. 5.1 Variables de Entorno #  /etc/nginx/main.d/folio-­‐nginx-­‐env.conf   env  APP_DB_HOST;  

    env  APP_DB_PORT;   env  APP_DB_DATABASE;   env  APP_DB_USERNAME;   env  APP_DB_PASSWORD;   env  RAILS_ENV=production; #  config/database.yml   production:      adapter:  mysql2      host:  <%=  ENV['APP_DB_HOST']  %>      port:  <%=  ENV['APP_DB_PORT']  ||  "3306"  %>      database:  <%=  ENV['APP_DB_DATABASE']  %>      username:  <%=  ENV['APP_DB_USERNAME']  %>      password:  <%=  ENV['APP_DB_PASSWORD']  %>
  15. Ejecutar el contenedor [pbruna@home]  boot2docker  status   running   [pbruna@home]

     docker  run  -­‐d  -­‐p  80:80  -­‐e  "APP_DB_HOST=IP_OTRAVM"  -­‐e   "APP_DB_DATABASE=rubyconfar"  -­‐e  "APP_DB_USERNAME=rubyconfar"  -­‐e   "APP_DB_PASSWORD=rubyconfar"  pbruna/rubyconfar   facf1576330dd6424a8bb37833bf9ff17844bdba2d813a6690ff59491c325e53   [pbruna@home]  curl  -­‐H  "Host:  docker.rubyconf.com.ar"  http://$DOCKER_IP_HOST/hello   Hola  a  todos!!   [pbruna@home]  docker  inspect  sharp_hawking  #  Nombre  del  momento   .  .  .   .  .  .   [pbruna@home]  docker  stop  sharp_hawking  #  nombre  del  momento   [pbruna@home]  cd  ~/tmp/  
  16. Compartir el entorno [pbruna@home]  docker  save  pbruna/rubyconfar  |  pv  |

     bzip2  -­‐  >  docker_rubyconfar.bz2   214MiB  0:00:28  [6,37MiB/s]  [                                                                <=>                                    ]   [pbruna@home]  ls  -­‐lh  docker_rubyconfar.bz2   -­‐rw-­‐r-­‐-­‐r-­‐-­‐    1  pbruna    staff        89M  19  oct  16:04  docker_rubyconfar.bz2   ...   ...   [pbruna@home]  bzcat  docker_rubyconfar.bz2  |  docker  load [pbruna@home]  docker  pull  pbruna/rubyconfar   [pbruna@home]  docker  run  -­‐p  80:80  pbruna/rubyconfar
  17. Fig web:      build:  .      command:  python

     app.py      links:        -­‐  db      ports:        -­‐  "8000:8000"   db:      image:  postgres FROM  python:2.7   ADD  .  /code   WORKDIR  /code   RUN  pip  install  -­‐r   requirements.txt
  18. CoreOS 01-03 docker - nginx-lb - folio - ccw -

    nagios - logstash - grafana/kibana S3 MySQL Master Mailgun
  19. #  /etc/systemd/system/rubyconfar.service   [Unit]   Description=Ruby  Conf  AR  Docker  Example

      After=docker.service   Requires=docker.service   [Service]   TimeoutStartSec=0   ExecStartPre=-­‐/usr/bin/docker  kill  rubyconfar-­‐01   ExecStartPre=-­‐/usr/bin/docker  rm  rubyconfar-­‐01   ExecStartPre=/usr/bin/docker  pull  rubyconfar   ExecStart=/usr/bin/docker  run  -­‐-­‐name  -­‐p  80:80  rubyconfar-­‐01  rubyconfar   [Install]   WantedBy=multi-­‐user.target AAASS [pbruna@coreOS-­‐01]  sudo  systemctl  enable  /etc/systemd/system/rubyconfar.service   [pbruna@coreOS-­‐01]  sudo  systemctl  start  rubyconfar.service   [pbruna@coreOS-­‐01]  journalctl  -­‐f  -­‐u  rubyconfar.service
  20. Actualizaciones 1. [pbruna@dev] git push -u origin master 2. [pbruna@dev]docker

    build -t=“pbruna/rubyconfar:0.2” . 3. [pbruna@dev]docker tag 0f6e1da7eb37 pbruna/rubyconfar:latest 4. [pbruna@dev] docker push pbruna/rubyconfar 5. [pbruna@dev]ssh coreos-01 6. [pbruna@coreOS-01] sudo systemctl restart rubyconfar.service
  21. Como lo estamos haciendo etcd Distributed key value store that

    provides the backbone of CoreOS clusters confd Manage local application configuration files using templates and data from etcd or consul fleet With fleet, you can treat your CoreOS cluster as if it shared a single init system. systemd CoreOS uses systemd as the core of its distributed init system, fleet