Fork me on GitHub

轻量级虚拟化Docker

一、Docker基本介绍

Docker发端于一个名为dotcloud的开源项目;随着编写者不断挖掘它的潜力,它迅速变成了一个炙手可热的项目。它由GO语言编写的,并且只支持Linux。它基于Linux容器(LxC)来创建一个虚拟环境。Docker不会通过建立独有的操作系统、进程和对硬件进行模拟来创建属于自己的虚拟机。请注意:虚拟环境VE(Virtual Environment)和虚拟机(VM)很不一样。虚拟机是由虚拟工具或者模拟器(HyperV 、VMWare等)创建的,是一个全镜像的主机源,其中包括操作系统、硬盘调整、网络和虚拟进程。过于臃肿的结构吃掉了大量的硬盘空间同时拖慢了运行和开机速度。

一台VE就像是轻量级的VM,它在已有的内核关于底层硬件的镜像上建立一个可以用来运行应用的‘容器’。它也可以用来创建操作系统,因为所谓的操作系统也不过是一个跑在内核上的应用而已。可以把Docker想象成LxC的一个强化版,只是具有以下LxC所不具有的特性:

LxC是一个Linux提供的收容功能接口,通过LxC提供的API和简单的工具,使得Linux用户可以简单的创建和管理系统或者应用的空间。LXC容器

Docker通常用于如下场景:

web应用的自动化打包和发布;
自动化测试和持续集成、发布;
在服务型环境中部署和调整数据库或其他的后台应用;
从头编译或者扩展现有的OpenShiftCloud Foundry平台来搭建自己的PaaS环境。

Docker实践解决方案:

参考文档:

二、docker 安装配置

2.1、Docker install

Docker的安装非常简单,这里只介绍Ubuntu 14.04的安装,其他发行版本的安装可以参考官网手册。

$ sudo apt-get update
$ sudo apt-get install docker.io
$ sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker

获取当前docker版本

$ sudo docker version
Client version: 1.1.1
Client API version: 1.13
Go version (client): go1.2.1
Git commit (client): bd609d2
Server version: 1.1.1
Server API version: 1.13
Go version (server): go1.2.1
Git commit (server): bd609d2

三、Docker images

3.1、Search index images

$ sudo docker search ubuntu

3.2、Pull images

$ sudo docker pull ubuntu # remote index 获取ubuntu官方镜像
$ sudo docker images # 查看当前镜像列表
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              13.10               5e019ab7bf6d        3 weeks ago         180 MB
ubuntu              saucy               5e019ab7bf6d        3 weeks ago         180 MB
ubuntu              12.04               74fe38d11401        3 weeks ago         209.6 MB
... ...

3.3、Running an interactive shell

$ sudo docker run -i -t ubuntu:14.04 /bin/bash

注: ubuntu会有多个版本,通过指定tag来启动特定的版本[image]:[tag]

$ sudo docker ps # 查看当前运行的容器, ps -a列出当前系统所有的容器
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
6c9129e9df10        ubuntu:14.04        /bin/bash           6 minutes ago       Up 6 minutes                            cranky_babbage

3.4、相关快捷键

四、docker常用命令

4.1、docker help

