您正在查看: DOCKER 分类下的文章

docker userguide_usingdocker

使用容器工作

在上一节的 docker 用户指南中,我们启动了我们的第一个容器。而后边的例子中我们使用 docker run 命令启动了两个容器

  • 与前台进行交互的容器

  • 以进程方式在后台运行的容器

在这个过程中,我们学习到了几个 Docker 命令:

  • docker ps 列出容器
  • docker logs 显示容器的标准输出
  • docker stop 停止正在运行的容器

提示:另一种学习 docker 命令的方式就是查看我们的 [交互式教程页面。]https://www.docker.com/tryit/

docker 客户端非常简单 。Docker 的每一项操作都是通过命令行来实现的,而每一条命令行都可以使用一系列的标识(flags)和参数。

# Usage:  [sudo] docker [flags] [command] [arguments] ..
# Example:
$ docker run -i -t ubuntu /bin/bash

让我们看看这个使用 docker version 命令的操作,它将返回当前安装的 Docker 客户端和进程的版本信息。

$ sudo docker version

这个命令不仅返回了您使用的 Docker 客户端和进程的版本信息,还返回了 GO 语言的版本信息( Docker的编程语言 )。

Client version: 0.8.0
Go version (client): go1.2

git commit (client): cc3a8c8
Server version: 0.8.0

git commit (server): cc3a8c8
Go version (server): go1.2

Last stable version: 0.8.0

查看一下 Docker 客户端都能做什么

我们可以通过只输入不附加任何参数的 docker 命令来运行 docker 二进制文件,这样我们就会查看到 Docker 客户端的所有命令选项。

$ sudo docker

会看到当前可用的所有命令行列表:

Commands:
 attach    Attach to a running container
 build     Build an image from a Dockerfile
 commit    Create a new image from a container's changes
 . . .

查看 Docker 命令用法

你可以更深入的去了解指定的 Docker 命令使用方法。

试着输入 Docker [command],这里会看到 docker 命令的使用方法:

$ sudo docker attach
Help output . . .

或者你可以通过在 docker 命令中使用 --help 标识(flags)

$ sudo docker images --help

这将返回所有的帮助信息和可用的标识(flags):

Usage: docker attach [OPTIONS] CONTAINER

Attach to a running container

  --no-stdin=false: Do not attach stdin
  --sig-proxy=true: Proxify all received signal to the process (even in non-tty mode)

注意:你可以点击[这里]https://docs.docker.com/reference/commandline/cli/ 来查看完整的 Docker 命令行列表和使用方法。

在Docker中运行一个web应用

到这里我们了解了更多关于 docker 客户端的知识,而现在我们需要将学习的焦点转移到重要的部分:运行多个容器。到目前为止我们发现运行的容器并没有一些什么特别的用处。让我们通过使用 docker 构建一个 web 应用程序来运行一个web应用程序来体验一下。

在这个 web 应用中,我们将运行一个 python Flask 应用。使用 docker run 命令。

$ sudo docker run -d -P training/webapp python app.py

让我们来回顾一下我们的命令都做了什么。我们指定两个标识(flags) -d-P 。我们已知是 -d 标识是让 docker 容器在后台运行。新的 -P 标识通知 Docker 将容器内部使用的网络端口映射到我们使用的主机上。现在让我们看看我们的 web 应用。

This image is a pre-built image we've created that contains a simple Python Flask web application.

我们指定了 training/web 镜像。我们创建容器的时候使用的是这个预先构建好的镜像,并且这个镜像已经包含了简单的 Python Flask web 应用程序。

最后,我们指定了我们容器要运行的命令: python app.py。这样我们的 web 应用就启动了。

注意:你可以在[命令参考]http://docs.docker.com/reference/commandline/cli/#run和[Docker run参考]http://docs.docker.com/reference/run/查看更多 docker run 命令细节

查看 WEB 应用容器

现在我们使用 docker ps 来查看我们正在运行的容器。

$ sudo docker ps -l
CONTAINER ID  IMAGE                   COMMAND       CREATED        STATUS        PORTS                    NAMES
bc533791f3f5  training/webapp:latest  python app.py 5 seconds ago  Up 2 seconds  0.0.0.0:49155->5000/tcp  nostalgic_morse

你可以看到我们在 docker ps 命令中指定了新的标识 -l。这样组合的 docker ps 命令会返回最后启动容器的详细信息。

