Docker Tool
Docker
Docker as defined in the docker website allows us to package an application with all of its dependencies into a standardized unit for software development
Docker is a tool which enables developers and system admins to easily deploy their applications in a sandbox container that can run on host operating system which in case of docker is always Linux. The docker allows developers to package an application with all its runtime dependencies into a standardized unit for software development. Container is a very lightweight process hence it does not have high overhead unlike a virtual machines where hypervisor consumes significant resources.
Difference between Container and Virtual Machine
Applications running in the virtual machines require full instance of the operating system along with all its supporting libraries.
Applications running in the Container shares the operating system with host. Processes running in the container are like the native processes running on the host. Applications can reuse and share the data across the containers. The overhead associated with hypervisor in case of virtual machine is not there while running container.
Docker Use Case
- CI/CD
- DevOps
- Big Data
- Infrastructure Optimization
Docker Architecture
Docker consists of four important components:
- Docker Container : Container is the instance of the Docker images.
- Docker Daemon : It is responsible for creating, running and monitoring containers. It is also responsible for creating and storing docker images.
- Docker Client : It communicates with the daemon through either HTTP or unix sockets(in case of daemon running on the same host as client)
- Docker Repository: A repository where various docker images public and private can be stored. Docker Hub is the official docker repository for both public and trusted docker images. We can host a docker repository in our own data centre.
Read the official documentation to gain more insight of docker architecture.
Docker Setup
Go to the docker site and download the docker toolbox and follow the installation steps as defined
Docker Basic Commands
- On mac you can search for the 'Docker QuickStart Terminal' and launch it.
- Once terminal is launched you can see the following as an output
- ## .## ## ## ==## ## ## ## ## ===/"""""""""""""""""\___/ ===~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~\______ o __/\ \ __/\____\_______/docker is configured to use the default machine with IP 192.168.99.100For help getting started, check out the docs at https://docs.docker.comkaushiki-2:~ arun$
- The docker machine is running at the ip address 192.168.99.100
- On Mac the docker machine is installed within the virtual box.
- Run the following command to see all the virtual docker machine installed.
- kaushiki-2:~ arun$ docker-machine lsNAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORSdefault * virtualbox Running tcp://192.168.99.100:2376 v1.11.0kaushiki-2:~ arun$We can see the single 'default' machine is running on the host machine.
- We can create a new virtual box using the following command. Here we are creating a new virtual box named as 'arun'
- kaushiki-2:~ arun$ docker-machine create --driver virtualbox arunRunning pre-create checks...Creating machine...(arun) Copying /Users/arun/.docker/machine/cache/boot2docker.iso to /Users/arun/.docker/machine/machines/arun/boot2docker.iso...(arun) Creating VirtualBox VM...(arun) Creating SSH key...(arun) Starting the VM...(arun) Check network to re-create if needed...(arun) Waiting for an IP...Waiting for machine to be running, this may take a few minutes...Detecting operating system of created instance...Waiting for SSH to be available...Detecting the provisioner...Provisioning with boot2docker...Copying certs to the local machine directory...Copying certs to the remote machine...Setting Docker configuration on the remote daemon...Checking connection to Docker...Docker is up and running!To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env arun
kaushiki-2:~ arun$ - Now run the docker ls command again to see the list of virtual box
- kaushiki-2:~ arun$ docker-machine lsNAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORSarun - virtualbox Running tcp://192.168.99.101:2376 v1.11.1default * virtualbox Running tcp://192.168.99.100:2376 v1.11.0kaushiki-2:~ arun$
- Now run the command to see the process running on the docker machine
- Tokaushiki-2:~ arun$ docker psCannot connect to the Docker daemon. Is the docker daemon running on this host?
- The docker client is not able to connect to daemon, so first we need to connect to daemon using the following command
- kaushiki-2:~ arun$ eval $(docker-machine env arun)
- After that run the following command to see the process running on this host. Since no process is running on this host hence the empty result is returned.
- kaushiki-2:~ arun$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- Now let us run the following command to start simple http process on this machine. This will download the hello-oreilly-http image from docker hub repository.
- kaushiki-2:~ arun$ docker run -p 4567:4567 -d rickfast/hello-oreilly-httpUnable to find image 'rickfast/hello-oreilly-http:latest' locallylatest: Pulling from rickfast/hello-oreilly-http8f4ec95ceaee: Pull complete65b6c5c277d4: Pull complete88605cedd195: Pull complete1e371643d338: Pull complete942927779857: Pull completea3ed95caeb02: Pull completeDigest: sha256:4f76ac57d4ba44e2cadf042a8d252f92dde7fc63cbf2d69df6c35adbdb80d4e5Status: Downloaded newer image for rickfast/hello-oreilly-http:latest477d7329eb368b3d21d862fe6a0887634febf10657c8f10795feec923183f656
- Now run the ps command again to see the process running on this machine
- kaushiki-2:~ arun$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES477d7329eb36 rickfast/hello-oreilly-http "ruby hello.rb" 2 minutes ago Up 2 minutes 0.0.0.0:4567->4567/tcp furious_bell
- To find the ip address of the machine run the following command
- kaushiki-2:~ arun$ docker-machine ip arun192.168.99.100
- To stop the machine run the following command
- kaushiki-2:~ arun$ docker-machine stop arunStopping "arun"...Machine "arun" was stopped.
- To start the machine run the following command
- kaushiki-2:~ arun$ docker-machine start arunStarting "arun"...(arun) Check network to re-create if needed...(arun) Waiting for an IP...Machine "arun" was started.Waiting for SSH to be available...Detecting the provisioner...Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.
- To remove the docker machine run the following command
- kaushiki-2:~ arun$ docker-machine rm arunAbout to remove arunAre you sure? (y/n): ySuccessfully removed run
Common Use cases
- Installing and Running the ubuntu container
- Install the ubuntu container by using the ubuntu image on the docker hub and passing the command 'pwd' for ubuntu container
- kaushiki-2:~ arun$ docker run ubuntu pwd
- Output is as shown below:
Unable to find image 'ubuntu:latest' locallylatest: Pulling from library/ubuntu6d28225f8d96: Pull complete166102ec41af: Pull completed09bfba2bd6a: Pull completec80dad39a6c0: Pull completea3ed95caeb02: Pull completeDigest: sha256:5718d664299eb1db14d87db7bfa6945b28879a67b74f36da3e34f5914866b71cStatus: Downloaded newer image for ubuntu:latest/- The last pwd command run on the ubuntu displays the present working directory as root i.e. '/' . This command was executed on ubuntu container and not on the host machine.
- Now when we run the command on the host machine we get the following output
kaushiki-2:~ arun$ pwd/Users/arun
Container lifecycle: Container has its own isolated view of the operating environment. It has its own userid and process trees which is different from the underlying operating system or host machine.
- Let us navigate to container from the host machine to understand more of the container process trees and file system.
- We can interact with container from host machine in interactive way using the following command
kaushiki-2:~ arun$ docker run -i -t ubuntu /bin/bashroot@47b15e7b86ba:/#- Here we can see we got logged into the ubuntu container as root user
- Let us see the hostname of the ubuntu container by typing the following command
root@47b15e7b86ba:/# hostname47b15e7b86ba- Let us explore the filesystem of the container
root@47b15e7b86ba:/# lsbin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
- Let us explore the processes running in the container
root@47b15e7b86ba:/# ps -APID TTY TIME CMD1 ? 00:00:00 bash12 ? 00:00:00 ps
- We can exit the ubuntu container and return to the host machine by typing the following command
root@47b15e7b86ba:/# exitexitkaushiki-2:~ arun$- Now when we run the docker process command we can see the empty process
kaushiki-2:~ arun$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES- We can view all the processes on the host machine by typing the following command. This command also prints the list of all processes exited.
- kaushiki-2:~ arun$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES47b15e7b86ba ubuntu "/bin/bash" 7 minutes ago Exited (0) 36 seconds ago determined_jenningsef1bfa37ff65 ubuntu "pwd" 3 hours ago Exited (0) 3 hours ago elated_roentgen8b6f19c3eb24 rickfast/hello-oreilly-http "ruby hello.rb" 16 hours ago Exited (0) 15 hours ago gigantic_torvalds3001a2810240 rickfast/hello-oreilly-http "ruby hello.rb" 16 hours ago Exited (0) 16 hours ago drunk_leavitta19f218002ff rickfast/hello-oreilly "echo 'Hello O'Reilly" 16 hours ago Exited (0) 16 hours ago jolly_brahmagupta0a66ff575cf7 arunstiwari/docker-whale "/bin/sh -c '/usr/gam" 2 weeks ago Exited (0) 2 weeks ago gigantic_burdockc366faff7e30 docker-whale "/bin/sh -c '/usr/gam" 2 weeks ago Exited (0) 2 weeks ago suspicious_bassi928e37e9b6b9 docker/whalesay "cowsay boo-boo" 2 weeks ago Exited (0) 2 weeks ago sleepy_mcclintockfaad375dc024 docker/whalesay "cowsay boo" 2 weeks ago Exited (0) 2 weeks ago gigantic_hugledcc0240b705a hello-world "/hello" 2 weeks ago Exited (0) 2 weeks ago thirsty_yalowkaushiki-2:~ arun$
Running Containers
- To run any container say for example ubuntu we use the following command
kaushiki-2:~ arun$ docker run ubuntu ls -ltotal 64drwxr-xr-x 2 root root 4096 May 3 15:53 bindrwxr-xr-x 2 root root 4096 Apr 12 20:14 bootdrwxr-xr-x 5 root root 360 May 10 08:32 devdrwxr-xr-x 44 root root 4096 May 10 08:32 etcdrwxr-xr-x 2 root root 4096 Apr 12 20:14 homedrwxr-xr-x 8 root root 4096 Sep 13 2015 libdrwxr-xr-x 2 root root 4096 May 3 15:52 lib64drwxr-xr-x 2 root root 4096 May 3 15:52 mediadrwxr-xr-x 2 root root 4096 May 3 15:52 mntdrwxr-xr-x 2 root root 4096 May 3 15:52 optdr-xr-xr-x 130 root root 0 May 10 08:32 procdrwx------ 2 root root 4096 May 3 15:52 rootdrwxr-xr-x 4 root root 4096 May 3 15:52 rundrwxr-xr-x 2 root root 4096 May 3 23:12 sbindrwxr-xr-x 2 root root 4096 May 3 15:52 srvdr-xr-xr-x 13 root root 0 May 10 08:32 sysdrwxrwxrwt 2 root root 4096 May 3 15:53 tmpdrwxr-xr-x 11 root root 4096 May 3 23:12 usrdrwxr-xr-x 13 root root 4096 May 3 23:12 varkaushiki-2:~
Running the Web Container
- To demonstrate the running of web container, use the hello-oreilly-http docker image which contains simple webapp
- kaushiki-2:~ arun$ docker run rickfast/hello-oreilly-http
[2016-05-10 08:40:35] INFO WEBrick 1.3.1[2016-05-10 08:40:35] INFO ruby 2.2.4 (2015-12-16) [x86_64-linux-musl]== Sinatra (v1.4.7) has taken the stage on 4567 for development with backup from WEBrick[2016-05-10 08:40:35] INFO WEBrick::HTTPServer#start: pid=1 port=4567This command runs the container in the foreground. In production we would like to run this container as daemon process in the background. To run this container in the background process kaushiki-2:~ arun$ docker run -d rickfast/hello-oreilly-http46faf816a4671c31fe55686026019d486eab2c6e523b9c378e68c8a3cbe9cb14This starts the container in the background and returns the value of the container id 46faf816a4671c31fe55686026019d486eab2c6e523b9c378e68c8a3cbe9cb14- Use the docker ps command to see the current process running on the host machine
kaushiki-2:~ arun$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES46faf816a467 rickfast/hello-oreilly-http "ruby hello.rb" 5 minutes ago Up 5 minutes 4567/tcp admiring_bhabhaThe name of the container is 'admiring_bhabha' which is dynamically chosen by the docker.
Create a named container
A named container is created when we have multiple container running for the same docker image.
- The named container is created as shown below
- Container for image hello-oreilly-http is created with name dummy_hello_container as shown
kaushiki-2:~ arun$ docker run -d --name dummy_hello_container rickfast/hello-oreilly-http83416be712af9544c6782a7b6fedcc64b16a6594c39d666aa17b3bcf0c165d5ad- To see our named container run the following command
kaushiki-2:~ arun$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESa801e5669e8a rickfast/hello-oreilly-http "ruby hello.rb" 21 seconds ago Up 20 seconds 4567/tcp dummy_hello_container
- To stop our named container use the following command
kaushiki-2:~ arun$ docker stop dummy_hello_containerdummy_hello_container
Running Containerised Web Applications
Scenario: A web application is using redis as a datastore.
Create one web container with web application installed on server and another container running redis. Link the two container so that web application can use the redis data store.
Create a redis container using the redis image from the docker hub and name it as 'redis'. See snippet below to create a redis container.
kaushiki-2:~ arun$ docker run -d -P --name redis redis0cfc95e2cc181f2081866950b732332be7cfbb6ed390c006aa6132e316855904
Inspect the redis properties of redis container. This is done using the following command
kaushiki-2:~ arun$ docker inspect redis
The output of the above command looks as below. Important thing to note is the IPAddress property.
"SandboxKey": "/var/run/docker/netns/face8cef1419",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "ad4e24d27ca1597440c3ae3a21b91de7deb5daa53792f7896dd95f7f7e93eb88",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
Now start a simple web app container and link the web application to the redis database
kaushiki-2:~ arun$ docker run -d -e "REDIS_PORT_6379_TCP_ADDR=172.17.0.2" --name web -p 4567:4567 rickfast/oreilly-simple-web-app
9959c58c8ad07c775639c23b46301e69d3a69bee300d500449bddc0938812615
9959c58c8ad07c775639c23b46301e69d3a69bee300d500449bddc0938812615
kaushiki-2:~ arun$
In this we have used the REDIS Configuration that was fetched by inspecting the redis. Use the property "REDIS_PORT_6379_TCP_ADDR=172.17.0.2" to link to the our web application.
This is the preferred way of linking the two docker container than using the deprecateddocker linkcommand.
The docker link command can work as shown below
kaushiki-2:~ arun$ docker run -d --link redis --name web rickfast/oreilly-simple-web-appa6011659de90795ef933a1c67011cf28037833bac88df22c7c7879f164205221
Now let us go to the browser and access the application.
Go to the other url and load the data in the redis. The parameter passed after the 'load' is the data that gets loaded in redis. Here we are passing 'hello' as parameter.
Now go back to the application url to view the data inserted in the redis.
References
- https://www.docker.com/enterprise