Tuesday, 10 May 2016

Getting Started with Docker

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

  1. On mac you can search for the 'Docker QuickStart Terminal' and launch it.
  2. 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.100
      For help getting started, check out the docs at https://docs.docker.com

      kaushiki-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.
  3. Run the following command to see all the virtual docker machine installed. 
    • kaushiki-2:~ arun$ docker-machine ls
      NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER    ERRORS
      default   *        virtualbox   Running   tcp://192.168.99.100:2376           v1.11.0   
      kaushiki-2:~ arun$ 
      We can see the single 'default' machine is running on the host machine.

  4.  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 arun
      Running 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$ 
  5. Now run the docker ls command again to see the list of virtual box 
    • kaushiki-2:~ arun$ docker-machine ls
      NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER    ERRORS
      arun      -        virtualbox   Running   tcp://192.168.99.101:2376           v1.11.1   
      default   *        virtualbox   Running   tcp://192.168.99.100:2376           v1.11.0   
      kaushiki-2:~ arun$   
  6. Now run the command to see the process running on the docker machine
    • Tokaushiki-2:~ arun$ docker ps
      Cannot 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 ps
      CONTAINER 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-http
      Unable to find image 'rickfast/hello-oreilly-http:latest' locally
      latest: Pulling from rickfast/hello-oreilly-http

      8f4ec95ceaee: Pull complete 
      65b6c5c277d4: Pull complete 
      88605cedd195: Pull complete 
      1e371643d338: Pull complete 
      942927779857: Pull complete 
      a3ed95caeb02: Pull complete 
      Digest: sha256:4f76ac57d4ba44e2cadf042a8d252f92dde7fc63cbf2d69df6c35adbdb80d4e5
      Status: Downloaded newer image for rickfast/hello-oreilly-http:latest
      477d7329eb368b3d21d862fe6a0887634febf10657c8f10795feec923183f656
    • Now run the ps command again to see the process running on this machine
    • kaushiki-2:~ arun$ docker ps
      CONTAINER ID        IMAGE                         COMMAND             CREATED             STATUS              PORTS                    NAMES
      477d7329eb36        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 arun
      192.168.99.100
    • To stop the machine run the following command
    • kaushiki-2:~ arun$ docker-machine stop arun
      Stopping "arun"...
      Machine "arun" was stopped.
    • To start the machine run the following command
    • kaushiki-2:~ arun$ docker-machine start arun
      Starting "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 arun
        About to remove arun
        Are you sure? (y/n): y
        Successfully removed run

