Learning Docker
I finally decided to learn docker, being a fun of linux academy tutorials it was a no-brainer to go through their docker training. Unfortunately they don't have any notes to accompany the video training, so i decided to write my own and publish it hopefully it will help others going through the docker training.
Installing Docker on Ubuntu 14.04
apt-get update apt-get install apt-transport-https ca-certificates sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D nano /etc/apt/sources.list.d/docker.list apt-get update apt-get install linux-image-extra-$(uname -r) apt-get install apparmor apt-get install docker-engine service docker start
The option version will display the docker version docker versionTo search for available containers
docker search centos docker search nginxTo get an image
docker pull nginxTo view available docker containers on your system
docker images
Going inside a container
docker run -i -t centos /bin/bash docker run -i -t centos:latest /bin/bash
Commit a customized Container once you have modified it
docker commit -m="Added json module for ruby" -a="Stelios" cae13561f52d liuxadademy/sinimage:v1.1 docker run -i -t liuxadademy/sinimage:v1.1 /bin/bash
Packaging a Customized Container
mkdir linuxacademy linuxacademy/
nano Dockerfile ---------------------------------------------------- #Custom dockerfile build FROM ubuntu:latest MAINTAINER Linux Academy <stelios@milidonis.com> RUN apt-get update RUN apt-get install -y ruby ruby-dev --------------------------------------------------
docker build -t="ubuntu:latest" . docker images docker run -i -t ubuntu:latest /bin/bash history
Running container commands within ocker
docker ps --- shows running containers
docker run ubuntu:latest /bin/echo 'helo from docker' helo from docker
docker run -d ubuntu:latest /bin/bash "while true; do echo fddman; sleep 1; done"
docker logs amazing_mcnulty
docker stop amazing_mcnulty
Lecture: Exposing Our Container With Port Redirects
run the container and start services forwarding port 8080 on server to 80 in the containerdocker run -d -p 8080:80 tutum/apache-php
Lecture: Attach to a Running Container
grab snapshot of a container instance and commit it so the changes made to it are saveddocker commit e1238b6a84f1 centos6:withupdateswith the d option you demonize the container instance and keep it running
docker run -itd centos6:withupdates /bin/bash
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 03b807ebedd0 centos6:withupdates "/bin/bash" 26 seconds ago Up 26 seconds grave_turingdoing a docker ps will show that the container is running bin/bash,
to identify the ip you can simply run
docker inspect grave_turing
..... a873122ceca1706721c", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02" }
The docker attach
command allows you to attach to a running container using the container’s ID or name, either to view its ongoing output or to control it interactively. You can attach to the same contained process multiple times simultaneously, screen sharing style, or quickly view the progress of your detached process.So since we have passed "d" option previously we can now attach to that container since its running.
docker attach sleepy_bassi
Lecture: Removing Images
docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos6 withupdates 8698ee40c98c 50 minutes ago 371.6 MB newcentos ithapache 05d85d398323 5 hours ago 346.3 MB ubuntu latest 44776f55294a 4 days ago 120.1 MB centos 6 fc73b108c5ae 3 weeks ago 228.9 MB
we wanto to remove the centos:6 image, however we cant because the other containers are dependent on that image. This is how docker works , once you modify a container and commit it , it depends on the parent container
docker rmi fc73b108c5ae Error response from daemon: conflict: unable to delete fc73b108c5ae (cannot be forced) - image has dependent child images
we have to remove the dependencies firtst. A sucessfull remove looks like this:
docker rmi 05d85d398323 Untagged: newcentos:ithapache Deleted: sha256:05d85d398323f2e04511f4c19dc92f4326a647b9c32504976c15095bb8b0c52b Deleted: sha256:801f5a5f83915ca1bbe33c9b6e6c4a621da251eea3102d0d6383fdaa8cfb60ff
Lecture: Directory Structure
Now that we have built images, containers, Dockerfile deployments and demonstrated removing them, we will step back and visit the Docker setup and directory structure. We will show how to use Linux to view the JSON configuration files and what they mean as well as how to delete a large number of containers safely so you can remove the underlying images (preventing us from accidentally orphaning our containers).location of the decker files and containers is in /var/lib/docker/
ls /var/lib/docker
4 drwx------. 10 root root 4096 Apr 29 16:00 containers
0 drwx------. 5 root root 50 Apr 29 10:37 devicemapper
0 drwx------. 3 root root 25 Apr 29 10:32 image
0 drwxr-x---. 3 root root 18 Apr 29 10:32 network
0 drwx------. 2 root root 6 Apr 29 10:42 tmp
0 drwx------. 2 root root 6 Apr 29 10:32 trust
0 drwx------. 2 root root 24 Apr 29 10:32 volumes
In the file /var/lib/docker/image/devicemapper/repositories.json you will find the container names on the system , its a reference file that can be edited. If you for example see "none " after the docker images command you may edit this file to fix that.
{ "Repositories": { "centos": { "centos:6": "sha256:fc73b108c5ae69424c1eec34499a74e8a0f17716a706d0813bccfeba5d9a8fbb" }, "centos6": { "centos6:withupdates": "sha256:8698ee40c98cc55faedf16d8d3584a960d5370aa411c8472208ba0011f8b28df" }, "ubuntu": { "ubuntu:latest": "sha256:44776f55294a30e89d6a348d3b3ba50576f5fe29d4b8d28d74699e87dfecc7c5" } } }
inside the container directory we find the containers and their directories.Navigating inside the directory of one container we see the following
03b807ebedd0ff2c4d8ac0f4b3833d76a856790ed77a3a0d94d1526508d4323d]# ls -la total 36 drwx------ 3 root root 4096 Apr 29 15:48 . drwx------. 10 root root 4096 Apr 29 16:00 .. -rw-r----- 1 root root 1242 Apr 29 15:58 03b807ebedd0ff2c4d8ac0f4b3833d76a856790ed77a3a0d94d1526508d4323d-json.log -rw-r--r-- 1 root root 2363 Apr 29 15:58 config.v2.json -rw-r--r-- 1 root root 1053 Apr 29 15:58 hostconfig.json -rw-r--r-- 1 root root 13 Apr 29 15:48 hostname -rw-r--r-- 1 root root 174 Apr 29 15:48 hosts -rw-r--r-- 1 root root 75 Apr 29 15:48 resolv.conf -rw------- 1 root root 71 Apr 29 15:48 resolv.conf.hash drwx------ 2 root root 6 Apr 29 15:48 shm
The .log file contains the information we see when we run "docker logs" on a runing container
the config file list the initial configuration for when the container was build
Lecture: Services That Run on Startup
Up to now, we have made changes to our containers and added services to them. However, a container is not a full OS and as such is not bound by services or init levels in order to start services on container start. We will talk about a couple of methods that can be used to start normal services in our container when started.Using bashrc
To make an application start automatically in a container we can edit the .bashrc file inside root hoem directory and make its as follows
# .bashrc # User specific aliases and functions alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi #start the apache web service /sbin/service httpd start
this will start the apache web server.
Then we must commit the image to save changes
docker commit 01b4b6ea00a6 cento6:apacherunning
then run the container with the daemon option
docker run -itd cento6:apacherunning /bin/bash
2)Create a script to run from bashrc
We create a bash script in /usr/bin#!/bin/bashwe then add the location of that script in .bashrcrm -rf /run/httpd/* #remove pid
exec /usr/sbin/apachectl -D FOREGROUND
# .bashrc # User specific aliases and functions alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi #start the apache web service /usr/bin/runhttp.sh #/sbin/service httpd start
again we commit the changes
docker commit 3780e4e4078e centos6:script
and run
docker run -itd centos6:script /bin/bash
Lecture: Dockerfile: Tying It Together
We have now spent a good amount of time building, one function at a time, our images and containers. We have been introduced to the Dockerfile to build a new image, now we are going to look at it in depth. We will use what we have done one step at a time previously and put it all in one place. We will also talk about how Dockerfile works related to how we have proceeded manually up to now.We first create a file, lets call it dockerfile and inside we add the following
FROM centos:centos6 #start with this base image if it doesnt exist it wil$ MAINTAINER Stelios <stelios@milidonis.com> #get updates and install apache, clean up and append to the index.html RUN yum -y update; yum clean all RUN yum -y install httpd RUN echo "This is an pache test site" >> /var/www/html/index.html #allow listening to port 80 EXPOSE 80 #append to bashrc the command to start apache RUN echo "/sbin/service httpd start" >> /root/.bashrc
Then we run the following command within the directory where the file exists
docker build -t stelios:centos6 .
What will happen is that the centos container will be downloaded, then within that container the update will run, apache will be installed , the bashrc file will be edited and then the final container will be commited. If we run docker images we will now see the container available
Then we run the container
run -itd stelios:centos6 /bin/bash
and we can see the container run with docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 72d81f9c4463 stelios:centos6 "/bin/bash" 4 seconds ago Up 3 seconds 80/tcp determined_torvalds
Lecture: Pushing Images to Docker Hub
We have a number of images on our local system. However, there is a particular naming convention that needs to be used when compiling an image to be uploaded. We will talk about that format and then demonstrate how to push our images to our repositories online.In the previous guide i build an image, it is importand that the maintainer must much your docker username and email address in order to successfully publish to docker hub
MAINTAINER stelios <stelios@milidonis.com>
when we build the image we must use our username followed by / and then give it a release name, in the eample below i am calling it beta1.
docker build -t stelios/centos6:beta1 .
First login to docker using the command bellow nd you will be prompted for your username and password
docker login
After your authenticated you can push to your repo using the following
docker push stelios/centos6:beta1
In your docker hub account you will after the upload is complete be ble to view you uploaded container. You can make it private so its not viewed by others. Remember your container will show up in people searhes so do remove it after this step.
[caption id="attachment_52" align="alignnone" width="687"] docker hub[/caption]
Lecture: Adding External Content
When building our images in the past, we have only pulled in content and applications that was available online through normal Linux repositories. Now, we are going to build a new container that inherits from our application base and include external content that can be distributed with the new images.First we edit the /root/build/dockerfile
FROM centos:centos6 #start with this base image if it doesnt exist it will download it MAINTAINER stelios <stelios@milidonis.com> EXPOSE 80 ADD testfile.html /var/www/html/testfile.html
We create a simple html file in /root/build/testfile.html we can put anything in it:
<html> <body> <h1>THIS IS A TEST </h1> </body> </html>
Then we create the container and call it test:html
docker build -t test:html .
We can then see in out images the container instance has been created, and when we start the conatiner we will have the file in the directory specidied
docker run -it test:html /bin/bash [root@9fb8e08ef099 /]# cat /var/www/html/testfile.html
Lecture: Image Volume Management
Up until now, everything we worked with in our container was just that - IN our container. In this video, we will start showing you how to expose external resources to your running containers, why you might do so and demonstrate the live benefits of the process.Using the "-v " option we can mount in a container a volume
docker run -it -v /myapp test:html /bin/bash
this wil appear in the container as:
10G 272M 9.8G 3% / tmpfs 737M 0 737M 0% /dev tmpfs 737M 0 737M 0% /sys/fs/cgroup /dev/mapper/centos-root 29G 2.6G 26G 10% /myapp /dev/mapper/centos-root 29G 2.6G 26G 10% /etc/resolv.conf /dev/mapper/centos-root 29G 2.6G 26G 10% /etc/hostname /dev/mapper/centos-root 29G 2.6G 26G 10% /etc/hosts shm 64M 0 64M 0% /dev/shm tmpfs 737M 0 737M 0% /proc/kcore tmpfs 737M 0 737M 0% /proc/timer_stats tmpfs 737M 0 737M 0% /proc/sched_debug
The following will map a directory from the os to the container.We create a directory /root/myvol that will then appear as /var/volume in the container as well as its contents.Notice what happens when the var/volume folder is checked after runing the container.
run -it -v /root/myvol/:/var/volume test:html /bin/bash
[root@localhost ~]# cd myvol/ [root@localhost myvol]# touch test [root@localhost myvol]# docker run -it -v /root/myvol/:/var/volume test:html /bin/bash [root@d6cb9c65e9f9 /]# cd /var/volume/ [root@d6cb9c65e9f9 volume]# ls test
This is an easy way to give access to a local folder to your container , and that folder can be shared among containers.
Another useful example if we add an html file in the OS /root/myvol/test.html..This wll mount the local operating systems /root/myvol directory containing the html file to container /var/www/html .
run -itd -v /root/myvol/:/var/www/html test:html /bin/bash
Any changes done inside the /root/myvol/ will be imediately reflected in the container
Lecture: Advanced Container Network Management
Advanced command line options for managing our containers network configuration. Up until now, we have accepted name, IP and configuration defaults for each container that we have launched - now we learn how to take control of what we run on our network!
Docker creates an interface that manges the ip's for the containers
docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP link/ether 02:42:59:f1:cb:3a brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:59ff:fef1:cb3a/64 scope link
you cannot set a static ip when you launch a container
We are going to change the ip's network range for the docker containers
First we need to stop the docker service
systemctl stop docker
Then we create and link an interface type bridge . So we create a bridge and call it br10
ip link add br10 type bridge
We then give it an ip range
ip addr add 10.10.100.1/24 dev br10
now we have
br10: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN link/ether 2e:01:71:3a:3d:a6 brd ff:ff:ff:ff:ff:ff inet 10.10.100.1/24 scope global br10 valid_lft forever preferred_lft forever
we need to bring it UP
ip link set br10 up
br10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN link/ether 2e:01:71:3a:3d:a6 brd ff:ff:ff:ff:ff:ff inet 10.10.100.1/24 scope global br10 valid_lft forever preferred_lft forever inet6 fe80::2c01:71ff:fe3a:3da6/64 scope link valid_lft forever preferred_lft forever
Now we need to tell docker to use that bridge adapter instead of docker0. This is done on a systemd server
/usr/bin/docker daemon -b br10
If we opena container now we will see that the container will get an ip in the 10.10.100.1/24 range
To make the changes permanent , we edit the /etc/network/interfaces file and we add
auto lo iface lo inet loopback auto br10 iface br10 inet static address 10.100.10.1 netmask 255.255.255.0 bridge_ports dummy0 bridge_stp off bridge_fd 0
Lecture: Interactive Shell Control
We will take a deeper dive into our Interactive Shell Prompt when starting containers. The viewer will learn how to detach and attach to running containers as well as restart a container in the same state it was stopped in.
Naming your container
docker run -it --name MYCONTAINER test:html /bin/bash
you will see the container now is called "MYCONTAINER" instead of a generated name
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 38726da2131e test:html "/bin/bash" 7 seconds ago Up 5 seconds 80/tcp MYCONTAINER
Running a command from outside the container to the container
First we deamonize the containerdocker run -itd --name MYCONTAINER1 test:html /bin/bash
Then we execute a command from the os to the container
docker exec -it MYCONTAINER1 /usr/bin/top
we will get top for the container, so we connect to teh container and running a process to the tti of the host.
Lecture: Previous Container Management
We explore the way to interact directly with previously run containers. We will show how to get their names and IDs and then how to restart them even after they have been stopped.To get a list of all the docker containers that have run in the past as well as the currnt ones
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 11346db3740c test:html "/bin/bash" 7 minutes ago Up 7 minutes 80/tcp MYCONTAINER1 38726da2131e test:html "/bin/bash" 12 minutes ago Exited (0) 7 minutes ago MYCONTAINER 3159dae75f28 test:html "/bin/bash" 17 minutes ago Exited (127) 14 minutes ago loving_spence ee14b6360af7 test:html "/bin/bash" 17 hours ago Exited (137) 16 hours ago nostalgic_mccarthy d6cb9c65e9f9 test:html "/bin/bash" 17 hours ago Exited (0) 17 hours ago stupefied_nobel da9f269a3db4 test:html "/bin/bash" 17 hours ago Exited (0) 17 hours ago admiring_spence ff1b2e9ba93f test:html "/bin/bash" 17 hours ago Exited (0) 17 hours ago awesome_easley 9fb8e08ef099 test:html "/bin/bash" 18 hours ago Exited (0) 17 hours ago focused_meitner 72d81f9c4463 57d081a803b8 "/bin/bash" 4 days ago Exited (137) 4 days ago determined_torvalds 63cfe4f13cb1 centos6:script "/bin/bash" 6 days ago Exited (137) 17 hours ago modest_jang 3780e4e4078e centos6:withupdates "/bin/bash" 6 days ago Exited (0) 6 days ago silly_hugle 0546df7913ae cento6:apacherunning "/bin/bash" 6 days ago Exited (137) 6 days ago big_archimedes 01b4b6ea00a6 8698ee40c98c "/bin/bash" 6 days ago Exited (0) 6 days ago jolly_wozniak 236d9514484f 8698ee40c98c "/bin/bash" 6 days ago Exited (0) 6 days ago sleepy_bassi 03b807ebedd0 8698ee40c98c "/bin/bash" 6 days ago Exited (0) 6 days ago grave_turing 254eb9fbfe10 8698ee40c98c "/bin/bash" 6 days ago Exited (0) 6 days ago goofy_colden e1238b6a84f1 9a61e0b7ef68 "/bin/bash" 6 days ago Exited (0) 6 days ago lonely_bose 80ed8528ddda centos:6 "/bin/bash" 6 days ago Exited (0) 6 days ago pensive_kowalevski 09fe89da7eb0 centos:6 "/bin/bash" 6 days ago Exited (0) 6 days ago grave_swartz a591a0c3ec3a centos:6 "/bin/bash" 6 days ago Exited (0) 6 days ago backstabbing_cori
What we can do with this information is we can start any of those containers again at the same status it was.
docker start big_archimides [root@localhost ~]# docker start big_archimedes big_archimedes
and then we can attach to that container and run commands
docker attach big_archimedes
Because containers remain we can kill them of , they clutter our system
If we want to remove all containers that are 6 days old we can do teh following
docker ps -a | grep '6 days ago' | awk '{print$1}' | xargs docker rm
Lecture: Container Routing
We have talked about how to give our hosted system access to container network resources by pulling the container IP from the JSON configuration as well as exposing network service ports or remapping them to local ports. In this video, we explore two methods of making your container resources available to other nodes on your local network and behind the firewall by accessing common Linux network management functions or through your local router interface.
One wy of accessing the container from another machine that sist on the local network as the host is to modify the settings on that machine so as whe you give it the ip of the container to lookup the host os ip instead.
So if the host os ip is 192.168.0.16 and the container is 172.17.0.2 and we are trying tp access the container from another machine that is on another ip for example 192.168.0.43 then on that machine we run the following command
route add -net 172.17.0.0 netmask 255.255.255.0 gw 192.168.0.16
so we are telling our machine for any ip in the 172.17.0.0/24 network go to gateway 192,168.0.16 an lookup that machine.
This is only usefull on that machine , we can set this setting on our router and give it a rule for the entire internal network.(example below show setup on dd-wrt router)
we can see now when we do a traceroute
traceroute 172.17.0.2 traceroute to 172.17.0.2 (172.17.0.2), 30 hops max, 60 byte packets 1 192.168.0.16 (192.168.0.16) 0.606 ms 0.601 ms 0.602 ms 2 172.17.0.2 (172.17.0.2) 1.137 ms 1.139 ms 1.128 ms
Lecture: Sharing Container Resources
We have previously introduced volume management with containers as it pertains to the underlying operating system and sharing mounts. Now we will explore how containers can be linked together to share their underlying filesystems.We are going to look at how container can share files between each other.The first step we run a container and in it we attach a volume that we will call /data
docker run -dti -v /data --name DATA1 stelios:centos6 /bin/bash
Then we run a second container but instead of adding a volume we reference the volume from the previous container
docker run -dti --volumes-from DATA1 --name DATA2 stelios:centos6 /bin/bash
So now we have the two containers running
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 772dcdac2fb7 stelios:centos6 "/bin/bash" 2 minutes ago Up 2 minutes 80/tcp DATA2 b63e15081295 stelios:centos6 "/bin/bash" 7 minutes ago Up 7 minutes 80/tcp D
So now the two containers are sharing the same folder /data and are linked by that filesystem.Anything you write in /data in one container its seen by the other and vice versa
Lecture: Committing a Running Container (Snapshot Images)
Up to now, we have built containers and base images by running a container, making some changes, ending the container and then committing those changes rolling them into a new base image. Now, we will show how to commit changes in a running container which can be used to provide in flight snapshots of periodic changes for development, version control, version testing and more.Lets say we have a running container upon which a package isnt installed.We install a apckage on that container and while the container is running we can simply comming the changes for that container and give it another name
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a742831c9a01 centos:centos6 "/bin/bash" 36 seconds ago Up 35 seconds jolly_northcutt [root@localhost ~]# docker commit jolly_northcutt centos6:which sha256:07df04cd482a2ca0b2cdf177d4aad412aabcd3426370d978e378ff14dae37c2e
so we see the container "jolly_northcut" is running and while its running we do a commit and save the container as centos:which
This way we take snapshots of a running container
We can use this in a development enviroment where we can have a script that takes snaphosts of running containers every 15 minutes and names them incrimentally , so we can roll back e.t.c
Only the changes are written when a commit is done , so this saves storage space
Lecture: Container Linking and Communication
Now that we have the fundamentals of communicating through port redirects and shared volumes, we can explore some of the more in depth methods of linking containers. In this video, we will explicit link together two containers so that they can securely share information amongst themselves about their IPs, applications and ports all automatically and through environment variables.
First step we start a container
docker run -itd --name mywebserver stelios:centos6 /bin/bash
Then we start a second container and we link that to the previous container.
docker run -it --name mytestcontainer1 --link mywebserver stelios:centos6 /bin/bash
What happens is that the two containers now know of each others existance and they are network linked together.
These two containers can now communicate with each other via known ports and ip's that arent necessarily open or known to the network.
We can ssh between them or write scripts to have them communicate.
If we run env | more on the "mytestcontainer1" we see the following
[root@41f4f8e50eac /]# ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02 inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:8 errors:0 dropped:0 overruns:0 frame:0 TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:648 (648.0 b) TX bytes:648 (648.0 b)
[root@41f4f8e50eac /]# env | more MYWEBSERVER_NAME=/mytestcontainer1/mywebserver MYWEBSERVER_PORT_80_TCP_ADDR=172.17.0.3 HOSTNAME=41f4f8e50eac MYWEBSERVER_PORT_80_TCP=tcp://172.17.0.3:80 TERM=xterm MYWEBSERVER_PORT_80_TCP_PROTO=tcp MYWEBSERVER_PORT=tcp://172.17.0.3:80
Notice that the containers mytestcontainer1's ip is 172.17.0.2 however it can see the web server running on port 80 at "mywebserver" at 172.17.0.3
Lecture: Taking Control of Ports
Previous videos have covered very basic port redirection and management. We will now discover why basic port to port redirection is inefficient as well as how to dynamically allocate host port redirects to known container ports. Finally, we will talk about how to bind a port to a single interface or IP rather than all network interfaces.As we saw before you forward a port to a container using the -p option.Navigating yo the host OS ip will show the apache site(as long as apache is running on the set container_
docker run -itd -p 80:80 --name Mywebserver2 test:html /bin/bash
The following command will choose a random port in the range of 32768 and above and point it to the running ports on the container
docker run -itd -P --name Mywebserver3 test:html /bin/bash
If we do a docker ps we can see that port 32768 from the host OS now points to port 8o on our container
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 489a53678edf test:html "/bin/bash" 2 minutes ago Up 2 minutes 0.0.0.0:32768->80/tcp Mywebserver3
we can start another two servers call them Mywebserver4 ,5 .As can be seen two other random ip's have been assigned.
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7ba29fa87c00 test:html "/bin/bash" 3 seconds ago Up 2 seconds 0.0.0.0:32770->80/tcp Mywebserver5 1f081a7ee14b test:html "/bin/bash" 11 seconds ago Up 10 seconds 0.0.0.0:32769->80/tcp Mywebserver4 489a53678edf test:html "/bin/bash" 8 minutes ago Up 8 minutes 0.0.0.0:32768->80/tcp Mywebserver3
We can also map specific ip's to port.this is usefull if we have more that one ip on our host machine.So we can say for ip 192.168.0.16 on the host , forward port 5000 to port 80 on the container
docker run -itd -p 192.168.0.16:5000:80 --name Mywebserver6 test:html /bin/bash
If we want to forard for a specific ip choosing a random port we can use the following ::, In the example bellow i am choosing a random port to forard to port 80. This will only be visible on the host OS since we are using 127.0.0.1.
docker run -itd -p 127.0.0.1::80 --name Mywebserver7 test:html /bin/bash
The docke ps command result for the previous two examples
1c72ed451c56 test:html "/bin/bash" 4 seconds ago Up 3 seconds 127.0.0.1:32771->80/tcp Mywebserver7 d0d59f35d742 test:html "/bin/bash" 6 minutes ago Up 6 minutes 192.168.0.16:5000->80/tcp Mywebserver6
Lecture: Five Useful Docker CLI Commands
Now that we have the context to understand why these commands are meaningful and how the information is derived behind the scenes, its time to learn about some of the most useful and more advanced CLI utilities from Docker: * docker cp * docker diff * docker events * docker history * docker execCopy
Copy is usefull for copying files from a container.
Even if we can start a container and then stop it , as long as we know its name we can copy a file from that container instance using the following syntax, will copy the file test/me to the tmp directory
docker cp distracted_keller:/srv/test.me /tmp/
Diff
Can be usefull to see what files have changed, modified , added, deleted in a container since it was started
docker diff Mywebserver2 C /var C /var/lock C /var/lock/subsys C /var/lock/subsys/httpd C /var/run C /var/run/httpd C /var/run/httpd/httpd.pid C /var/log C /var/log/httpd C /var/log/httpd/access_log C /var/log/httpd/error_log
Events
This will show events that happen to docker in general. i.e the system messages that are issued when a container is running
The example below shows what will be displayed while we execute docker events and we start a container
docker events 2016-05-07T17:53:49.512603183-04:00 container create 2f65a4d528b4345922530f7c5b970b1c2233a5783e6a0676eca5b863c043526d (build-date=2016-03-31, image=centos:centos6, license=GPLv2, name=evil_khorana, vendor=CentOS) 2016-05-07T17:53:49.514070794-04:00 container attach 2f65a4d528b4345922530f7c5b970b1c2233a5783e6a0676eca5b863c043526d (build-date=2016-03-31, image=centos:centos6, license=GPLv2, name=evil_khorana, vendor=CentOS) 2016-05-07T17:53:49.598431754-04:00 network connect fd2407fc878a0442cf2fd1554032e4d2dad97b39f54150d29089b6bf68250d0b (container=2f65a4d528b4345922530f7c5b970b1c2233a5783e6a0676eca5b863c043526d, name=bridge, type=bridge) 2016-05-07T17:53:49.728383410-04:00 container start 2f65a4d528b4345922530f7c5b970b1c2233a5783e6a0676eca5b863c043526d (build-date=2016-03-31, image=centos:centos6, license=GPLv2, name=evil_khorana, vendor=CentOS) 2016-05-07T17:53:49.731207866-04:00 container resize 2f65a4d528b4345922530f7c5b970b1c2233a5783e6a0676eca5b863c043526d (build-date=2016-03-31, height=24, image=centos:centos6, license=GPLv2, name=evil_khorana, vendor=CentOS, width=80)
We can also pass a parameter and see all the events that happened from a s specific date
docker events --since '2016-05-07'
History
Has to do with the initial image history on which the containers are based on
So below we run history on test:html image and its almost like a revision history of what was done to that image
docker history test:html IMAGE CREATED CREATED BY SIZE COMMENT 1e097b024b70 About an hour ago /bin/bash 2.377 MB d34231955c88 About an hour ago /bin/bash 113.4 MB 730e619a41ca 2 days ago /bin/sh -c #(nop) ADD file:06caba9b4b7649dba1 57 B 8691adf7aca2 2 days ago /bin/sh -c #(nop) EXPOSE 80/tcp 0 B 914df3ae6392 6 days ago /bin/sh -c #(nop) MAINTAINER stelios <stelios 0 B fc73b108c5ae 5 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B <missing> 5 weeks ago /bin/sh -c #(nop) LABEL name=CentOS Base Imag 0 B <missing> 5 weeks ago /bin/sh -c #(nop) ADD file:ae8f506cbd1f016c67 228.9 MB <missing> 8 months ago /bin/sh -c #(nop) MAINTAINER The CentOS Proje 0 B
Exec
We can execute a command without attaching to a container and get all the feedback from terminal on whats happening tonthe container when we execute the command
so we start a container and then we use the exec option to run update on that container
docker run -itd --name testexec centos:centos6 /bin/bash
docker exec -it testexec /usr/bin/yum -y update
Lecture: More Useful Docker CLI Commands
Now that we have the context to understand why these commands are meaningful and how the information is derived behind the scenes, its time to learn about some of the most useful and more advanced CLI utilities from Docker: * docker info * docker kill * docker save/export * docker load/import * docker pause/unpause * docker topInfo
The docker info command gives us a general overview of the docker server :
docker info Containers: 44 Running: 3 Paused: 0 Stopped: 41 Images: 24 Server Version: 1.11.1 Storage Driver: devicemapper Pool Name: docker-253:0-370564-pool Pool Blocksize: 65.54 kB Base Device Size: 10.74 GB Backing Filesystem: xfs Data file: /dev/loop0 Metadata file: /dev/loop1 Data Space Used: 2.402 GB Data Space Total: 107.4 GB Data Space Available: 27 GB Metadata Space Used: 7.877 MB Metadata Space Total: 2.147 GB Metadata Space Available: 2.14 GB Udev Sync Supported: true Deferred Removal Enabled: false Deferred Deletion Enabled: false Deferred Deleted Device Count: 0 Data loop file: /var/lib/docker/devicemapper/devicemapper/data Library Version: 1.02.107-RHEL7 (2015-12-01) Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: host bridge null Kernel Version: 3.10.0-327.13.1.el7.x86_64 Operating System: CentOS Linux 7 (Core) OSType: linux
top
Using "docker top" is like running top within the container , only we can do it from the host os. In the example below we run top for running container ourWeb1 , which is running apache.
root@localhost ~]# docker top ourWeb1 UID PID PPID C STIME TTY TIME CMD root 529 516 0 16:04 pts/2 00:00:00 /bin/bash root 570 529 0 16:04 ? 00:00:00 /usr/sbin/httpd 48 572 570 0 16:04 ? 00:00:00 /usr/sbin/httpd 48 573 570 0 16:04 ? 00:00:00 /usr/sbin/httpd 48 574 570 0 16:04 ? 00:00:00 /usr/sbin/httpd 48 575 570 0 16:04 ? 00:00:00 /usr/sbin/httpd 48 576 570 0 16:04 ? 00:00:00 /usr/sbin/httpd 48 577 570 0 16:04 ? 00:00:00 /usr/sbin/httpd 48 578 570 0 16:04 ? 00:00:00 /usr/sbin/httpd 48 579 570 0 16:04 ? 00:00:00 /usr/sbin/httpd
kill
used in case a container is unresponsive , wont stop because eit maybe waiting for a system process, or due to any other issue.
Its an unclean way of stoppinga container li
docker kill ourWeb1
pause
pausing a container is invisible to teh container itself
docker pause ourWeb1
to unpause issue the following
docker unpause ourWeb1
docker save/export docker load/import
We can export a container so that is can be used as a base image on another docker server.
First we need to stop the docker instance and then simply use the export command and output the command to a .tar file
docker stop ourWeb1 docker export ourWeb1 > /srv/ourweb.tar
To import the image we can simply run the following command
docker load -i /srv/ourweb.tar
also the following will work
docker load < /srv/ourweb.tar
Lecture: Optimizing Our Dockerfile Builds
Now that we have some background with our Dockerfile, let's talk about how to optimize a few things. We will demonstrate building a basic apache server with sshFirstly we modify the /root/dockerfile to conatin the following information
FROM centos:centos6 #start with this base image if it doesnt exist it will download it MAINTAINER stelios <stelios@milidonis.com> RUN yum -y update RUN yum -y install httpd #install the apache service RUN echo "/sbin/service httpd start" >> /root/.bashrc # to autostart apache RUN yum -y install openssh-server #install ssh server RUN echo "/sbin/service sshd start" >>/root/.bashrc # to autostart ssh RUN echo "The system configuration is ended" > /root/README EXPOSE 80 22
Then we build the image
docker build -t mytestnode .
The docker file runs different commands sequentially to build the docker image, and creates it takes more time and creates multiple container by the time it finishes, we can do it using one command by joining the commands using && so it is less time consuming and takes up less resources/ Its important that the command is on one line .
FROM centos:centos6 MAINTAINER stelios <stelios@milidonis.com> RUN yum -y update && RUN yum -y install httpd #install the apache service && RUN echo "/sbin/service httpd start" >> /root/.bashrc && RUN yum -y install openssh-server && RUN echo "/sbin/service sshd start" >>/root/.bashrc && RUN echo "The system configuration is ended" > /root/README && EXPOSE 80 22