与Docker Images一起工作

在介绍中,我们发现Docker images是container的基本容器。在之前的章节,我们已经使用已经存在的Docker images了,例如Ubuntu image和training/webapp image。

Docker stores下载在Docker 主机上下载images。如果image 不存在本地,则将从Docker Hub上下载。

我们将在本节学到一些Docker images:

  • 与本地Docker host上images工作,及管理它们。
  • 创建一个基础images。
  • 上传images到Docker Hub Registry。

列举主机上的images

        我们从列举本地主机上的images开始学习。我们可以像这样使用docker images:

$ sudo docker images
REPOSITORY       TAG      IMAGE ID      CREATED      VIRTUAL SIZE
training/webapp  latest   fc77f57ad303  3 weeks ago  280.5 MB
ubuntu           13.10    5e019ab7bf6d  4 weeks ago  180 MB
ubuntu           saucy    5e019ab7bf6d  4 weeks ago  180 MB
ubuntu           12.04    74fe38d11401  4 weeks ago  209.6 MB
ubuntu           precise  74fe38d11401  4 weeks ago  209.6 MB
ubuntu           12.10    a7cf8ae4e998  4 weeks ago  171.3 MB
ubuntu           quantal  a7cf8ae4e998  4 weeks ago  171.3 MB
ubuntu           14.04    99ec81b80c55  4 weeks ago  266 MB
ubuntu           latest   99ec81b80c55  4 weeks ago  266 MB
ubuntu           trusty   99ec81b80c55  4 weeks ago  266 MB
ubuntu           13.04    316b678ddf48  4 weeks ago  169.4 MB
ubuntu           raring   316b678ddf48  4 weeks ago  169.4 MB
ubuntu           10.04    3db9c44f4520  4 weeks ago  183 MB
ubuntu           lucid    3db9c44f4520  4 weeks ago  183 MB

            我们将看到之前使用的images。当我们使用image启动容器的时候,每一个都已经从Docker Hub上下载了。

            我们从列表中看三个重要的信息:

  •             他们来源的repository,例如:ubuntu。
  •             每一个image的tags,例如14.04。
  •              每个image的ID。
            每一个repository可能含有多个不同的images。例如Ubuntu image,我看到多个image:Ubuntu 10.04,12.04,12.10,13.04,13.10和14.04。每一个类型用tag表示,我们可以像这样引用被标签的image:
ubuntu:14.04
           我们使用被标签的image启动容器,像这样:
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
            替代,我们想要运行Ubuntu 12.04 image来启动container:
$ sudo docker run -t -i ubuntu:12.04 /bin/bash
            如果没有指定一个image类型,例如:只是使用了Ubuntu,则Docker将默认使用ubuntu:latest 的image。

           注意:建议指定image的tag,这样可以准确的知道我们使用的image类型。

获得一个新的image

        怎样获得新的images呢?如果Docker主机上不存在,则Docker会自动下载image。这将潜在的增加一些时间来启动container。如果我们想要预加载一个image,可以使用docker pull命令下载它。我们可以下载centos image。

$ sudo docker pull centos
Pulling repository centos
b7de3133ff98: Pulling dependent layers
5cc9e91966f7: Pulling fs layer
511136ea3c5a: Download complete
ef52fb1fe610: Download complete
. . .

Status: Downloaded newer image for centos

             我们看到image的每一个层都已经下载,现在我们从这个image的运行container,我们将不用等待去下载这个image。

$ sudo docker run -t -i centos /bin/bash
bash-4.1#
搜索images

         Docker的一个特性是,许多人创建了用于不同目的的Docker images。许多已经上传到了Docker Hub。我们可以在Docker Hub网站上搜索这些image。


        我们也可以在命令行中使用命令docker search搜索image。我们团队需要一个image,Ruby和Sinatra已经被安装在WEB应用开发环境。我们可以使用docker search搜索合适image,搜索出那些包含sinatra的image。

$ sudo docker search sinatra
NAME                                   DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
training/sinatra                       Sinatra training image                          0                    [OK]
marceldegraaf/sinatra                  Sinatra test app                                0
mattwarren/docker-sinatra-demo                                                         0                    [OK]
luisbebop/docker-sinatra-hello-world                                                   0                    [OK]
bmorearty/handson-sinatra              handson-ruby + Sinatra for Hands on with D...   0
subwiz/sinatra                                                                         0
bmorearty/sinatra                                                                      0
. . .
          我们看到返回了许多包含sinatra的images。返回给我们罗列的image、names、description、stars(哪个image是流行,如果一个用户喜欢这个image,就是star它),offical 和Automated 构建的状态。官方的repositories的构建和维护是由Stackbrew项目负责的,Automated repositories是自动构建的,允许你去验证image的来源和内容。

          我们会回顾了可用的image,我们决定使用training/sinatra image。到目前为止,我们使用了两种类型的image repositories,images像Ubuntu这样的,称为base或者root images。这些base images有Docker Inc提供、构建、验证和支出。这些可以被单个名字标识。

          我们也可以看用户images,例如我们选择的training/sinatra。一个用户image属于Docker community成员,由他们构建和维护。你可以标识这些用户image,他们前缀使用创建者的名字,这里是training。

