Docker
DevOps Knowledge Sharing
sudo wget -qO- [Link] | sh
Docker Prerequisites
No Docker Experience required
Need to have
Linux Machine (Ubuntu Preferred)
Use your own or use cloud provider
Amazon EC2
Digital Ocean
Be familiar with Linux command line
Contents
What is Docker ?
Container Vs Virtual Machines
Docker Platform Overview and Terminology
Docker Engines
Images
Containers
Registry
Repositories
Docker Hub
Docker orchestration tools
Intro to Images
Getting Started with Containers
What is Docker?
Docker is a platform for developing, shipping and running application using
container virtualization technology.
The Docker Platform consists of multiple products/tools
Docker Engine
Docker Hub
Docker Machine
Docker Swarm
Docker Compose
Kitematic
Introducing Containers
Containers based virtualization uses the kernel on the hosts operating system
to run multiple guest instances
Each guest instance is called a container
Each Container has its own:
Root Filesystem
Processes
Memory
Devices
Network Ports
Containers Vs VMs
Containers are more lightweight
No need to install guest OS
Less CPU, RAM, storage space required
More containers per machine than VMs
Great portability
Docker and Linux the Linux kernel
Docker Engine is the program that enables containers to be built, shipped and
run.
Docker Engine uses Linux kernel namespaces and control group
Namespaces give is the isolated workspace
Install Docker
Follow the instructions at
[Link]
P7VXMCRKaumHr2Y/edit#
to install the latest Docker maintained Docker package on your preferred
operating system.
Run hello-world container to test your installation
$sudo docker run hello-world
Add your user account to the docker group
$sudo usermod -aG docker <your username>
Logout of your terminal and log back in for the changes to take effect
Verify that you can run the hello-world container without using sudo
$sudo run hello-world
Docker Client and Daemon
Client/Server architecture
Client takes user inputs and send them to the daemon
Daemon builds, run, and distributes containers
Client and daemon can run on the same host or on different
hosts
Cli client and GUI (Kitematic)
Docker Version Check
$docker version
Docker Containers and Images
Images
Read only template used to create containers
Built by you or other Docker users
Stored in the Docker Hub or your local Registry
Containers
Isolated application platform
Contains everything needed to run your application
Based on one or more images
Repository
Docker Hub
Docker Hub is the public registry that contains a large number of images available
for your use.
Benefits of the Docker
Separation of concerns
Developers focus on building their apps
System admins focus on deployment
Fast Development cycle
Application portability
Build in one environment. ship to another
Scalability
Easy spin up new containers if needed
Run more apps on one host machine
Images
Search for Images On Docker Hub
Lots of images available for use
Images resides in various Repositories
Create your docker hub account
official Repositories
Getting Started with Containers
Creating a Container
Use docker run command
Syntax
docker run [options] [images] [command] [args]
Image is specified with repository:tag
#Examples:
docker run ubuntu:14.04 echo Hello World
docker run ubuntu ps ax
Run a Simple Container
Contd ...
On Terminal
$docker run ubuntu:14.04 echo hello world
$docker run ubuntu:14.04 ps as
Use -i and -t flags with docker run
The -i flag tells docker to connect to STDIN on the container
The -t flag specifies to get a pseudo-terminal
Note: You need to run a terminal process as your command (e.g /bin/bash)
Example:
$docker run -i -t ubuntu:latest /bin/bash
Run a Container and get Terminal Access
Create a container using ubuntu 14.04 image and connect to STDIN and a
terminal
sudo docker run -it ubuntu:14.40 /bin/bash
In your container create a new user using your first and last name as the
username
#adduser username
#adduser username sudo
#exit
Notice how the container shut down
Once again run:
#sudo docker run -it ubuntu:14.40 /bin/bash
Try and find your user
Notice that it does not exist
Container Processes
A container only runs as long as the process from your specified docker run
command running
Your command's process is always PID 1 inside the container
Running in Detached Mode
Also known as running in the background or as a daemon
Use -d flag
To Observer output use: $docker logs [container id]
Try:
$docker run -d ubuntu:14.04 ping [Link] -c 10
Running Tomcat in docker container
Use -O flag to map container ports to host ports
Example
$docker run -d -P tomcat:7
$docker ps
References
[Link]
[Link]
[Link]
Docker Fundamentals
Agenda
1. Building Images
2. Dockerfile
3. Managing Images and Containers
4. Distributing Images on Docker Hub
5. Basic Container Networking
6. Docker in continuous integration
Building Images
Image layers
1. Images are comprised of multiple layers
2. A layer is also Just another image
3. Every image contains a base layer
4. Docker uses a copy on write system
5. layers are read only.
The Container Writable Layer
1. Docker creates a top writable layer for containers
2. Parent images are read only
3. All changes are made at the writeable layer
Docker Commit
docker commit commands saves changes in a container as a new image
Syntax:
docker commit [options] [container ID] [repository:tag]
Repository name should be based on username/application
can reference the container with container name instead of ID
Example:Save the container with ID as a new image in the repository
prabin/myapp. Tag the image as 1.0
$docker commit [container ID] prabin/myapp:1.0
Build New Image
Create a container from Ubuntu Image and run a bash terminal
$docker run -it ubuntu:14.04 /bin/bash
Inside the container, install curl
$apt-get install curl
Exit the container
Run docker ps -a and take note of your container ID
save the container as a new image. For the repository name use <your
name>/curl. Tag the image as 1.0
$docker commit <container ID> <yourname>/curl:1.0
Dockerfile
A dockerfile is a configuration file that contains instructions for building a Docker
image
Provides a more effective way to build images compared to using docker
commit
Easily fits into your continuous integration and deployment process
Dockerfile Instruction
Instruction specify what to do when building the image
FROM instruction specifies what the base image should be
RUN instruction specifies a command to execute
#Example
FROM ubuntu:14.04
RUN apt-get install vim
RUN apt-get install curl
RUN instruction
Each RUN instruction will execute the command on top writable layer and
perform a commit of the image
Can aggregate multiple RUN instruction by using &&
#Example
RUN apt-get update && apt-get install -y \
curl \
vim \
openjdk-7-jdk
Docker Build
Syntax
docker build [options] [path]
Common option to tag the build
docker build -t [repository:tag] [path]
docker build -t prabin/myapp:1.0 .
docker build -t prabin/myapp:1.0 myapp
Note: [path] >> build context
Build From DockerFile
In your home directory, create a folder called test
in the test folder, create a file called Dockerfile
in the file specify to use ubuntu 14.04 as the base image
FROM ubuntu:14.04
write an instruction to install curl and vim after an apt-get update
RUN apt-get update && apt-get install -y curl \
vim
Build an image from Dcokerfile. Give it the repository
<yourname>/testimage abd tag it as 1.0
CMD instruction
CMD defines a default command to execute when a container is created
CMD performs no action during the image build
Shell format and EXEC format
can only be specified once in a Dockerfile
#Example
Shell Format
CMD ping [Link] -c 30
Exec Format
Try CMD
Go to the test folder and open your Dockerfile from previous exercise
Add the following line to the end
CMD [ping, [Link], -c 30] (jason Array)
Build the image
docker build -t <yourname>/testimage:1.1 .
Execute a container from the image observer the output
docker run <yourname>/testimage:1.1 .
Execute a container from the image observer the output and specify the echo
command
ENTRYPOINT Instruction
Defines the command that will run when a container is executed
Run time arguments and CMD instruction are passed as parameters to the
ENTRYPOINT instruction
EXEC form preferred as shell form accept arguments at run time
Container essentially runs as an executable
#Example
ENTRYPOINT [ping]
Start,Stop and Deleting Containers
Find your containers first with docker ps and note the ID or name
docker start and docker stop
List all containers
docker ps -a
start container using the container ID
docker start <container ID>
Stop a container using the Container ID
docker stop <container ID>
Deleting the container
Getting terminal access
Use docker exec command to start another process within a container
Execute /bin/bash to get a bash shell
docker exec -i -t [container ID] /bin/bash
Exiting from the terminal will not terminate the container
Deleting Local Images
Use docker rmi command
docker images
docker rmi [image ID] or docker rmi [repo:tag]
if an image is tagged multiple times, removes each tag
docker rmi prabin/test:1.1
docker rmi prabin/test:1.2
Docker Hub Repositories
User can create their own repositories on Docker Hub
Public and Private
Push local images to a repository
Pushing Images to Docker Hub
Use docker push command
Syntax
docker push [repo:tag]
local repo must have same name and tag as the Docker Hub repo
Tagging Images
Used to rename a local image repository before pushing to Docker Hub
Syntax:
docker tag [image ID] [repo:tag] or docker tag [local repo:tag] [Docker Hub repo:tag]
Tag Image using the local repository
docker tag prabin/testimage:1.5 prabin/test:2.0
Push to Docker Hub
Login to your Docker Hub account
Create a new public repository test
tag your local image to give it the same repo name as the repository you
created on Docker Hub
docker tag <yourname>/testimage:1.1 <yourname>/testexample:1.1
push the new image to Docker Hub
docker push <yourname>/testexmple:1.1
Go to your Docker Hub repository and check for the tag
Volumes
A volume is a designated directory in a container, which is designed to persist
data, independent of the containers lifecycle
Volume changes are excluded when updating an image
Persist when a container is deleted
Can be mapped to a host folder
Can shared between containers
Mount a Volume
Volumes are mounted when creating or executing a container
Can be mapped to a host directory
Volume paths specified must be absolute
Execute a container and mount the volume /myvolume into its filesystem
docker run -d -P -v /myvolume myapp:1.2
Execute a new container and map the /data/src folder from the host into the
/test/src folder in the container
docker run -i -t -v /data/src/:test/src myapp:1.2
Volumes in Dockerfile
VOLUME Instruction creates a mount point
Can specify arguments JSON array or string
cannot map volumes to host directories
Volumes are initialized when the container is executed
String Example
VOLUME /myvol
String example with multiple volumes
VOLUME /www/[Link] /www/[Link]
Uses of volumes
De-couple the data that is stored from the container which created the data
Good for sharing data between containers
Can setup a data containers which has a volume you mount in other containers
Mounting folders from the host is good for testing purposes but generally not
recommended for production use
Create and test a volume
Execute a container and initialise a volume at /www/website Run a bash
terminal as your container process
docker run -i -t -v /www/website ubuntu:14.04 bash
inside the container, verify that you can get to /www/website
Create a file inside the /www/website folder
Exit the container
Commit the updated container as a new image called test and tag it as 1.0
docker commit <container ID> test:1.0
Execute a new container with your test image abd go into itss bash shell
Mapping ports
Containers have their own network and IP address
Map exposed container ports to ports on the host machine
Ports can be manually mapped or auto mapped
Uses the -p and -P parameters in docker run
#Example
Maps port 80 on the container to 8080 on the host
docker run -d -p 8080:80 nginx:1.2
Automapping ports
Uses the -P option in docker run
Automatically maps exposed ports in the container to a port in the host
Host port numbers used to go from 49153 to 65535
only works for ports defined in the EXPOSE instruction
Auto map ports exposed by the nginx container to a port value on the host
docker run -d -P nginx:1.7
EXPOSE instruction
Configures which ports a container will listen on at runtime
Ports still need to be mapped when container is executed
#Example (Dockerfile)
FROM ubuntu:14.04
RUN apt-get update
RUN apt-get install -y nginx
EXPOSE 80 443
CMD [nginx, -g, daemon off;]
Linking Containers
Linking is a communication method between containers which allows them to
securely transfer data from one to another
Source and recipient containers
Recipient containers have access to data on source containers
Links are established based on containers names
Creating a Link
Create the source containers
Create the recipient container and use the --link option
Best practice - give your containers meaningful names
Create the source container using the postgres
docker run -d --name database mysql
Create the recipient container and link it
docker run -d -P --name website --link database:db nginx (db > alias>
Link two containers
Run a container in detached mode using the mysql image name the container
dbms
docker run -d --name dbms postgres
Run another container using the Ubuntu image and link it with the dbms
container. Use the alias db. run the bash terminal as the main process
docker run -it --name website --link dbms:db ubuntu:14.04 bash
in the website container terminal, open the /etc/hosts file
What can you observe
Docker in Continuous Integration
Self Study