devops training - day 2/2
TRANSCRIPT
What is a container?
• Program executed in a limited kernel resources• Cgroups: CPU, Memory, Network, …• Namespace: Process, User, Filesystem, ...• Union file system: Filesystem
Virtual machine vs Container
Server
OS
Hypervisor
Guest OS
Libraries
App 1
Server
OS
Docker Engine
Guest OS Guest OS
Libraries Libraries
App 2 App 3
Libraries
App 1
Libraries Libraries
App 2 App 3
Containers for developers
• Micro service paradigm• Environment variables for application configuration
User
Contract
Support
Notification
Analytics
Invoice
Storage
Task
Containers for system engineers
• Blue/Green deployment• High level management• Security issues• Change all tools…
User
Load balancer
A version
B version
A version
B version
A version
B version
Web server Application Database
Docker softwares
DockerEngine
DockerMachine
DockerRegistry
DockerComposeKitematic
Docker Toolbox
Automate Docker provisioning
Desktop GUI for Docker
Multi-container orchestration tool
Run Docker container
Docker containers hosted registry
Helper to install Docker components on desktop
DockerCloud
Hosted service for building and
deploying containers
DockerSwarm
Host clustering and container
scheduling
Dockerfile
• Dockerfile is a document composed of various commands to assemble an image• Inherit from on a base image
DockerfileFROM ubuntu
MAINTAINER [email protected]
RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdgmain" > /etc/apt/sources.list.d/pgdg.listRUN apt-get update && apt-get install -y python-software-properties software-properties-common postgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3
USER postgres
RUN /etc/init.d/postgresqlstart &&\psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" &&\createdb -O docker docker
RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/9.3/main/pg_hba.confRUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf
EXPOSE 5432
VOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]
Base image
Maintainer information
Install requirements
Set user to use when running the image
Application configuration
Export port on network
Export volumes
Start application
Docker compose
• Compose is a tool for defining and running multi-container Docker applications• /!\ 2 versions of docker-compose format
docker-compose.yml (version 1)postgres :image: postgres
cron:build: .dockerfile: Dockerfile-cronlinks:- postgres
web:build: .
volumes:- .:/code
ports:- "8000:8000"
links:- postgres
PostgreSQL database
CRON container
Load volume fromcurrent directory
Expose ports
Link containers
docker-compose.yml (version 2)
version: '2’
services:web:build: .ports:- ”8000:8000"volumes:- .:/code- logvolume01:/var/logdepends_on:- postgresql
postgres:image: postgres
volumes:logvolume01: {}
Version
Application
Postgresql
Volumes
Running containers with Docker composer
1. Define application containerCreate Dockerfile
2. Define container relationsCreate docker-compose.yml
3. Start containersdocker-compose up
4. Execute commandsdocker-compose run <container> <cmd>
Install Docker Toolbox
• Docker Toolbox’ll install all tools• https://www.docker.com/products/docker-toolbox
Virtualbox
Virtual machine
Docker Engine
Docker Machine
Docker CLI client
Docker Composer
Container
Create your first container
• Start Docker serverdocker-machine start default
• Load Docker connection parameterseval $(docker-machine env default)
• Create DockerfileFROM php
WORKDIR /var/www
ADD index.php .
EXPOSE 8080
ENTRYPOINT ["php", "-S", "0.0.0.0:8080"]
Start your first container
• Create index.phpecho '<?php echo ”Good morning!\n”; ?>' > index.php
• Build containerdocker build -t app1 .
• Check imagesdocker images | head
• Run the containerdocker run -t app1 -p 8080:8080 app1
• Connect to the websitecurl -v $(docker-machine ip):8080
Update the container
• Update application contentecho '<?php echo "Welcome!\n”; ?>' > index.php
• Connect to the websitecurl -v $(docker-machine ip):8080
• Still Good morning… What’s wrong?• Restart your container
Share your container
• Create an account on https://hub.docker.com• Tag your container
docker tag app1 <username>/app1• Connect on Dockerhub
docker login• Push container to Docker Hub
docker push <username>/app1• Connect on DockerHub website
https://hub.docker.com/<username>/app1/
cAdvisor
• Created by Google to monitor their own containers (lmctfy)• Analyzes resource usage and performance characteristics of running
containers.
Start cAdvisor• Run cAdvisor
docker run \--name=cadvisor \--restart always \--detach=true \--volume=/:/rootfs:ro \--volume=/var/run:/var/run:rw \--volume=/sys:/sys:ro \--volume=/var/lib/docker/:/var/lib/docker:ro \--publish=8001:8080 \google/cadvisor:latest
• Connect to the web interface
http://192.168.99.100:8001
Continuous integration/deployment
• Continuous integration• Run tests for each commit• Detect bugs
• Continuous deployment• Deploy application if tests success
GIT repository
CI CD
ProductionStaging
Developer
Gitlab
• Open source GIT repository management solution• Community and Enterprise editions
• GitHub alternative• https://about.gitlab.com
Start GitLab• Run GitLab
docker run --detach \--hostname gitlab.example.com\--publish 8000:80 \--name gitlab \--restart always \--volume /srv/gitlab/config:/etc/gitlab \--volume /srv/gitlab/logs:/var/log/gitlab \--volume /srv/gitlab/data:/var/opt/gitlab \gitlab/gitlab-ce:latest
• Connect to the web interface (Default password: root/5iveL!fe)
http://$(docker-machine ip):8000
Clone the repository
git clone http://192.168.99.100:8000/root/app1.gitcd app1/echo 'Welcome' > README.mdgit add README.mdgit commit README.md -m 'Add README.md'git push
Jenkins
• The most popular tool to build and deploy projects• Unittest• Continuous Integration• Continuous Delivery
• Plugins for everything!• Distribute work across multiple machines• https://jenkins.io
Start Jenkins
• Run Jenkins
docker run --detach \--publish 10000:8080 \--name jenkins \--restart always \jenkins:latest
• Connect to the web interface
http://$(docker-machine ip):10000
Configure Jenkins
• Install “Git plugin”• Restart Jenkins• Create a new project called “App1 - master”• Add GIT credentials• Poll SCM
* * * * *
• Executephpunit -c app
Technical details
• 2 Docker containers:• Redis• Application (PHP application)
• Use PHP composer to install requirements• Use Docker Compose to start containers• Bonus:• 3 tiers architecture (Nginx/PHP/Redis)• SSL• Unit tests• …
Application files
<?php
require __DIR__ . '/vendor/autoload.php';Predis\Autoloader::register();
// Connect to redistry {
$redis = new Predis\Client('tcp://redis:6379');}catch (Exception $error) {
die($error->getMessage());}
// Get visitors$visitors = ($redis->exists('visitors')) ? $redis->get('visitors') : 0;
// Increment visitors$visitors++;$redis->set('visitors', $visitors);
// Display visitorsif ($visitors > 1) {
echo "<h1>There are $visitors visitors!</h1>\n";} else {
echo "<h1>There is $visitors visitor!</h1>\n";}
?>
{"require": {
"predis/predis": "^1.0.3"}
}
index.php composer.json
Docker files
FROM php:5-apache
# Install GITRUN apt-get update \
&& apt-get install -y git \&& apt-get clean \&& rm -rf /var/lib/apt/lists/*
# Install PHP composerRUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
WORKDIR /var/www/html
# Add applicationADD . /var/www/html/
# Install application requirements with PHP composerRUN composer install
version: '2'services:application:
build: .ports:
- "80:80"depends_on:- redis
redis:image: redis:latest
Dockerfile docker-compose.yml