推送image

        我们标识一个合适image,training/sinatra,我们现在可以使用docker pull命令下载。

$ sudo docker pull training/sinatra
        团队可以使用者image运行他们自己的container了。

$ sudo docker run -t -i training/sinatra /bin/bash
root@a8cb6ce02d85:/#
创建我们自己images

         团队发现training/sinatra image 相当有用,但是他们想在上面做出一些改变。这里有两种方法来更新和创建images。

        1. 我们更新由image创建来的container,然后提交结果到一个image。

        2. 我们使用Dockerfile来特定的指令创建image。

        

         更新和提交image

         在更新一个image之前,我们先用想用更新的image创建一个container。

$ sudo docker run -t -i training/sinatra /bin/bash
root@0b2616b0e5a8:/#
          注意:记录一下container ID已经被创建:0b2616b0e5a8,我们接下来将会使用。

         在运行的container内部,我们添加json gem。

root@0b2616b0e5a8:/# gem install json
          一旦这步完成,我们使用exit命令退出container。

         现在我们有一个container的变化需要去做。我们可以提交container的副本作为image,使用docker commit命令。

$ sudo docker commit -m "Added json gem" -a "Kate Smith" \
0b2616b0e5a8 ouruser/sinatra:v2
4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c

          我们使用了docker commit指令。我们指定两个flag:-m 和 -a 。-m 允许我们指定提交的信息,更像是向版本控制系统提交。-a允许我们指定这个更新的作者。

          我们也可以指定这个新的image创建来的container,0b2616b0e5a8(我们记录的container ID)和我们为这个image指定了目标。

ouruser/sinatra:v2
          我们分解来看这个目标。它包含一个新的用户ouruser,我们正在写入image。我们也指定了image的名字,这里我们保留原始的image的名字sinatra。最后我们指定了一个特定tag:v2。

          我们可以看到我们新的ourser/sinatra image,使用docker images命令。

$ sudo docker images
REPOSITORY          TAG     IMAGE ID       CREATED       VIRTUAL SIZE
training/sinatra    latest  5bc342fa0b91   10 hours ago  446.7 MB
ouruser/sinatra     v2      3c59e02ddd1a   10 hours ago  446.7 MB
ouruser/sinatra     latest  5db5f8471261   10 hours ago  446.7 MB
          使用我们新的image来创建container,我们可以:

$ sudo docker run -t -i ouruser/sinatra:v2 /bin/bash
root@78e82f680994:/#
构建image来自Dockerfile  

        使用docker commit指令是一个相当简单的扩展image的方法,但是它有一点麻烦,在团队之中分享images的开发进度不是很方便。替代方法,我们使用一个新的命令docker build,从草稿中构建新的image。

        为了实现这个,我们创建了一个dockerfile,它包含了一系列指令告诉Dicker如何构建image。

        首先创建一个目录和Dockerfile。

$ mkdir sinatra
$ cd sinatra
$ touch Dockerfile

         每一指令创建了一个新的image层。让我们看一个简单的例子,为我们开发团队构建一个自己的sinatra image。

# This is a comment
FROM ubuntu:14.04
MAINTAINER Kate Smith <ksmith@example.com>
RUN apt-get update && apt-get install -y ruby ruby-dev
RUN gem install sinatra
          Dockerfile做了什么?每一个指定前缀是一个语法,而且大写。

INSTRUCTION statement
          注意:使用#标识注释。

         第一个指令From告诉Docker我们的image的来源,在这个例子中我们将新的image构建在一个Ubuntu 14.04 image上。

         下一步我们使用MAINTAINER指令来指定谁来维护我们的新image。

          最后,我们指定了两个RUN指令。一个RUN指令执行一个命令在image中,例如安装包。这个我们更新了APT缓存,安装Ruby和RubyGems 和安装了Sinatra gem。

          注意:a lot more instructions available to us in a Dockerfile

          现在我们那Dockerfile和使用docker build命令来创建一个image。

