$30 off During Our Annual Pro Sale. View Details »

Docker, Ceci N'Est Pas Une Introduction (APIHour #12)

Docker, Ceci N'Est Pas Une Introduction (APIHour #12)

Docker, l'une des technologies les plus en vogue ces derniers temps, permet de créer des conteneurs logiciels. Retour sur mon utilisation pour le développement mais également pour la production, avec en ligne de mire : une architecture micro-services, quelques principes 12 Factors et un déploiement en (presque) zéro-downtime.

Sources: https://github.com/willdurand-slides/docker-clermontech

William Durand

December 15, 2014
Tweet

More Decks by William Durand

Other Decks in Programming

Transcript

  1. (Ceci N'Est Pas Une Introduction)
    William Durand ‑ December 16th, 2014

    View Slide

  2. Docker In A Nutshell

    View Slide

  3. Containers
    A container is an operating‑system level virtualization
    method that provides a completely isolated
    environment, simulating a closed system running on a
    single host.
    chroot, OpenVZ, Jail, LXC, etc.

    View Slide

  4. Containers vs VMs

    View Slide

  5. Docker
    Developed by Docker.inc (formerly DotCloud)
    Open platform for developing, shipping,
    and running applications
    Use as execution driver
    libcontainer

    View Slide

  6. Docker's Architecture
    Host
    Container 1
    Container 2
    Container 3
    Container ...
    Docker Client
    docker pull
    docker run
    docker ...
    Docker Index
    Docker Daemon

    View Slide

  7. The Plan
    Simple solution to deploy my application
    Idempotent and reliable process
    No need for rollbacks
    Targetting zero downtime
    Single host

    View Slide

  8. How?

    View Slide

  9. Methodology

    View Slide

  10. Twelve Factors
    One codebase tracked in revision control,
    many deploys
    Store config in the environment
    Keep development, staging, and production
    as similar as possible
    by
    The Twelve‑Factor App @aymericbrisse

    View Slide

  11. Infrastructure

    View Slide

  12. Services
    Reverse proxy: (+ )
    Backend: + + application
    Sessions are stored into
    Database (at some point...)
    Hipache Redis
    Nginx HHVM
    memcached

    View Slide

  13. Overall Architecture

    View Slide

  14. Application's fig.yml
    web:
    build: .
    # No support for `env-file` yet...
    # See: https://github.com/docker/fig/pull/665
    environment:
    - SYMFONY_ENV=dev
    - SYMFONY_DEBUG=1
    - SYMFONY__MEMCACHED_HOST=memcached
    - SYMFONY__MEMCACHED_PORT=11211
    - SYMFONY__SESSION_MEMCACHED_PREFIX=session
    - SYMFONY__SESSION_MEMCACHED_EXPIRE=604800
    links:
    - memcached
    - database

    View Slide

  15. Application's Dockerfile
    FROM debian:wheezy
    MAINTAINER William Durand
    ENV DEBIAN_FRONTEND noninteractive
    # Let APT know about HHVM repo...
    RUN apt-get update -y
    RUN apt-get install -y nginx hhvm supervisor
    # Configure Nginx, HHVM, Supervisor here...
    ADD . /app
    WORKDIR /app
    EXPOSE 80
    CMD [ "/usr/bin/supervisord" ]

    View Slide

  16. DNS
    example.org w www.example.org
    Configured at the DNS level. Faster than making
    this redirection using the load balancer.

    View Slide

  17. SSL
    Hipache listens on ports 80 and 443.
    Patched version of Hipache to redirect
    HTTP traffic to HTTPS. Sort of SSL offloading.
    ® willdurand/docker‑hipache

    View Slide

  18. Deploy

    View Slide

  19. 1. Build Artifact
    git archive --format tar --prefix myapp/ | (cd /tmp && tar xf -)
    Protip: use a Docker container to run build tools:
    cd /tmp/myapp
    docker run --rm -v `pwd`:/srv buildtools composer install
    docker run --rm -v `pwd`:/srv buildtools bundle install
    docker run --rm -v `pwd`:/srv buildtools bower install
    rm

    View Slide

  20. 2. Build Container (From Artifact)
    docker build -t myapp:latest .

    View Slide

  21. 3. Push It
    docker push
    q Or whatever that makes the image
    available on the production server.

    View Slide

  22. 4. Retrieve Running Containers
    RUNNING_CIDS=$(docker ps | grep web | cut -d ' ' -f 1)

    View Slide

  23. 5. Run The New Container
    fig run -d --no-deps --rm web
    † Booting the container may take a few seconds, wait.

    View Slide

  24. 6. Register It As Backend
    IP=$(docker inspect --format='{{ .NetworkSettings.IPAddress }}' )
    fig run --rm rediscli rpush frontend:www.example.com "http://$IP:80"
    # fig.yml
    rediscli:
    image: redis
    entrypoint: [ redis-cli, -h, redis ]
    links:
    - redis

    View Slide

  25. 7. Unregister Previous Backends
    For each container id CID in $RUNNING_CIDS, do:
    IP=$(docker inspect --format='{{ .NetworkSettings.IPAddress }}' )
    fig run --rm rediscli lrem frontend:www.example.com 0 "http://$IP:80"
    † New backend is up and serves requests. However,
    previous backends may still process requests. Wait.

    View Slide

  26. 8. Stop Previous Containers
    For each container id CID in $RUNNING_CIDS, do:
    docker stop

    View Slide

  27. 9. Tag A Release (And Profit!)

    View Slide

  28. Testing

    View Slide

  29. Like , but better!
    Apache Bench
    ® tarekziade/boom

    View Slide

  30. 1. Run boom
    boom https://www.example.org/ -n 2000 -c 50
    Server Software: nginx/1.2.1
    Running GET https://www.example.org/
    Running 2000 times per 50 workers.
    [================================================================>.] 99% Done
    -------- Results --------
    Successful calls 2000
    Total time 137.1827 s
    Average 6.7114 s
    Fastest 2.3701 s
    Slowest 9.4738 s
    Amplitude 7.1037 s
    -------- Status codes --------
    Code 200 2000 times.

    View Slide

  31. 2. Deploy
    fab deploy --hide=running,stdout,stderr
    ---> Deploying branch "awesome-feature"
    ---> Building artifact
    ---> Artifact id is: "build-8fe47fc"
    ---> Pushing artifact to the server
    ---> Building container
    ---> Finding running containers
    ---> Starting new container
    ---> Waiting while container is booting
    ---> Registering new backend to Hipache
    ---> Unregistering the previous backends from Hipache
    ---> Waiting before stopping the previous backends
    Done.
    q I use .
    Fabric

    View Slide

  32. 3. Monitor
    Elasticsearch, Logstash, Kibana
    +
    Logstash Forwarder (lumberjack)
    ® willdurand/docker‑elk
    ® willdurand/docker‑logstash‑forwarder

    View Slide

  33. View Slide

  34. Thank You.
    Questions?
    ¾
    ®
    ¬
    williamdurand.fr
    github.com/willdurand
    twitter.com/couac

    View Slide

  35. Bonus

    View Slide

  36. Fig & Environments
    Keep development, staging, and
    production as similar as possible
    X. Dev/prod parity — 12 Factors
    # fig.yml.dist
    web:
    # In PRODUCTION, the line below MUST be COMMENTED:
    build: .
    # In PRODUCTION, the line below must be UNCOMMENTED:
    # image: myapp
    # ...

    View Slide

  37. Data Only Containers
    Data, logs, etc. MUST live in data only containers:
    # fig.yml
    redis:
    image: redis
    volumes_from:
    - dataredis
    dataredis:
    image: busybox
    volumes:
    - /data
    Wanna backup? ė
    docker run --rm \
    --volumes-from dataredis \
    -v $(pwd):/backup \
    busybox \
    tar cvf /backup/dataredis.tgz /data

    View Slide