注意:默认情况下,docker ps 命令只显示运行中的容器。如果你还想看已经停止的容器,请加上 -a 标示。

我们这里可以看到一些细节,与我们第一次运行 docker ps 命令的时候相比,这里多了一个 PORTS 列。

PORTS
0.0.0.0:49155->5000/tcp

我们通过在 docker run 中使用 -P 标示(flags) 来将我们 Docker 镜像内部容器端口暴露给主机。

提示:当我们学习如何构建镜像的时候,我们将了解更多关于如何开放 Docker 镜像端口。

在这种情况下,Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 49155 上。

Docker 能够很容易的配置和绑定网络端口。在最后一个例子中 -P 标识(flags)是 -p 5000 的缩写,它将会把容器内部的 5000 端口映射到本地 Docker 主机的高位端口上(这个端口的通常范围是 32768 至 61000)。我们也可以指定 -p 标识来绑定指定端口。举例:

$ sudo docker run -d -p 5000:5000 training/webapp python app.py

这将会把容器内部的 5000 端口映射到我们本地主机的 5000 端口上。你可能现在会问:为什么我们只使用 1对1端口映射的方式将端口映射到 Docker 容器, 而不是采用自动映射高位端口的方式?这里 1:1 映射方式能够保证映射到本地主机端口的唯一性。假设你想要测试两个 Python 应用程序,两个容器内部都绑定了端口5000,这样就没有足够的 Docker 的端口映射,你只能访问其中一个。

所以,现在我们打开浏览器访问端口49155。

png" alt="应用访问" />

我们的应用程序可以访问了!

注意:如果你在 OS X windows或者linux上使用 boot2docker 虚拟机,你需要获取虚拟机的 ip 来代替localhost 使用,你可以通过运行 boot2docker shell 来获取 ip。

$ boot2docker ip
The VM's Host only interface IP address is: 192.168.59.103

在这种情况下,你可以通过输入 http://192.168.59.103:49155 来访问上面的例子。

查看网络端口快捷方式

使用 docker ps 命令来会返回端口的映射是一种比较笨拙的方法。为此,Docker 提供了一种快捷方式: docker port ,使用 docker port 可以查看指定 (ID或者名字的)容器的某个确定端口映射到宿主机的端口号。

$ sudo docker port nostalgic_morse 5000
0.0.0.0:49155

在这种情况下,我们看到容器的 5000 端口映射到了宿主机的的 49155 端口。

###查看WEB应用程序日志

让我们看看我们的容器中的应用程序都发生了什么,这里我们使用学习到的另一个命令 docker logs 来查看。

$ sudo docker logs -f nostalgic_morse
* Running on http://0.0.0.0:5000/
10.0.2.2 - - [23/May/2014 20:16:31] "GET / HTTP/1.1" 200 -
10.0.2.2 - - [23/May/2014 20:16:31] "GET /favicon.ico HTTP/1.1" 404 -

这次我们添加了一个 -f 标识。 docker log 命令就像使用 tail -f 一样来输出容器内部的标准输出。这里我们从显示屏上可以看到应用程序使用的是 5000 端口并且能够查看到应用程序的访问日志。

查看WEB应用程序容器的进程

我们除了可以查看容器日志,我们还可以使用 docker top 来查看容器内部运行的进程:

$ sudo docker top nostalgic_morse
PID                 USER                COMMAND
854                 root                python app.py

这里我们可以看到 python app.py 在容器里唯一进程。

###检查WEB应用程序

最后,我们可以使用 docker inspect 来查看Docker的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。

$ sudo docker inspect nostalgic_morse

来让我们看下JSON的输出。