$ sudo docker build -t ouruser/sinatra:v2 .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon 
Step 0 : FROM ubuntu:14.04
 ---> e54ca5efa2e9
Step 1 : MAINTAINER Kate Smith <ksmith@example.com>
 ---> Using cache
 ---> 851baf55332b
Step 2 : RUN apt-get update && apt-get install -y ruby ruby-dev
 ---> Running in 3a2558904e9b
Selecting previously unselected package libasan0:amd64.
(Reading database ... 11518 files and directories currently installed.)
Preparing to unpack .../libasan0_4.8.2-19ubuntu1_amd64.deb ...
Unpacking libasan0:amd64 (4.8.2-19ubuntu1) ...
Selecting previously unselected package libatomic1:amd64.
Preparing to unpack .../libatomic1_4.8.2-19ubuntu1_amd64.deb ...
Unpacking libatomic1:amd64 (4.8.2-19ubuntu1) ...
Selecting previously unselected package libgmp10:amd64.
Preparing to unpack .../libgmp10_2%3a5.1.3+dfsg-1ubuntu1_amd64.deb ...
Unpacking libgmp10:amd64 (2:5.1.3+dfsg-1ubuntu1) ...
Selecting previously unselected package libisl10:amd64.
Preparing to unpack .../libisl10_0.12.2-1_amd64.deb ...
Unpacking libisl10:amd64 (0.12.2-1) ...
Selecting previously unselected package libcloog-isl4:amd64.
Preparing to unpack .../libcloog-isl4_0.18.2-1_amd64.deb ...
Unpacking libcloog-isl4:amd64 (0.18.2-1) ...
Selecting previously unselected package libgomp1:amd64.
Preparing to unpack .../libgomp1_4.8.2-19ubuntu1_amd64.deb ...
Unpacking libgomp1:amd64 (4.8.2-19ubuntu1) ...
Selecting previously unselected package libitm1:amd64.
Preparing to unpack .../libitm1_4.8.2-19ubuntu1_amd64.deb ...
Unpacking libitm1:amd64 (4.8.2-19ubuntu1) ...
Selecting previously unselected package libmpfr4:amd64.
Preparing to unpack .../libmpfr4_3.1.2-1_amd64.deb ...
Unpacking libmpfr4:amd64 (3.1.2-1) ...
Selecting previously unselected package libquadmath0:amd64.
Preparing to unpack .../libquadmath0_4.8.2-19ubuntu1_amd64.deb ...
Unpacking libquadmath0:amd64 (4.8.2-19ubuntu1) ...
Selecting previously unselected package libtsan0:amd64.
Preparing to unpack .../libtsan0_4.8.2-19ubuntu1_amd64.deb ...
Unpacking libtsan0:amd64 (4.8.2-19ubuntu1) ...
Selecting previously unselected package libyaml-0-2:amd64.
Preparing to unpack .../libyaml-0-2_0.1.4-3ubuntu3_amd64.deb ...
Unpacking libyaml-0-2:amd64 (0.1.4-3ubuntu3) ...
Selecting previously unselected package libmpc3:amd64.
Preparing to unpack .../libmpc3_1.0.1-1ubuntu1_amd64.deb ...
Unpacking libmpc3:amd64 (1.0.1-1ubuntu1) ...
Selecting previously unselected package openssl.
Preparing to unpack .../openssl_1.0.1f-1ubuntu2.4_amd64.deb ...
Unpacking openssl (1.0.1f-1ubuntu2.4) ...
Selecting previously unselected package ca-certificates.
Preparing to unpack .../ca-certificates_20130906ubuntu2_all.deb ...
Unpacking ca-certificates (20130906ubuntu2) ...
Selecting previously unselected package manpages.
Preparing to unpack .../manpages_3.54-1ubuntu1_all.deb ...
Unpacking manpages (3.54-1ubuntu1) ...
Selecting previously unselected package binutils.
Preparing to unpack .../binutils_2.24-5ubuntu3_amd64.deb ...
Unpacking binutils (2.24-5ubuntu3) ...
Selecting previously unselected package cpp-4.8.
Preparing to unpack .../cpp-4.8_4.8.2-19ubuntu1_amd64.deb ...
Unpacking cpp-4.8 (4.8.2-19ubuntu1) ...
Selecting previously unselected package cpp.
Preparing to unpack .../cpp_4%3a4.8.2-1ubuntu6_amd64.deb ...
Unpacking cpp (4:4.8.2-1ubuntu6) ...
Selecting previously unselected package libgcc-4.8-dev:amd64.
Preparing to unpack .../libgcc-4.8-dev_4.8.2-19ubuntu1_amd64.deb ...
Unpacking libgcc-4.8-dev:amd64 (4.8.2-19ubuntu1) ...
Selecting previously unselected package gcc-4.8.
Preparing to unpack .../gcc-4.8_4.8.2-19ubuntu1_amd64.deb ...
Unpacking gcc-4.8 (4.8.2-19ubuntu1) ...
Selecting previously unselected package gcc.
Preparing to unpack .../gcc_4%3a4.8.2-1ubuntu6_amd64.deb ...
Unpacking gcc (4:4.8.2-1ubuntu6) ...
Selecting previously unselected package libc-dev-bin.
Preparing to unpack .../libc-dev-bin_2.19-0ubuntu6_amd64.deb ...
Unpacking libc-dev-bin (2.19-0ubuntu6) ...
Selecting previously unselected package linux-libc-dev:amd64.
Preparing to unpack .../linux-libc-dev_3.13.0-30.55_amd64.deb ...
Unpacking linux-libc-dev:amd64 (3.13.0-30.55) ...
Selecting previously unselected package libc6-dev:amd64.
Preparing to unpack .../libc6-dev_2.19-0ubuntu6_amd64.deb ...
Unpacking libc6-dev:amd64 (2.19-0ubuntu6) ...
Selecting previously unselected package ruby.
Preparing to unpack .../ruby_1%3a1.9.3.4_all.deb ...
Unpacking ruby (1:1.9.3.4) ...
Selecting previously unselected package ruby1.9.1.
Preparing to unpack .../ruby1.9.1_1.9.3.484-2ubuntu1_amd64.deb ...
Unpacking ruby1.9.1 (1.9.3.484-2ubuntu1) ...
Selecting previously unselected package libruby1.9.1.
Preparing to unpack .../libruby1.9.1_1.9.3.484-2ubuntu1_amd64.deb ...
Unpacking libruby1.9.1 (1.9.3.484-2ubuntu1) ...
Selecting previously unselected package manpages-dev.
Preparing to unpack .../manpages-dev_3.54-1ubuntu1_all.deb ...
Unpacking manpages-dev (3.54-1ubuntu1) ...
Selecting previously unselected package ruby1.9.1-dev.
Preparing to unpack .../ruby1.9.1-dev_1.9.3.484-2ubuntu1_amd64.deb ...
Unpacking ruby1.9.1-dev (1.9.3.484-2ubuntu1) ...
Selecting previously unselected package ruby-dev.
Preparing to unpack .../ruby-dev_1%3a1.9.3.4_all.deb ...
Unpacking ruby-dev (1:1.9.3.4) ...
Setting up libasan0:amd64 (4.8.2-19ubuntu1) ...
Setting up libatomic1:amd64 (4.8.2-19ubuntu1) ...
Setting up libgmp10:amd64 (2:5.1.3+dfsg-1ubuntu1) ...
Setting up libisl10:amd64 (0.12.2-1) ...
Setting up libcloog-isl4:amd64 (0.18.2-1) ...
Setting up libgomp1:amd64 (4.8.2-19ubuntu1) ...
Setting up libitm1:amd64 (4.8.2-19ubuntu1) ...
Setting up libmpfr4:amd64 (3.1.2-1) ...
Setting up libquadmath0:amd64 (4.8.2-19ubuntu1) ...
Setting up libtsan0:amd64 (4.8.2-19ubuntu1) ...
Setting up libyaml-0-2:amd64 (0.1.4-3ubuntu3) ...
Setting up libmpc3:amd64 (1.0.1-1ubuntu1) ...
Setting up openssl (1.0.1f-1ubuntu2.4) ...
Setting up ca-certificates (20130906ubuntu2) ...
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
Setting up manpages (3.54-1ubuntu1) ...
Setting up binutils (2.24-5ubuntu3) ...
Setting up cpp-4.8 (4.8.2-19ubuntu1) ...
Setting up cpp (4:4.8.2-1ubuntu6) ...
Setting up libgcc-4.8-dev:amd64 (4.8.2-19ubuntu1) ...
Setting up gcc-4.8 (4.8.2-19ubuntu1) ...
Setting up gcc (4:4.8.2-1ubuntu6) ...
Setting up libc-dev-bin (2.19-0ubuntu6) ...
Setting up linux-libc-dev:amd64 (3.13.0-30.55) ...
Setting up libc6-dev:amd64 (2.19-0ubuntu6) ...
Setting up manpages-dev (3.54-1ubuntu1) ...
Setting up libruby1.9.1 (1.9.3.484-2ubuntu1) ...
Setting up ruby1.9.1-dev (1.9.3.484-2ubuntu1) ...
Setting up ruby-dev (1:1.9.3.4) ...
Setting up ruby (1:1.9.3.4) ...
Setting up ruby1.9.1 (1.9.3.484-2ubuntu1) ...
Processing triggers for libc-bin (2.19-0ubuntu6) ...
Processing triggers for ca-certificates (20130906ubuntu2) ...
Updating certificates in /etc/ssl/certs... 164 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.
 ---> c55c31703134