$ sudo docker   # docker命令帮助
Usage: docker [OPTIONS] COMMAND [arg...]
 -H=[unix:///var/run/docker.sock]: tcp://host:port to bind/connect to or unix://path/to/socket to use

A self-sufficient runtime for linux containers.

Commands:
    attach    Attach to a running container                 # 当前shell下attach连接指定运行镜像
    build     Build an image from a Dockerfile              # 通过Dockerfile定制镜像
    commit    Create a new image from a container's changes # 提交当前容器为新的镜像
    cp        Copy files/folders from the containers filesystem to the host path
              # 从容器中拷贝指定文件或者目录到宿主机中
    diff      Inspect changes on a container's filesystem   # 查看docker容器变化
    events    Get real time events from the server          # 从docker服务获取容器实时事件
    export    Stream the contents of a container as a tar archive   
              # 导出容器的内容流作为一个tar归档文件[对应import]
    history   Show the history of an image                  # 展示一个镜像形成历史
    images    List images                                   # 列出系统当前镜像
    import    Create a new filesystem image from the contents of a tarball  
              # 从tar包中的内容创建一个新的文件系统映像[对应export]
    info      Display system-wide information               # 显示系统相关信息
    inspect   Return low-level information on a container   # 查看容器详细信息
    kill      Kill a running container                      # kill指定docker容器
    load      Load an image from a tar archive              # 从一个tar包中加载一个镜像[对应save]
    login     Register or Login to the docker registry server   
              # 注册或者登陆一个docker源服务器
    logs      Fetch the logs of a container                 # 输出当前容器日志信息
    port      Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
              # 查看映射端口对应的容器内部源端口
    pause     Pause all processes within a container        # 暂停容器
    ps        List containers                               # 列出容器列表
    pull      Pull an image or a repository from the docker registry server
              # 从docker镜像源服务器拉取指定镜像或者库镜像
    push      Push an image or a repository to the docker registry server
              # 推送指定镜像或者库镜像至docker源服务器
    restart   Restart a running container                   # 重启运行的容器
    rm        Remove one or more containers                 # 移除一个或者多个容器
    rmi       Remove one or more images                 
              # 移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或-f强制删除]
    run       Run a command in a new container
              # 在一个新的容器中运行一个命令
    save      Save an image to a tar archive                # 保存一个镜像为一个tar包[对应load]
    search    Search for an image in the docker index       # 在docker index中搜索镜像
    start     Start a stopped containers                    # 启动容器
    stop      Stop a running containers                     # 停止容器
    tag       Tag an image into a repository                # 给源中镜像打标签
    top       Lookup the running processes of a container   # 查看容器中运行的进程信息
    unpause   Unpause a paused container                    # 取消暂停容器
    version   Show the docker version information           # 查看docker版本号
    wait      Block until a container stops, then print its exit code   
              # 截取容器停止时的退出状态值

docker选项帮助

$ sudo docker --help
Usage of docker:
  --api-enable-cors=false                Enable CORS headers in the remote API                      # 远程API中开启CORS头
  -b, --bridge=""                        Attach containers to a pre-existing network bridge         # 桥接网络
                                           use 'none' to disable container networking
  --bip=""                               Use this CIDR notation address for the network bridge's IP, not compatible with -b
                                         # 和-b选项不兼容,具体没有测试过
  -d, --daemon=false                     Enable daemon mode                                         # daemon模式
  -D, --debug=false                      Enable debug mode                                          # debug模式
  --dns=[]                               Force docker to use specific DNS servers                   # 强制docker使用指定dns服务器
  --dns-search=[]                        Force Docker to use specific DNS search domains            # 强制docker使用指定dns搜索域
  -e, --exec-driver="native"             Force the docker runtime to use a specific exec driver     # 强制docker运行时使用指定执行驱动器
  -G, --group="docker"                   Group to assign the unix socket specified by -H when running in daemon mode
                                           use '' (the empty string) to disable setting of a group
  -g, --graph="/var/lib/docker"          Path to use as the root of the docker runtime              # 容器运行的根目录路径
  -H, --host=[]                          The socket(s) to bind to in daemon mode                    # daemon模式下docker指定绑定方式[tcp or 本地socket]
                                           specified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.
  --icc=true                             Enable inter-container communication                       # 跨容器通信
  --ip="0.0.0.0"                         Default IP address to use when binding container ports     # 指定监听地址,默认所有ip
  --ip-forward=true                      Enable net.ipv4.ip_forward                                 # 开启转发
  --iptables=true                        Enable Docker's addition of iptables rules                 # 添加对应iptables规则
  --mtu=0                                Set the containers network MTU                             # 设置网络mtu
                                           if no value is provided: default to the default route MTU or 1500 if no default route is available
  -p, --pidfile="/var/run/docker.pid"    Path to use for daemon PID file                            # 指定pid文件位置
  -r, --restart=true                     Restart previously running containers                      # 重新启动以前运行的容器                     
  -s, --storage-driver=""                Force the docker runtime to use a specific storage driver  # 强制docker运行时使用指定存储驱动
  --selinux-enabled=false                Enable selinux support                                     # 开启selinux支持
  --storage-opt=[]                       Set storage driver options                                 # 设置存储驱动选项
  --tls=false                            Use TLS; implied by tls-verify flags                       # 开启tls
  --tlscacert="/root/.docker/ca.pem"     Trust only remotes providing a certificate signed by the CA given here
  --tlscert="/root/.docker/cert.pem"     Path to TLS certificate file                               # tls证书文件位置
  --tlskey="/root/.docker/key.pem"       Path to TLS key file                                       # tls key文件位置
  --tlsverify=false                      Use TLS and verify the remote (daemon: verify client, client: verify daemon) # 使用tls并确认远程控制主机
  -v, --version=false                    Print version information and quit                         # 输出docker版本信息

官方镜像源地址:registry.hub.docker.com

$ sudo docker search

Usage: docker search TERM

Search the docker index for images      # 从docker镜像主页搜索镜像

  --automated=false    Only show automated builds
  --no-trunc=false     Don't truncate output
  -s, --stars=0        Only displays with at least xxx stars

示例:

$ sudo docker search -s 100 ubuntu      
# 查找star数至少为100的镜像,找出只有官方镜像start数超过100,默认不加s选项找出所有相关ubuntu镜像
NAME      DESCRIPTION                  STARS     OFFICIAL   AUTOMATED
ubuntu    Official Ubuntu base image   425       [OK]       

4.1.2、docker info

$ sudo docker info 
Containers: 7                       # 容器个数
Images: 102                         # 镜像个数
Storage Driver: aufs                # 存储驱动,默认aufs
 Root Dir: /var/lib/docker/aufs     # 根目录
 Dirs: 116
Execution Driver: native-0.2        # 执行驱动
Kernel Version: 3.13.0-24-generic
WARNING: No swap limit support

4.1.3、docker pull && docker push

$ sudo docker pull                  # pull拉取镜像

Usage: docker pull NAME[:TAG]

Pull an image or a repository from the registry

$ sudo docker push                  # push推送指定镜像

Usage: docker push NAME[:TAG]

Push an image or a repository to the registry

示例:

$ sudo docker pull ubuntu           # 下载官方ubuntu docker镜像,默认下载所有ubuntu官方库镜像
$ sudo docker pull ubuntu:14.04     # 下载指定版本ubuntu官方镜像
$ sudo docker push 192.168.0.100:5000/ubuntu
# 推送镜像库到私有源[可注册docker官方账户,推送到官方自有账户]
$ sudo docker push 192.168.0.100:5000/ubuntu:14.04 
# 推送指定镜像到私有源

4.1.4、docker images

列出当前系统镜像

$ sudo docker images -h

Usage: docker images [OPTIONS] [NAME]

List images

  -a, --all=false      Show all images (by default filter out the intermediate image layers)
  # -a显示当前系统的所有镜像,包括过渡层镜像,默认docker images显示最终镜像,不包括过渡层镜像
  -f, --filter=[]      Provide filter values (i.e. 'dangling=true')
  --no-trunc=false     Don't truncate output
  -q, --quiet=false    Only show numeric IDs

示例:

$ sudo docker images            # 显示当前系统镜像,不包括过渡层镜像
$ sudo docker images -a         # 显示当前系统所有镜像,包括过渡层镜像
$ sudo docker images ubuntu     # 显示当前系统docker ubuntu库中的所有镜像
REPOSITORY                 TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu                     12.04               ebe4be4dd427        4 weeks ago         210.6 MB
ubuntu                     14.04               e54ca5efa2e9        4 weeks ago         276.5 MB
ubuntu                     14.04-ssh           6334d3ac099a        7 weeks ago         383.2 MB

4.1.5、docker rmi

删除一个或者多个镜像

$ sudo docker rmi

Usage: docker rmi IMAGE [IMAGE...]

Remove one or more images

  -f, --force=false    Force removal of the image       # 强制移除镜像不管是否有容器使用该镜像
  --no-prune=false     Do not delete untagged parents   # 不要删除未标记的父镜像

4.1.6、docker run

$ sudo docker run 

Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Run a command in a new container

  -a, --attach=[]            Attach to stdin, stdout or stderr.
  -c, --cpu-shares=0         CPU shares (relative weight)                       # 设置cpu使用权重
  --cidfile=""               Write the container ID to the file                 # 把容器id写入到指定文件
  --cpuset=""                CPUs in which to allow execution (0-3, 0,1)        # cpu绑定
  -d, --detach=false         Detached mode: Run container in the background, print new container id # 后台运行容器
  --dns=[]                   Set custom dns servers                             # 设置dns
  --dns-search=[]            Set custom dns search domains                      # 设置dns域搜索
  -e, --env=[]               Set environment variables                          # 定义环境变量
  --entrypoint=""            Overwrite the default entrypoint of the image      # ?
  --env-file=[]              Read in a line delimited file of ENV variables     # 从指定文件读取变量值
  --expose=[]                Expose a port from the container without publishing it to your host    # 指定对外提供服务端口
  -h, --hostname=""          Container host name                                # 设置容器主机名
  -i, --interactive=false    Keep stdin open even if not attached               # 保持标准输出开启即使没有attached
  --link=[]                  Add link to another container (name:alias)         # 添加链接到另外一个容器[这个会专门章节讲解]
  --lxc-conf=[]              (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
  -m, --memory=""            Memory limit (format: <number><optional unit>, where unit = b, k, m or g) # 内存限制
  --name=""                  Assign a name to the container                     # 设置容器名
  --net="bridge"             Set the Network mode for the container             # 设置容器网络模式
                               'bridge': creates a new network stack for the container on the docker bridge
                               'none': no networking for this container
                               'container:<name|id>': reuses another container network stack
                               'host': use the host network stack inside the container.  Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure.
  -P, --publish-all=false    Publish all exposed ports to the host interfaces   # 自动映射容器对外提供服务的端口
  -p, --publish=[]           Publish a container's port to the host             # 指定端口映射
                               format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort
                               (use 'docker port' to see the actual mapping)
  --privileged=false         Give extended privileges to this container         # 提供更多的权限给容器
  --rm=false                 Automatically remove the container when it exits (incompatible with -d) # 如果容器退出自动移除和-d选项冲突
  --sig-proxy=true           Proxify received signals to the process (even in non-tty mode). SIGCHLD is not proxied. # ?
  -t, --tty=false            Allocate a pseudo-tty                              # 分配伪终端
  -u, --user=""              Username or UID                                    # 指定运行容器的用户uid或者用户名
  -v, --volume=[]            Bind mount a volume (e.g., from the host: -v /host:/container, from docker: -v /container)     
                             # 挂载卷[这个会专门章节讲解]
  --volumes-from=[]          Mount volumes from the specified container(s)      # 从指定容器挂载卷
  -w, --workdir=""           Working directory inside the container             # 指定容器工作目录

示例:

$ sudo docker images ubuntu
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              14.04               e54ca5efa2e9        4 weeks ago         276.5 MB
... ...
$ sudo docker run -t -i -c 100 -m 512MB -h test1 -d --name="docker_test1" ubuntu /bin/bash 
# 创建一个cpu优先级为100,内存限制512MB,主机名为test1,名为docker_test1后台运行bash的容器
a424ca613c9f2247cd3ede95adfbaf8d28400cbcb1d5f9b69a7b56f97b2b52e5
$ sudo docker ps 
CONTAINER ID        IMAGE           COMMAND         CREATED             STATUS              PORTS       NAMES
a424ca613c9f        ubuntu:14.04    /bin/bash       6 seconds ago       Up 5 seconds                    docker_test1
$ sudo docker attach docker_test1
root@test1:/# pwd
/
root@test1:/# exit
exit

关于cpu优先级:

By default all groups have 1024 shares. A group with 100 shares will get a ~10% portion of the CPU time:

4.1.7、docker start|stop|kill... ...

docker start|stop|kill|restart|pause|unpause|rm|commit|inspect|logs

4.2、参考文档

五、docker端口映射

# Find IP address of container with ID <container_id> 通过容器id获取ip
$ sudo docker inspect <container_id> | grep IPAddress | cut -d ’"’ -f 4

无论如何,这些ip是基于本地系统的并且容器的端口非本地主机是访问不到的。此外,除了端口只能本地访问外,对于容器的另外一个问题是这些ip在容器每次启动的时候都会改变。

Docker解决了容器的这两个问题,并且给容器内部服务的访问提供了一个简单而可靠的方法。Docker通过端口绑定主机系统的接口,允许非本地客户端访问容器内部运行的服务。为了简便的使得容器间通信,Docker提供了这种连接机制。

5.1、自动映射端口

-P使用时需要指定--expose选项,指定需要对外提供服务的端口

$ sudo docker run -t -P --expose 22 --name server  ubuntu:14.04

使用docker run -P自动绑定所有对外提供服务的容器端口,映射的端口将会从没有使用的端口池中(49000..49900)自动选择,你可以通过docker psdocker inspect <container_id>或者docker port <container_id> <port>确定具体的绑定信息。

5.2、绑定端口到指定接口

基本语法

$ sudo docker run -p [([<host_interface>:[host_port]])|(<host_port>):]<container_port>[/udp] <image> <cmd>

默认不指定绑定ip则监听所有网络接口。

5.2.1、绑定TCP端口

# Bind TCP port 8080 of the container to TCP port 80 on 127.0.0.1 of the host machine.
$ sudo docker run -p 127.0.0.1:80:8080 <image> <cmd>
# Bind TCP port 8080 of the container to a dynamically allocated TCP port on 127.0.0.1 of the host machine.
$ sudo docker run -p 127.0.0.1::8080 <image> <cmd>
# Bind TCP port 8080 of the container to TCP port 80 on all available interfaces of the host machine.
$ sudo docker run -p 80:8080 <image> <cmd>
# Bind TCP port 8080 of the container to a dynamically allocated TCP port on all available interfaces
$ sudo docker run -p 8080 <image> <cmd>

5.2.2、绑定UDP端口

# Bind UDP port 5353 of the container to UDP port 53 on 127.0.0.1 of the host machine.
$ sudo docker run -p 127.0.0.1:53:5353/udp <image> <cmd>

六、配置网络

Docker uses Linux bridge capabilities to provide network connectivity to containers. The docker0 bridge interface is managed by Docker for this purpose. When the Docker daemon starts it :

Dokcer通过使用Linux桥接提供容器之间的通信,docker0桥接接口的目的就是方便Docker管理。当Docker daemon启动时需要做以下操作:

6.1、列出当前主机网桥

$ sudo brctl show  # brctl工具依赖bridge-utils软件包
bridge name bridge id STP enabled interfaces
docker0 8000.000000000000 no

6.2、查看当前docker0 ip

$ sudo ifconfig docker0
docker0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
inet addr:172.17.42.1 Bcast:0.0.0.0 Mask:255.255.0.0

在容器运行时,每个容器都会分配一个特定的虚拟机口并桥接到docker0。每个容器都会配置同docker0 ip相同网段的专用ip地址,docker0 的IP地址被用于所有容器的默认网关。

6.3、运行一个容器

$ sudo docker run -t -i -d ubuntu /bin/bash
52f811c5d3d69edddefc75aff5a4525fc8ba8bcfa1818132f9dc7d4f7c7e78b4
$ sudo brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.fef213db5a66 no vethQCDY1N

以上, docker0 扮演着52f811c5d3d6 container这个容器的虚拟接口vethQCDY1N interface桥接的角色。

6.3.1、使用特定范围的IP

Docker会尝试寻找没有被主机使用的ip段,尽管它适用于大多数情况下,但是它不是万能的,有时候我们还是需要对ip进一步的规划。Docker允许你管理docker0桥接或者通过-b选项自定义桥接网卡,需要安装bridge-utils软件包。

基本步骤如下:

# Stop Docker
$ sudo service docker stop
# Clean docker0 bridge and
# add your very own bridge0
$ sudo ifconfig docker0 down
$ sudo brctl addbr bridge0
$ sudo ifconfig bridge0 192.168.227.1 netmask 255.255.255.0
# Edit your Docker startup file
$ echo "DOCKER_OPTS=\"-b=bridge0\"" >> /etc/default/docker
# Start Docker
$ sudo service docker start
# Ensure bridge0 IP is not changed by Docker
$ sudo ifconfig bridge0
bridge0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
inet addr:192.168.227.1 Bcast:192.168.227.255 Mask:255.255.255.0
# Run a container
$ docker run -i -t ubuntu /bin/bash
# Container IP in the 192.168.227/24 range
root@261c272cd7d5:/# ifconfig eth0
eth0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
inet addr:192.168.227.5 Bcast:192.168.227.255 Mask:255.255.255.0
# bridge0 IP as the default gateway
root@261c272cd7d5:/# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.227.1 0.0.0.0 UG 0 0 0 eth0
192.168.227.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

6.4、不同主机间容器通信

不同容器之间的通信可以借助于pipework这个工具:

$ git clone https://github.com/jpetazzo/pipework.git
$ sudo cp -rp pipework/pipework /usr/local/bin/

6.4.1、安装相应依赖软件

$ sudo apt-get install arping bridge-utils -y

6.4.2、桥接网络

Ubuntu14.04

# cat /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual

auto br0
iface br0 inet static
address 10.0.128.219
netmask 255.255.255.192
gateway 10.0.128.254
bridge_ports eth0
bridge_stp off
bridge_fd 0
bridge_maxwait 0
dns-nameservers 10.0.127.110
dns-search intranet.123u.com
启动br0,使桥接生效
# ifup br0
# Bash=$(docker run -i -d -t 10.0.128.219:5000/ubuntu:14.04 /bin/bash)
# pipework br0 $Bash 10.0.128.223/26

6.5、参考文档

七、构建docker私有库

为方便管理,我们需要对官方的镜像做一些定制,我们可以构建私有的docker registry

7.1、快速构建

The fastest way to get running:

That will use the official image from the Docker index.[因为国内被墙的原因,速度比较慢,推荐第二种方式]

7.2、传统构建方式

$ sudo apt-get install build-essential python-dev libevent-dev python-pip liblzma-dev
$ git clone https://github.com/dotcloud/docker-registry.git
$ cd docker-registry/
$ cp config/config_sample.yml config/config.yml
$ mkdir /data/registry -p
$ pip install .

7.2.1、启动

$ sudo gunicorn --access-logfile - --debug -k gevent -b 0.0.0.0:5000 \
-w 1 docker_registry.wsgi:application

生产环境可以通过如supervisord创建8个workers,或者通过nginx和apache来管理,具体可以参考docker-registry readme

$ sudo gunicorn -k gevent --max-requests 100 --graceful-timeout 3600 \
-t 3600 -b localhost:5000 -w 8 docker_registry.wsgi:application

7.2.2、提交指定容器到私有库

$ docker tag 74fe38d11401 192.168.0.219:5000/ubuntu:12.04
$ docker push 192.168.0.219:5000/ubuntu

7.3、参考

八、容器数据管理

docker管理数据的方式有两种:

8.1、数据卷

数据库是一个或多个容器专门指定绕过Union File System的目录,为持续性或共享数据提供一些有用的功能:

8.1.2、添加一个数据卷

你可以使用-v选项添加一个数据卷,或者可以使用多次-v选项为一个docker容器运行挂载多个数据卷。

$ sudo docker run --name data -v /data -t -i centos:6.4 /bin/bash
# 创建数据卷绑定到到新建容器,新建容器中会创建/data数据卷
bash-4.1# ls -ld /data/
drwxr-xr-x 2 root root 4096 Jul 23 06:59 /data/
bash-4.1# df -Th
Filesystem    Type    Size  Used Avail Use% Mounted on
... ...
              ext4     91G  4.6G   82G   6% /data

创建的数据卷可以通过docker inspect获取宿主机对应路径

$ sudo docker inspect data
... ...
    "Volumes": {
        "/data": "/var/lib/docker/vfs/dir/151de401d268226f96d824fdf444e77a4500aed74c495de5980c807a2ffb7ea9"
    }, # 可以看到创建的数据卷宿主机路径
    "VolumesRW": {
        "/data1": true
    }
... ...

8.1.3、挂载宿主机目录为一个数据卷

-v选项除了可以创建卷,也可以挂载当前主机的一个目录到容器中。

$ sudo docker run --name web -v /source/:/web -t -i centos:6.4 /bin/bash
bash-4.1# ls -ld /web/
drwxr-xr-x 2 root root 4096 Jul 23 06:59 /web/
bash-4.1# df -Th
... ...
              ext4     91G  4.6G   82G   6% /web
bash-4.1# exit

默认挂载卷是可读写的,可以在挂载时指定只读

$ sudo docker run --rm --name test -v /source/:/test:ro -t -i centos:6.4 /bin/bash

8.2、创建和挂载一个数据卷容器

如果你有一些持久性的数据并且想在容器间共享,或者想用在非持久性的容器上,最好的方法是创建一个数据卷容器,然后从此容器上挂载数据。

创建数据卷容器

$ sudo docker run -t -i -d -v /test --name test centos:6.4 /bin/bash

使用--volumes-from选项在另一个容器中挂载/test卷

$ sudo docker run -t -i -d --volumes-from test --name test1 centos:6.4 /bin/bash

添加另一个容器

$ sudo docker run -t -i -d --volumes-from test --name test2 centos:6.4 /bin/bash

也可以继承其它挂载有/test卷的容器

$ sudo docker run -t -i -d --volumes-from test1 --name test3 centos:6.4 /bin/bash

8.3、备份、恢复或迁移数据卷

$ sudo docker run --volumes-from test -v $(pwd):/backup centos:6.4 tar cvf /backup/test.tar /test
tar: Removing leading `/' from member names
tar: /test/test.tar: file is the archive; not dumped
/test/
/test/b
/test/d
/test/c
/test/a

启动一个新的容器并且从test容器中挂载卷。然后我们挂载当前目录$(pwd)到容器中为backup,然后备份卷数据为test.tar,即备份数据存放在当前宿主机的所在路径下。

$ ls        # 当前目录下产生了test卷的备份文件test.tar
test.tar

你可以恢复给同一个容器或者另外的容器,新建容器并解压备份文件到新的容器数据卷:

$ sudo docker run -t -i -d -v /test --name test2 centos:6.4  /bin/bash
$ sudo docker run --volumes-from test2 -v $(pwd):/backup centos:6.4 tar xvf /backup/test.tar
# 恢复之前的文件到新建卷中
test/
test/b
test/d
test/c
test/a

8.4、参考

九、链接容器

之前介绍过通过端口映射连接容器中对外提供的服务。这是你与运行在容器中的服务和应用进行交互的方式之一。在本节中,会介绍同网络端口方式访问一样好用的方式,即链接容器。docker容器具有一个链接系统允许多个容器连接在一起并且共享连接信息。docker链接将创建一个父子关系,其中父容器可以看到关于它子容器选择的信息。

9.1 容器命名

执行docker链接依赖容器的名称,在创建容器时,如果不指定容器的名字,则默认会自动创建一个名字。这种命名提供了两个很有用的功能:

可以通过--name选项给容器自定义命名:

$ sudo docker run -d -t -i --name bash centos:6.4 bash
$ sudo docker ps -l
CONTAINER ID    IMAGE           COMMAND     CREATED              STATUS             PORTS   NAMES
70be821b7804    centos:6.4      bash        About a minute ago   Up About a minute          bash                

也可以通过docker inspect获取容器名

$ sudo docker inspect -f "{{ .Name }}" 70be821b7804
/bash
注:容器名称必须是唯一,意思是你只能命名一个叫`web`的容器。如果你想复用容器名,则必须在创建新的容器前通过`docker rm`删除旧的容器。

9.2 链接容器

链接允许容器间安全可见通信,使用--link选项创建链接。

$ sudo docker run -d -t -i --name test1 centos:6.4 bash

创建一个容器链接到test1容器

$ sudo docker run -d -t -i --name test2 --link test1:test1 centos:6.4 bash
$ sudo docker ps
CONTAINER ID    IMAGE       COMMAND CREATED         STATUS      PORTS   NAMES
1966fe2a909c    centos:6.4  bash    2 minutes ago   Up 2 minutes        test2
20f7f53b61df    centos:6.4  bash    4 minutes ago   Up 4 minutes        test1,test2/test1

从上面命令输出可以看出test2链接到test1容器的父/子关系。