[{
    "ID": "bc533791f3f500b280a9626688bc79e342e3ea0d528efe3a86a51ecb28ea20",
    "Created": "2014-05-26T05:52:40.808952951Z",
    "Path": "python",
    "Args": [
       "app.py"
    ],
    "Config": {
       "Hostname": "bc533791f3f5",
       "Domainname": "",
       "User": "",
. . .

我们也可以针对我们想要的信息进行过滤,例如,返回容器的 IP 地址,如下:

$ sudo docker inspect -f '{{ .NetworkSettings.IPAddress }}' nostalgic_morse
172.17.0.5

###停止WEB应用容器

现在,我们的WEB应用程序处于工作状态。现在我们通过使用 docker stop 命令来停止名为 nostalgic_morse 的容器:

$ sudo docker stop nostalgic_morse
nostalgic_morse

现在我们使用 docker ps 命令来检查容器是否停止了。

$ sudo docker ps -l

###重启WEB应用容器

哎呀!刚才你停止了另一个开发人员所使用的容器。这里你现在有两个选择:您可以创建一个新的容器或者重新启动旧的。让我们启动我们之前的容器:

$ sudo docker start nostalgic_morse
nostalgic_morse

现在再次运行 docker ps -l 来查看正在运行的容器,或者通过URL访问来查看我们的应用程序是否响应。

注意:也可以使用 docker restart 命令来停止容器然后再启动容器。

###移除WEB应用容器

你的同事告诉你他们已经完成了在容器上的工作,不在需要容器了。让我们使用 docker rm 命令来删除它:

$ sudo docker rm nostalgic_morse
Error: Impossible to remove a running container, please stop it first or use -f
2014/05/24 08:12:56 Error: failed to remove one or more containers

发生了什么?实际上,我们不能删除正在运行的容器。这避免你意外删除了正在使用并且运行中的容器。让我们先停止容器,然后再试一试删除容器。

$ sudo docker stop nostalgic_morse
nostalgic_morse
$ sudo docker rm nostalgic_morse
nostalgic_morse

现在我们停止并删除了容器。

注意:删除容器是最后一步!

###下一步

直到现在,我们使用的镜像都是从Docker Hub下载的。接下来,我们学习创建和分享镜像。

阅读使用镜像

docker userguide_dockerizing

docker 应用 "hello World"

docker 允许你在容器内运行应用程序, 使用 docker run 命令来在容器内运行一个应用程序。

##Hello world

现在让我们来试试

$ sudo docker run ubuntu:14.04 /bin/echo 'Hello world'
Hello world

刚才你启动了你的第一个容器!

那么刚才发生了什么? 我们逐步来分析 docker run 命令做了哪些事情。

首先,我们指定了 docker 二进制执行文件和我们想要执行的命令 rundocker run 组合会运行容器。

接下来,我们指定一个镜像: ubuntu 14.04 。这是我们运行容器的来源。 Docker 称此为镜像。在本例中,我们使用一个 Ubuntu 14.04 操作系统镜像。

当你指定一个镜像,Docker 首先会先从你的 Docker 本地主机上查看镜像是否存在,如果没有,Docker 就会从镜像仓库 [Docker Hub]https://hub.docker.com/ 下载公共镜像。

接下来,我们告诉 Docker 在容器内我们需要运行什么命令:

/bin/echo 'Hello world'

当我们的容器启动了 Docker 创建的新的 Ubuntu 14.04 环境,并在容器内执行 /bin/echo 命令后。我们会在命令行看到如下结果:

hello world

那么,我们创建容器之后会发生什么呢? 当命令状态状态处于激活状态的时候 Docker 容器就会一直运行。这里只要 "hello world" 被输出,容器就会停止。

一个交互式的容器

让我们尝试再次运行 docker run,这次我们指定一个新的命令来运行我们的容器。

$ sudo docker run -t -i ubuntu:14.04 /bin/bash
root@af8bae53bdd3:/#

我们继续指定了 docker run 命令,并启动了 ubuntu:14.04 镜像。但是我们添加了两个新的标识(参数flags): -t-i-t 表示在新容器内指定一个伪终端或终端,-i表示允许我们对容器内的 (STDIN) 进行交互。

我们在容器内还指定了一个新的命令: /bin/bash 。这将在容器内启动 bash shell

所以当容器(container)启动之后,我们会获取到一个命令提示符:

root@af8bae53bdd3:/#

我们尝试在容器内运行一些命令:

root@af8bae53bdd3:/# pwd
/
root@af8bae53bdd3:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var

你可以看到我们运行 pwd 来显示当前目录,这时候显示的是我们的根目录。我们还列出了根目录的文件列表,通过目录列表我们看出来这是一个典型的 linux 文件系统。

你可以在容器内随便的玩耍,你可以使用 exit 命令或者使用 CTRL-D 来退出容器。

root@af8bae53bdd3:/# exit

与我们之前的容器一样,一旦你的 Bash shell 退出之后,你的容器就停止了。

Hello world 守护进程

现在当一个容器运行完一个命令后就会退出,但是这样看起来有时候并不好。让我们创建一个容器以进程的方式运行,就像大多数我们运行在 Docker 中的应用程序一样,这里我们可以使用 docker run 命令:

$ sudo docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147

等等,怎么回事?我们的 “hello world” 输出呢?让我们看看它是怎么运行的。这个命令看起来应该很熟悉.我们运行docker run ,但是我们指定了一个 -d 标识。-d 标识告诉 docker 在容器内以后台进程模式运行。

我们也指定了一个相同的镜像: ubuntu:14.04

最终,我们指定命令行运行:

/bin/sh -c "while true; do echo hello world; sleep 1; done"

这是一个忠实的 hello world 进程:一个脚本会一直输出 "hello world"

为什么我们看不到的一大堆的 "hello world" ? 而是docker返回的一个很长的字符串:

1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147

这个长的字符串叫做容器ID(container ID)。它对于每一个容器来说都是唯一的,所以我们可以使用它。

注意:容器 ID 是有点长并且非常的笨拙,稍后我们会看到一个短点的 ID,某些方面来说它是容器 ID 的简化版。

我们可以根据容器 ID 查看 "hello world" 进程发生了什么

首先,我们要确保容器正在运行。我们可以使用 docker ps 命令来查看。docker ps 命令可以查询 docker 进程的所有容器。

$ sudo docker ps
CONTAINER ID  IMAGE         COMMAND               CREATED        STATUS       PORTS NAMES
1e5535038e28  ubuntu:14.04  /bin/sh -c 'while tr  2 minutes ago  Up 1 minute        insane_babbage

这里我们看到了以进程模式运行的容器。docker ps 命令会返回一些有用的信息,这里包括一个短的容器 ID:1e5535038e28

我们还可以查看到构建容器时使用的镜像, ubuntu:14.04,当命令运行之后,容器的状态随之改变并且被系统自动分配了名称 insane_babbage

注意:当容器启动的时候 Docker 会自动给这些容器命名,稍后我们可以看到我们如何给容器指定名称。

好了,现在我们知道它正在运行。但是我们能要求它做什么呢?做到这,我们需要在我们容器内使用 docker logs 命令。让我们使用容器的名称来填充 docker logs 命令。

$ sudo docker logs insane_babbage
hello world
hello world
hello world
. . .

docker logs 命令会查看容器内的标准输出:这个例子里输出的是我们的命令 hello world

太棒了!我们的 docker 进程是工作的,并且我们创建了我们第一个 docker 应用。

现在我们已经可以创建我们自己的容器了,让我们处理正在运行的进程容器并停止它。我们使用 docker stop 命令来停止容器 。

$ sudo docker stop insane_babbage
insane_babbage

docker stop 命令会通知 Docker 停止正在运行的容器。如果它成功了,它将返回刚刚停止的容器名称。

让我们通过 docker ps 命令来检查它是否还工作。

$ sudo docker ps
CONTAINER ID  IMAGE         COMMAND               CREATED        STATUS       PORTS NAMES

太好了,我们的容器停止了。

###下一步

现在我们看到了Docker 是多么简单,让我们学习如何做一些更高级的任务。

去阅读使用容器

docker userguide_dockerlinks

连接容器

在使用 docker 部分, 我们谈到了如何通过网络端口来访问运行在 docker 容器内的服务。这是与docker容器内运行应用程序交互的一种方法。在本节中,我们打算通过端口连接到一个docker容器,并向您介绍容器连接概念。

###网络端口映射

在使用docker部分,我们创建了一个python应用的容器。

$ sudo docker run -d -P training/webapp python app.py

注:容器有一个内部网络和IP地址(在使用Docker部分我们使用docker inspect命令显示容器的IP地址)。Docker可以有各种网络配置方式。你可以再这里学到更多docker网络信息。

我们使用-P标记创建一个容器,将容器的内部端口随机映射到主机的高端口49000到49900。这时我们可以使用docker ps来看到端口5000绑定主机端口49155。

$ sudo docker ps nostalgic_morse
CONTAINER ID  IMAGE                   COMMAND       CREATED        STATUS        PORTS                    NAMES
bc533791f3f5  training/webapp:latest  python app.py 5 seconds ago  Up 2 seconds  0.0.0.0:49155->5000/tcp  nostalgic_morse

我们也可以使用-p标识来指定容器端口绑定到主机端口

$ sudo docker run -d -p 5000:5000 training/webapp python app.py

我们看这为什么不是一个好的主意呢?因为它限制了我们容器的一个端口。

我们还有很多设置-p标识的方法。默认-p标识会绑定本地主机上的指定端口。并且我们可以指定绑定的网络地址。举例设置localhost

$ sudo docker run -d -p 127.0.0.1:5001:5002 training/webapp python app.py

这将绑定容器内部5002端口到主机的localhost或者127.0.0.1的5001端口。

如果要绑定容器端口5002到宿主机动态端口,并且让localhost访问,我们可以这样做:

$ sudo docker run -d -p 127.0.0.1::5002 training/webapp python app.py

我们也可以绑定UDP端口,我们可以在后面添加/udp,举例:

$ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py

我们可以使用docker port快捷方式来绑定我们的端口,这有助于向我们展示特定的端口。例如我们绑定localhost,如下是docker port输出:

$ docker port nostalgic_morse 5000
127.0.0.1:49155

注:-p可以使用多次配置多个端口。

###Docker容器连接

端口映射并不是唯一把docker连接到另一个容器的方法。docker有一个连接系统允许将多个容器连接在一起,共享连接信息。docker连接会创建一个父子关系,其中父容器可以看到子容器的信息。

###容器命名

执行此连接需要依靠你的docker的名字,这里我们可以看到当我们创建每一个容器的时候,它都会自动被命名。事实上我们已经熟悉了老的nostalgic_morse指南。你也可以自己命名容器。这种命名提供了两个有用的功能:

  • 1.给容器特定的名字使你更容易记住他们,例如:命名web应用程序为web容器。
  • 2.它为docker提供一个参考,允许其他容器引用,举例连接web容器到db容器。

你可以使用--name标识来命名容器,举例:

$ sudo docker run -d -P --name web training/webapp python app.py

我们可以看到我们启动了的容器,就是我们使用--name标识命名为web的容器。我们可以使用docker ps命令来查看容器名称。

$ sudo docker ps -l
CONTAINER ID  IMAGE                  COMMAND        CREATED       STATUS       PORTS                    NAMES
aed84ee21bde  training/webapp:latest python app.py  12 hours ago  Up 2 seconds 0.0.0.0:49154->5000/tcp  web

我们也可以使用docker inspect来返回容器名字。

$ sudo docker inspect -f "{{ .Name }}" aed84ee21bde
/web

注:容器的名称必须是唯一的。这意味着你只能调用一个web容器。如果你想使用重复的名称来命名容器,你需要使用docker rm命令删除以前的容器。在容器停止后删除。

###容器连接

连接允许容器之间可见并且安全地进行通信。使用--link创建连接。我们创建一个新容器,这个容器是数据库

$ sudo docker run -d --name db training/postgres

这里我们使用training/postgres容器创建一个新的容器。容器是PostgreSQL数据库

现在我们创建一个web容器来连接db容器。

$ sudo docker run -d -P --name web --link db:db training/webapp python app.py

这将使我们的web容器和db容器连接起来。--link的形式

--link name:alias

name是我们连接容器的名字,alias是link的别名。让我们看如何使用alias。

让我们使用docker ps来查看容器连接.

$ docker ps
CONTAINER ID  IMAGE                     COMMAND               CREATED             STATUS             PORTS                    NAMES
349169744e49  training/postgres:latest  su postgres -c '/usr  About a minute ago  Up About a minute  5432/tcp                 db
aed84ee21bde  training/webapp:latest    python app.py         16 hours ago        Up 2 minutes       0.0.0.0:49154->5000/tcp  db/web,web

我们可以看到我们命名的容器,dbweb,我们还在名字列中可以看到web容器也显示db/web。这告诉我们web容器和db容器是父/子关系。

我们连接容器做什么?我们发现连接的两个容器是父子关系。这里的父容器是db可以访问子容器web。为此docker在容器之间打开一个安全连接隧道不需要暴露任何端口在容器外部。你会注意到当你启动db容器的时候我们没有使用-P或者-p标识。我们连接容器的时候我们不需要通过网络给PostgreSQL数据库开放端口。

Docker在父容器中开放子容器连接信息有两种方法:

  • 环境变量
  • 更新/etc/hosts文件。

让我们先看看docker的环境变量。我们运行env命令来查看列表容器的环境变量。

$ sudo docker run --rm --name web2 --link db:db training/webapp env
    . . .
    DB_NAME=/web2/db
    DB_PORT=tcp://172.17.0.5:5432
    DB_PORT_5000_TCP=tcp://172.17.0.5:5432
    DB_PORT_5000_TCP_PROTO=tcp
    DB_PORT_5000_TCP_PORT=5432
    DB_PORT_5000_TCP_ADDR=172.17.0.5
    . . .

注:这些环境变量只设置顶一个进程的容器。同样,一些守护进程(例如sshd)进行shell连接时就会去除。

我们可以看到docker为我们的数据库容器创建了一系列环境变量。每个前缀变量是DB_填充我们指定的别名。如果我们的别名是db1,前缀别名就是DB1_。您可以使用这些环境变量来配置您的应用程序连接到你的数据库db容器。该连接时安全、私有的,只能在web容器和db容器之间通信。

docker除了环境变量,可以添加信息到父主机的/etc/hosts

root@aed84ee21bde:/opt/webapp# cat /etc/hosts
172.17.0.7  aed84ee21bde
. . .
172.17.0.5  db

这里我们可以看到两个主机项。第一项是web容器用容器ID作为主机名字。第二项是使用别名引用IP地址连接数据库容器。现在我们试试ping这个主机:

root@aed84ee21bde:/opt/webapp# apt-get install -yqq inetutils-ping
root@aed84ee21bde:/opt/webapp# ping db
PING db (172.17.0.5): 48 data bytes
56 bytes from 172.17.0.5: icmp_seq=0 ttl=64 time=0.267 ms
56 bytes from 172.17.0.5: icmp_seq=1 ttl=64 time=0.250 ms
56 bytes from 172.17.0.5: icmp_seq=2 ttl=64 time=0.256 ms

注:我们不得不安装ping,因为容器内没有它。

我们使用ping命令来pingdb容器,使用它解析到127.17.0.5主机。我们可以利用这个主机项配置应用程序来使用我们的db容器。

注:你可以使用一个父容器连接多个子容器。例如,我们可以有多个web容器连接到我们的db数据库容器。

###下一步

现在我们已经学会如何连接容器了,下一步我们学习融合管理数据、卷标和如果在容器内挂载。

阅读管理容器数据

docker userguide_dockerrepos

使用docker Hub

现在你已经学习了如何利用命令行在本地运行docker,还学习了如何拉取镜像用于从现成的镜像中构建容器,并且还学习了如何创建自己的镜像。

接下来,你将会学到如何利用[Docker Hub]https://hub.docker.com简化和提高你的Docker工作流程。

[Docker Hub]https://hub.docker.com是一个由Docker公司负责维护的公共注册中心,它包含了超过15,000个可用来下载和构建容器的镜像,并且还提供认证、工作组结构、工作流工具(比如webhooks)、构建触发器以及私有工具(比如私有仓库可用于存储你并不想公开分享的镜像)。

###Docker命令和Docker Hub

Docker通过docer searchpullloginpush等命令提供了连接Docker Hub服务的功能,本页将展示这些命令如何工作的。

###账号注册和登陆

一般,你需要先在docker中心创建一个账户(如果您尚未有)。你可以直接在[Docker Hub]https://hub.docker.com创建你的账户,或通过运行:

$ sudo docker login

这将提示您输入用户名,这个用户名将成为你的公共存储库的命名空间名称。如果你的名字可用,docker会提示您输入一个密码和你的邮箱,然后会自动登录到Docker Hub,你现在可以提交和推送镜像到Docker Hub的你的存储库。

注:你的身份验证凭证将被存储在你本地目录的.dockercfg文件中。

###搜索镜像

你可以通过使用搜索接口或者通过使用命令行接口在Docker Hub中搜索,可对镜像名称、用户名或者描述等进行搜索:

$ sudo docker search centos
NAME           DESCRIPTION                                     STARS     OFFICIAL   TRUSTED
centos         Official CentOS 6 Image as of 12 April 2014     88
tianon/centos  CentOS 5 and 6, created using rinse instea...   21
...

这里你可以看到两个搜索的示例结果:centostianon/centos。第二个结果是从名为tianon/的用户仓储库搜索到的,而第一个结果centos没有用户空间这就意味着它是可信的顶级命名空间。/字符分割用户镜像和存储库的名称。

当你发现你想要的镜像时,便可以用docker pull <imagename>来下载它。

$ sudo docker pull centos
Pulling repository centos
0b443ba03958: Download complete
539c0211cd76: Download complete
511136ea3c5a: Download complete
7064731afe90: Download complete

现在你有一个镜像,基于它你可以运行容器。

###向Docker Hub贡献

任何人都可以从Docker Hub仓库下载镜像,但是如果你想要分享你的镜像,你就必须先注册,就像你在第一部分的docker用户指南看到的一样。

###推送镜像到Docker Hub

为了推送到仓库的公共注册库中,你需要一个命名的镜像或者将你的容器提到为一个命名的镜像,正像这里我们所看到的。

你可以将此仓库推送到公共注册库中,并以镜像名字或者标签来对其进行标记。

$ sudo docker push yourname/newimage

镜像上传之后你的团队或者社区的人都可以使用它。

###Docker Hub特征

让我们再进一步看看Docker Hub的特色,[这里]http://docs.docker.com/docker-hub/你可以看到更多的信息。

  • 私有仓库
  • 组织和团队
  • 自动构建
  • Webhooks

###私有仓库

有时候你不想公开或者分享你的镜像,所以Docker Hub允许你有私有仓库,你可以在[这里]https://registry.hub.docker.com/plans/登录设置它。

###组织和机构

私人仓库一个较有用的地方在于你可以将仓库分享给你团队或者你的组织。Docker Hub支持创建组织,这样你可以和你的同事来管理你的私有仓库,在[这里]https://registry.hub.docker.com/account/organizations/你可以学到如何创建和管理一个组织。

###自动构建

自动构建功能会自动从[github]https://www.github.com/和[BitBucket]http://bitbucket.com/直接将镜像构建或更新至Docker Hub,通过为Github或Bitbucket的仓库添加一个提交的hook来实现,当你推送提交的时候就会触发构建和更新。

设置一个自动化构建你需要:

  • 1.创建一个[Docker Hub]https://hub.docker.com/账户并且登陆
  • 2.通过[Link Accounts]https://registry.hub.docker.com/account/accounts/菜单连接你的GitHub或者BitBucket
  • 3.[配置自动化构建]https://registry.hub.docker.com/builds/add/
  • 4.选择一个包含Dockerfile的Github或BitBucket项目
  • 5.选择你想用于构建的分支(默认是master分支)
  • 6.给自动构建创建一个名称
  • 7.指定一个Docker标签来构建
  • 8.指定Dockerfile的路径,默认是/

一旦配置好自动构建,在几分钟内就会自动触发构建,你就会在[Docker Hub]https://hub.docker.com/仓库源看到你新的构建,并且它将会和你的Github或者BitBucket保持同步更新直到你解除自动构建。

如果你想看到你自动化构建的状态,你可以去你的Docker Hub[自动化构建页面]https://registry.hub.docker.com/builds/,它将会想你展示你构建的状态和构建历史。

一旦你创建了一个自动化构建,你可以禁用或删除它。但是,你不能通过docker push推送一个自动化构建,而只能通过在Github或者BitBucket提交你的代码来管理它。

你可以在一个仓库中创建多个自动构建,配置它们只指定的Dockerfile或Git 分支。

###构建触发器

自动构建也可以通过Docker Hub的Url来触发,这样你就可以通过命令重构自动构建镜像。

###Webhooks

webhooks属于你的存储库的一部分,当一个镜像更新或者推送到你的存储库时允许你触发一个事件。当你的镜像被推送的时候,webhook可以根据你指定的url和一个有效的Json来递送。

###下一步

去使用Docker!

docker userguide_dockervolumes

管理容器数据

到目前为止,我们已经介绍了docker的一些基本概念,了解了如何使用docker镜像,以及容器之间如何通过网络连接。本节,我们来讨论如何管理容器和容器间的共享数据。

接下来,我们将主要介绍Docker管理数据的两种主要的方法:

  • 数据卷
  • 数据卷容器

###数据卷

数据卷是指在存在于一个或多个容器中的特定目录,此目录能够绕过[Union File System]http://docs.docker.com/terms/layer/#ufs-def提供一些用于持续存储或共享数据的特性。

  • 数据卷可在容器之间共享或重用
  • 数据卷中的更改可以直接生效
  • 数据卷中的更改不会包含在镜像的更新中
  • 数据卷的生命周期一直持续到没有容器使用它为止

###添加一个数据卷

你可以在docker run命令中使用-v标识来给容器内添加一个数据卷,你也可以在一次docker run命令中多次使用-v标识挂载多个数据卷。现在我们在web容器应用中创建单个数据卷。

$ sudo docker run -d -P --name web -v /webapp training/webapp python app.py

这会在容器内部创建一个新的卷/webapp

注:类似的,你可以在Dockerfile中使用VOLUME指令来给创建的镜像添加一个或多个数据卷。

###挂载一个主机目录作为卷

使用-v,除了可以创建一个数据卷,还可以挂载本地主机目录到容器中:

$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py

这将会把本地目录/src/webapp挂载到容器的/opt/webapp目录。这在做测试时是非常有用的,例如我们可以挂载宿主机的源代码到容器内部,这样我们就可以看到改变源代码时的应用时如何工作的。宿主机上的目录必须是绝对路径,如果目录不存在docker会自动创建它。

注:出于可移植和分享的考虑,这种方法不能够直接在Dockerfile中实现。作为宿主机目录——其性质——是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录。

docker默认情况下是对数据卷有读写权限,但是我们通过这样的方式让数据卷只读:

$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py

这里我们同样挂载了/src/webapp目录,只是添加了ro选项来限制它只读。

将宿主机上的特定文件挂载为数据卷

除了能挂载目录外,-v标识还可以将宿主机的一个特定文件挂载为数据卷:

$ sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash

上述命令会在容器中运行一个bash shell,当你退出此容器时在主机上也能够看到容器中bash的命令历史。

注:很多文件编辑工具如vised --in-place会导致inode change。Docker v1.1.0之后的版本,会产生一个错误:“sed cannot rename ./sedKdJ9Dy: Device or resource busy”。这种情况下如果想要更改挂载的文件,最好是直接挂载它的父目录。

###创建、挂载数据卷容器

如果你想要容器之间数据共享,或者从非持久化容器中使用一些持久化数据,最好创建一个指定名称的数据卷容器,然后用它来挂载数据。

让我们创建一个指定名称的数据卷容器:

$ sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres

你可以在另外一个容器使用--volumes-from标识,通过刚刚创建的数据卷容器来挂载对应的数据卷。

$ sudo docker run -d --volumes-from dbdata --name db1 training/postgres

可以将对应的数据卷挂载到更多的容器中:

$ sudo docker run -d --volumes-from dbdata --name db2 training/postgres

当然,您也可以对一个容器使用多个--volumes-from标识,来将多个数据卷桥接到这个容器中。

数据卷容器是可以进行链式扩展的,之前的dbdata数据卷依次挂载到了dbdata 、db1和db2容器,我们还可以使用这样的方式来将数据卷挂载到新的容器db3:

$ sudo docker run -d --name db3 --volumes-from db1 training/postgres

即使你删除所有de 挂载了数据卷dbdata的容器(包括最初的dbdata容器和后续的db1db2),数据卷本身也不会被删除。要删在磁盘上删除这个数据卷,只能针对最后一个挂载了数据卷的容器显式地调用docker rm -v命令。这种方式可使你在容器之间方便的更新和迁移数据。

###备份、恢复或者迁移数据卷

数据卷还可以用来备份、恢复或迁移数据。为此我们使用--volumes-from参数来创建一个挂载数据卷的容器,像这样:

$ sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata

这里我们启动了一个挂载dbdata卷的新容器,并且挂载了一个本地目录作为/backup卷。最后,我们通过使用tar命令将dbdata卷的内容备份到容器中的/backup目录下的backup.tar文件中。当命令完成或者容器停止,我们会留下我们的dbdata卷的备份。

然后,你可以在同一容器或在另外的容器中恢复此数据。创建一个新的容器

$ sudo docker run -v /dbdata --name dbdata2 ubuntu /bin/bash

然后在新的容器中的数据卷里un-tar此备份文件。

$ sudo docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar

你可以对熟悉的目录应用此技术,来测试自动备份、迁移和恢复。

###下一步

本小节中,我们学习了关于数据卷和数据卷容器使用方法。接下来,我们要看看如何使用Docker Hub服务,包括自动化构建和私人仓库。

阅读使用Docker Hub