Removing intermediate container 3a2558904e9b
Step 3 : RUN gem install sinatra
 ---> Running in 6b81cb6313e5
unable to convert "\xC3" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to US-ASCII for README.rdoc, skipping
unable to convert "\xC3" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to US-ASCII for README.rdoc, skipping
Successfully installed rack-1.5.2
Successfully installed tilt-1.4.1
Successfully installed rack-protection-1.5.3
Successfully installed sinatra-1.4.5
4 gems installed
Installing ri documentation for rack-1.5.2...
Installing ri documentation for tilt-1.4.1...
Installing ri documentation for rack-protection-1.5.3...
Installing ri documentation for sinatra-1.4.5...
Installing RDoc documentation for rack-1.5.2...
Installing RDoc documentation for tilt-1.4.1...
Installing RDoc documentation for rack-protection-1.5.3...
Installing RDoc documentation for sinatra-1.4.5...
 ---> 97feabe5d2ed
Removing intermediate container 6b81cb6313e5
Successfully built 97feabe5d2ed

            我们指定了我们的docker build命令,使用了-t 去表示我们新的image属于用户ouruser,这个repository名字sinatra,给了一个tag:v2。

            我们也可以指定我们Dockerfile的路径,使用. 标识Docker在当前路径。

            注意:也可以为Dockerfile指定一个路径。

            现在我们每一个Dockerfile中的指令都被一步一步的执行。我们可以看到每一步创建一个新的container,在container中运行指令,然后提交变化,类似之前看到的docker commit工作流。当所有的指令执行之后,我们留下了97feabe5d2ed image(被标记为ouruser/sinatra:v2)和所有的中间容器将被完全清楚。

            注意:一个image在不包括storage driver的情况下,不能操作127层。这个限制有利于优化image的大小。

            我们可以从新image中运行container。

