程式扎記: [ 文章收集 ] A Practical Introduction to Docker Containers

標籤

2015年4月22日 星期三

[ 文章收集 ] A Practical Introduction to Docker Containers

Source From Here 
Background 
Why 
Docker has quite an amount of buzz around it today because it makes so many things easy that were difficult with virtual machines. 

Docker containers makes it easy for Developers, Systems Administrators, Architects, Consultants and others to quickly test a piece of software in a container;much quicker than a virtual machine, and using less resources. The average command in Docker takes under a second to complete. 
# time docker run fedora cat /etc/redhat-release
Fedora release 20 (Heisenbug)
real 0m0.715s
user 0m0.004s
sys 0m0.004s

What 
SIMPLE USE CASES 
* I need to see the man page from a specific version of RHELCentOS or Fedora
* I need to quickly verify the command line options of a program
* I need to test the functionality of a specific version of software
* I need a scratch pad that is NOT my system
* I need a single daemon running, and I don’t care what distribution of Linux it runs on (see registry below)


COMPLEX USE CASES 
Docker containers run a single process when started, but complex installations of software which require multiple daemons running simultaneously (RHEV-M, Satellite, etccan be done. However, they require more engineering work using either Bash scripting or something like: Using Supervisor with Docker or SystemD

PRODUCTION VS. DEVELOPMENT 
At the time of this writing Docker has not yet reached version 1.0 and Red Hat Enterprise Linux 7 has not yet been released as generally available, so production workloads are not recommended. Also, take note that some of the examples in this tutorial make use of docker to test software from different versions of CentOS and Red Hat Enterprise Linux; while this will have limited support, it is quite useful for quick testing and reading man pages. 

CENTOS AND RED HAT ENTERPRISE LINUX 
This tutorial will focus on integration with Red Hat technologies including CentOS and Red Hat Enterprise Linux. As mentioned, at the time of this writing, Docker has not yet reached version 1.0 and Red Hat Enterprise Linux 7 has not yet been released as generally available, so the majority of the hands on portion of this tutorial will use CentOS. Many of these tutorials can also be completed using Fedora. 

Architecture 
One of the key advantages of using Docker is it’s centralized image management server, called a Registry ServerThe Docker project maintains a public registry server which hosts images they maintain, as well as images created by the community. This registry service is free to use, as long as the images are public. As one builds images, they are made up of layers. These layers are shared together in, what is called a repository. Users on the registry can share multiple repositories. 

Docker has an official CentOS 6 repository which they support: https://index.docker.io/_/centos/ 

This tutorial will use several public CentOS repositories which I have created and shared on Docker’s public registry. I have created a separate repository for each major version of CentOS: https://index.docker.io/u/fatherlinux/ 

OS VIRTUALIZATION VS. APPLICATION VIRTUALIZATION 
Why separate repositories for each major version of Red Hat Enterprise Linux or CentOS? This was a conscious decision because we are working with a full enterprise Linux distribution versus a single application. Historically, it has been best practice to install a fresh copy when upgrading major versions of Red Hat Enterprise Linux or CentOS. While it is possible to upgrade in place and share multiple versions in a single repository, this is not the preferred method with an enterprise operating system. 

However, when virtualizing individual applications, it may be very appropriate to upgrade in place and share all versions within a single repository (See section: Set Up a Registry Server). 

Known Caveats 
After reading this tutorial, you may be excited to set up your own registry server. This is easy to do, but has some caveats, so think think through whether it is worth just using a hosted registry server. 
* As of version 0.6.9, the private registry server does not have any kind of authentication support without using an HTTP proxy such as Apache or NginX.
* As of version 0.6.9, the private registry server has support for search, but the client can not search them by default, so a browser must be used to view the images.

Basic Operations 
Now we will run through some basic operations to get you up and running. 

Install Docker 
In CentOS 6, this requires the user space tools from the EPEL. Personally, I prefer to disable after installation so that later, full system updates don’t break the system. 
# rpm -ivh http://mirrors.syringanetworks.net/fedora-epel/6/i...86/epel-release-6-8.noarch.rpm
# yum install docker-io
# yum-config-manager --disable epel
# service docker start
# chkconfig docker on

From CentOS7, the Docker installation become simple (ref): 
# yum install docker
# service docker start # Start the docker daemon.
# chkconfig docker on # If we want Docker to start at boot, we should also do so

Test Docker 
This will automatically pull the latest CentOS 4 image from the remote repository and cache it locally. 

// -i, --interactive=false Keep STDIN open even if not attached
// -t, --tty=false Allocate a pseudo-TTY

# docker run -i -t --rm fatherlinux/centos4-base cat /etc/redhat-release
CentOS release 4.8 (Final)

Pull an Image 
This will pull the latest CentOS 5 image from the remote repository and cache it in the local index. If the image you are pulling is made up of layers, all of the layers will be pulled. 
# docker pull fatherlinux/centos5-base:latest

List Images 
This will list all of the images in the local index and display how they are linked to each other. Every time a new container is spawned from an image, it will create another copy on write image to save it’s changes too. The tree structure will help make things clear. 
# docker images --tree

Tag an Image 
It makes it easier to deal with images if they are tagged with simple names 
# docker tag fatherlinux/centos5-base centos5-base

Run a Container 
Notice how easy it is to test a command in CentOS 4 
# docker run -i -t --rm fatherlinux/centos4-base man rsync

Docker Registry 
Log in to the Hosted Docker Registry 
To create repositories on the public Docker Registry, it is necessary to sign up at: https://www.docker.io/account/signup/ 

Once you have created an account, you will need to login from the command line: 
# docker login index.docker.io
Username: johnklee
Password: 
Email: puremonkey2001@yahoo.com.tw
Login Succeeded

Dockerfile: Commit an Image 
Once logged in to the public Docker Registry, new images can be built and committed with code using a Dockerfile. This allows an administrator to automatically rebuild a known good starting point quickly and easily. It is recommended to always start with an image defined by a Dockerfile. 

There are a couple of important things to notice with this Dockerfile. First, the FROM directive specifies a username and repository: fatherlinux/centos6-base. This will pull the latest image from the centos6-base repostiory. In this example, I have provided the source repository for you. Second, the only change we have specified in the Dockerfile, is to update CentOS to latest available packages. 
# vi Dockerfile
  1. # crunchtools image  
  2. #  
  3. # Version 1  
  4.   
  5. # Pull from CentOS RPM Build Image  
  6. FROM fatherlinux/centos6-base  
  7.   
  8. MAINTAINER Scott McCarty smccarty@redhat.com  
  9.   
  10. # Update the image  
  11. RUN yum update -y  
  12.   
  13. # Output  
  14. # ENTRYPOINT tail /var/log/yum.log  

BUILD AND TAG THE IMAGE 
# docker build --help

Usage: docker build [OPTIONS] PATH | URL | -

Build a new image from the source code at PATH

-f, --file= Name of the Dockerfile(Default is 'Dockerfile')
--force-rm=false Always remove intermediate containers
--help=false Print usage
--no-cache=false Do not use cache when building the image
--pull=false Always attempt to pull a newer version of the image
-q, --quiet=false Suppress the verbose output generated by the containers
--rm=true Remove intermediate containers after a successful build
-t, --tag= Repository name (and optionally a tag) for the image


# docker build -t centos6-base-updated .

INSPECT THE NEW IMAGE 
This will list all of the layers in an image: 
# docker images --tree


Notice that the new image is now available for deployment. 

TEST THE NEW IMAGE 
docker run -i -t --rm centos6-base-updated uname -a
Linux 3c36ed41228a 3.10.0-229.el7.x86_64 #1 SMP Fri Mar 6 11:36:42 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux


Manually: Commit an Image 
Once a container has changes made locally, they can be committed to the local index. This allows you to check point and continue. It also allows you to create new images based off of this modified container. 
docker run -i -t fatherlinux/centos6-base bash

MODIFY THE IMAGE 
Make some changes inside the container. In this example, change the hostname and exit 
# vi /etc/sysconfig/network
  1. NETWORKING=yes  
  2. HOSTNAME=test.crunchtools.com  

# exit

COMMIT THE CONTAINER 
First, get a list of containers. Notice that every container has a CONTAINTER ID and a STATUS. A status of Up means the container is currently running, while a status of Exit indicates that the container has been stopped. Think of the CONTAINER ID as a branch from the base image that contains all of the changes that were made to the container while it was running. By default this data is saved even after the container is shut down. 
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5c4abb8dcc01 fatherlinux/centos6-base:latest "bash" About a minute ago Exited (0)

Now, commit the container back as a branch of it’s base image 
# docker commit 5c4abb8dcc01
4fb1c181433bbd929b02909dd053c8d089535cf921d98b24e24a1734912c2a8f

Tag the new image with something meaningful 
# docker tag --help
Usage: docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]