Common Use cases


  1. 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' locally
    latest: Pulling from library/ubuntu

    6d28225f8d96: Pull complete 
    166102ec41af: Pull complete 
    d09bfba2bd6a: Pull complete 
    c80dad39a6c0: Pull complete 
    a3ed95caeb02: Pull complete 
    Digest: sha256:5718d664299eb1db14d87db7bfa6945b28879a67b74f36da3e34f5914866b71c
    Status: 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/bash
    root@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:/# hostname
    47b15e7b86ba
  • Let us explore the filesystem of the container
  • root@47b15e7b86ba:/# ls
    bin  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 -A
      PID TTY          TIME CMD
        1 ?        00:00:00 bash
       12 ?        00:00:00 ps

  • We can exit the ubuntu container and return to the host machine by typing the following command
  • root@47b15e7b86ba:/# exit
    exit
    kaushiki-2:~ arun$ 
  •  Now when we run the docker process command we can see the empty process 
  • kaushiki-2:~ arun$ docker ps
    CONTAINER 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               NAMES
    47b15e7b86ba        ubuntu                        "/bin/bash"              7 minutes ago       Exited (0) 36 seconds ago                       determined_jennings
    ef1bfa37ff65        ubuntu                        "pwd"                    3 hours ago         Exited (0) 3 hours ago                          elated_roentgen
    8b6f19c3eb24        rickfast/hello-oreilly-http   "ruby hello.rb"          16 hours ago        Exited (0) 15 hours ago                         gigantic_torvalds
    3001a2810240        rickfast/hello-oreilly-http   "ruby hello.rb"          16 hours ago        Exited (0) 16 hours ago                         drunk_leavitt
    a19f218002ff        rickfast/hello-oreilly        "echo 'Hello O'Reilly"   16 hours ago        Exited (0) 16 hours ago                         jolly_brahmagupta
    0a66ff575cf7        arunstiwari/docker-whale      "/bin/sh -c '/usr/gam"   2 weeks ago         Exited (0) 2 weeks ago                          gigantic_burdock
    c366faff7e30        docker-whale                  "/bin/sh -c '/usr/gam"   2 weeks ago         Exited (0) 2 weeks ago                          suspicious_bassi
    928e37e9b6b9        docker/whalesay               "cowsay boo-boo"         2 weeks ago         Exited (0) 2 weeks ago                          sleepy_mcclintock
    faad375dc024        docker/whalesay               "cowsay boo"             2 weeks ago         Exited (0) 2 weeks ago                          gigantic_hugle
    dcc0240b705a        hello-world                   "/hello"                 2 weeks ago         Exited (0) 2 weeks ago                          thirsty_yalow
    kaushiki-2:~ arun$ 
                 Running Containers 
  • To run any container say for example ubuntu we use the following command
  • kaushiki-2:~ arun$ docker run ubuntu ls -l
    total 64
    drwxr-xr-x   2 root root 4096 May  3 15:53 bin
    drwxr-xr-x   2 root root 4096 Apr 12 20:14 boot
    drwxr-xr-x   5 root root  360 May 10 08:32 dev
    drwxr-xr-x  44 root root 4096 May 10 08:32 etc
    drwxr-xr-x   2 root root 4096 Apr 12 20:14 home
    drwxr-xr-x   8 root root 4096 Sep 13  2015 lib
    drwxr-xr-x   2 root root 4096 May  3 15:52 lib64
    drwxr-xr-x   2 root root 4096 May  3 15:52 media
    drwxr-xr-x   2 root root 4096 May  3 15:52 mnt
    drwxr-xr-x   2 root root 4096 May  3 15:52 opt
    dr-xr-xr-x 130 root root    0 May 10 08:32 proc
    drwx------   2 root root 4096 May  3 15:52 root
    drwxr-xr-x   4 root root 4096 May  3 15:52 run
    drwxr-xr-x   2 root root 4096 May  3 23:12 sbin
    drwxr-xr-x   2 root root 4096 May  3 15:52 srv
    dr-xr-xr-x  13 root root    0 May 10 08:32 sys
    drwxrwxrwt   2 root root 4096 May  3 15:53 tmp
    drwxr-xr-x  11 root root 4096 May  3 23:12 usr
    drwxr-xr-x  13 root root 4096 May  3 23:12 var
    kaushiki-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=4567
    This 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-http
    46faf816a4671c31fe55686026019d486eab2c6e523b9c378e68c8a3cbe9cb14
    This 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 ps
    CONTAINER ID        IMAGE                         COMMAND             CREATED             STATUS              PORTS               NAMES
    46faf816a467        rickfast/hello-oreilly-http   "ruby hello.rb"     5 minutes ago       Up 5 minutes        4567/tcp            admiring_bhabha
    The 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-http
    83416be712af9544c6782a7b6fedcc64b16a6594c39d666aa17b3bcf0c165d5ad

  • To see our named container run the following command
  • kaushiki-2:~ arun$ docker ps
    CONTAINER ID        IMAGE                         COMMAND             CREATED             STATUS              PORTS               NAMES
    a801e5669e8a        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_container
    dummy_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
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 deprecated docker link command.
The docker link command can work as shown below
kaushiki-2:~ arun$ docker run -d --link redis --name web rickfast/oreilly-simple-web-app
a6011659de90795ef933a1c67011cf28037833bac88df22c7c7879f164205221
 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

  1. https://www.docker.com/enterprise

No comments:

Post a Comment