$ sudo docker run -t -i ouruser/sinatra:v2 /bin/bash
root@8196968dac35:/#

             注意:这只是一个简单的image创建指南。我们跳过了很大一群可以使用的指令。我们将在后面的章节或者dockerfile索引中看到详细的描述和每个指令的例子。Best Practices guide有利于写出清晰、可读、可维护的Dockerfile。

在image上设置tag

            我们可以在你提交或者构建见后,添加tag在存在的image上。我们可以使用dicker tag命令。我们添加一个新的tag到我们的ouruser/sinatra image。

$ sudo docker tag 5db5f8471261 ouruser/sinatra:devel
             docker tag命令带有image ID,5db5f8471261,我们的用户名字,repository名字和新的tag。

             我们使用docker image命令查看新的tag。

$ sudo docker images ouruser/sinatra
REPOSITORY          TAG     IMAGE ID      CREATED        VIRTUAL SIZE
ouruser/sinatra     latest  5db5f8471261  11 hours ago   446.7 MB
ouruser/sinatra     devel   5db5f8471261  11 hours ago   446.7 MB
ouruser/sinatra     v2      5db5f8471261  11 hours ago   446.7 MB
推送image到Docker Hub

            一旦我们构建或者创建了一个新的image,我们可以使用docker push命令将它推送到Docker Hub上。这让你将它分享给其他人,也可以推送到私有的repository。

$ sudo docker push ouruser/sinatra
The push refers to a repository [ouruser/sinatra] (len: 1)
Sending image list
Pushing repository ouruser/sinatra (3 tags)
. . .
 移除主机的image

         使用docker rmi命令移除Docker 主机上的image,这个类似于移除container。

         删除不在需要的training/sinatra image。

$ sudo docker rmi training/sinatra
Untagged: training/sinatra:latest
Deleted: 5bc342fa0b91cabf65246837015197eecfa24b2213ed6a51a8974ae250fedd8d
Deleted: ed0fffdcdae5eb2c3a55549857a8be7fc8bc4241fb19ad714364cbfd7a56b22f
Deleted: 5c58979d73ae448df5af1d8142436d81116187a7633082650549c52c3a2418f0
         注意:为了从主机上移除image,请没有基于它的活动container。


猜你喜欢

转载自blog.csdn.net/ronggangzhao/article/details/43968425
今日推荐