Tag an image into a repository

-f, --force=false Force
--help=false Print usage


# docker tag -f 4fb1c181433b centos6-base-hostname
# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
docker.io/centos6-base-hostname latest 4fb1c181433b 13 minutes ago 1.724 GB
centos6-base-updated latest 05882f4d02ce 13 hours ago 1.724 GB
docker.io/centos 7 0114405f9ff1 7 days ago 215.7 MB
docker.io/centos centos7 0114405f9ff1 7 days ago 215.7 MB
docker.io/fatherlinux/centos6-base latest e39724bc32b2 13 months ago 1.724 GB
docker.io/fatherlinux/centos4-base latest 822821076bef 13 months ago 1.212 GB

Push a Container 
Once a container is committed locally, it can be pushed back to the registry server to be shared. The changes will be pushed as a layered image. Notice how quickly it is able to push only the differences between your modified image and the base image. This is a big part of the value. 
# docker tag centos6-base-hostname johnklee/tutorial # Here johnklee/tutorial is your personal repository
# docker push johnklee/tutorial
Do you really want to push to public registry? [Y/n]: Y
The push refers to a repository [docker.io/johnklee/tutorial] (len: 1)
Sending image list
Pushing repository docker.io/johnklee/tutorial (1 tags)
e39724bc32b2: Image already pushed, skipping
4fb1c181433b: Image successfully pushed
Pushing tag for rev [4fb1c181433b] on {https://cdn-registry-1.docker.io/v1/repositories/johnklee/tutorial/tags/latest}


Advanced Operations 
Pull All Standard Images 
These CentOS images are in the public Docker repository. 
# docker pull fatherlinux/centos4-base
# docker pull fatherlinux/centos5-base
# docker pull fatherlinux/centos6-base

Create Base Image 
This method was developed with guidance from this script. This example is based on CentOS 6. 

Create a tar file of the system 
# tar --numeric-owner --exclude=/proc --exclude=/sys -cvf centos6-base.tar /

Copy the tar file to where the consuming system and Import the image 
# cat centos6-base.tar | docker import - centos6-base

Test 
# docker run -i -t centos6-base cat /etc/redhat-release

Remove Old Docker Containers 
By default, Docker keeps changes for every container which is instantiated. When testing, this can be undesirable. Be careful because this will remove all branches/data. Any containers which have not been committed will have all data deleted: 
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5c4abb8dcc01 fatherlinux/centos6-base:latest "bash" 55 minutes ago Exited (0) 55 minutes ago elated_wilson
7438f3c698ee aa5a847957ffaa51544325fc1a8c7d31140fa904230cffc44c0ef66e7e82c4a0:latest "/bin/sh -c 'yum upd 13 hours ago Exited (1) 13 hours ago insane_ardinghelli
142873548b68 aa5a847957ffaa51544325fc1a8c7d31140fa904230cffc44c0ef66e7e82c4a0:latest "/bin/sh -c 'yum upd 13 hours ago Exited (1) 13 hours ago naughty_albattani
3fbd20430713 centos:latest "/bin/sh" 23 hours ago Exited (0) 23 hours ago reverent_banach

# docker rm --help
Usage: docker rm [OPTIONS] CONTAINER [CONTAINER...]

Remove one or more containers

-f, --force=false Force the removal of a running container (uses SIGKILL)
--help=false Print usage
-l, --link=false Remove the specified link
-v, --volumes=false Remove the volumes associated with the container

# docker rm 7438f3c698ee
# docker ps -a # Container 7438f3c698ee has been deleted.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5c4abb8dcc01 fatherlinux/centos6-base:latest "bash" 56 minutes ago Exited (0) 55 minutes ago elated_wilson
142873548b68 aa5a847957ffaa51544325fc1a8c7d31140fa904230cffc44c0ef66e7e82c4a0:latest "/bin/sh -c 'yum upd 13 hours ago Exited (1) 13 hours ago naughty_albattani
3fbd20430713 centos:latest "/bin/sh" 23 hours ago Exited (0) 23 hours ago reverent_banach


// -a, --all=false Show all containers (default shows just running)
// -q, --quiet=false Only display numeric IDs
// --no-trunc=false Don't truncate output

# docker ps --no-trunc -a -q
5c4abb8dcc0142e3ac5eba7eb2dbf3af2cf76bc5d4851c69c020f5a15fe92310
142873548b689f222401fccff232a3177aa744826bf0684ccbdb9d1d44013b11
3fbd2043071334bacbb7f062c30744e91eca48045fa5c67c45982d7709aecca0

# docker rm `docker ps --no-trunc -a -q` // Delete all containers 

Supplement 
Docker Document - Installing Docker - CentOS-7

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!