UP | HOME

the-docker-book

Table of Contents

Chapter 1: Introduction

  • 首先我们要区分两个概念:
    • hypervisor virtualiation: 是指在一个物理机器上面,通过中间层,运行多个相互独 立的"虚拟机(machine)". hypervisor 隔绝的是多个machine
    • container: 是在user space运行的,不会创建独立的Machine. 所以container又叫做 system-level virtualization. container隔绝的是多个user space instance
  • 正是由于两者的差异, container可以说是不如hypervisor"灵活":
    • container只可以在ubuntu上面运行RedHat
    • hypervisor不仅仅可以在ubuntu上面运行RedHat,还能在ubuntu上面运行windows
  • 相比于拥有完整操作系统的hypervisor, docker有优点也有缺点:
    • 缺点是可能没那么安全
    • 优点是比较节省资源
  • docker是新一代的container,旨在让container技术更加的容易使用.

Introducing Docker

  • docker相比于其他container,有如下的优点:
    • 轻量级: docker非常的轻量而且快速, 因为基于copy-on-write model, 只有需要改 的地方才做了改动
    • 有了docker, 开发人员和运维人员的职责分开了: 开发人员专注于开发好container 里面的内容, 运维人员维护管理好container就好了.在docker的帮助下,运维人员可 以"百分百"的确认, 开发人员写的代码,和自己部署的代码是同一套,避免了在dev下 成立,但是运维的时候失败的问题
  • Docker的组成部分有如下:
    • Docker Client和Docker server
    • Docker Images
    • Registries
    • Docker Containers

Docker client and Server

  • Docker整体上来看,是一个CS结构的应用, Docker Client是通过和Docker Server(或者 是daemon)交流来获取能力的.
  • 你可以把Client以及Server放在同一个或者不同的机器上面

Docker images

  • image是Docker世界的基石.container就是从image开始启动的.
  • image是通过一系列指令来创建的, 比如:
    • 添加一个文件
    • 运行一个命令
    • 打开一个端口
  • 你可以把image想象成container的"source code", 而且image像git管理的代码一样,可 以方便的进行分享,存储和升级.

Registries

  • Docker通过Registry来存储你的image,就像repo存储你的git code一样.
  • registry也是区分public和private的, 和git的repo一样

Containers

  • container就是启动了的image,里面可能有一个或者多个运行的process
  • 对, 如果把image看做是静态代码的话, container就是code的运行时态
  • container保存的是process,所以就像process可以created, started, stopped, restarted, destroyed一样, container也可以有这些过程
  • 对于docker来说,container的运行方法是完全一样的,就好像对于船坞(docker)来说,集 装箱都是一样的,堆起来就可以
  • container里面有什么并不重要, docker会按照自己永远不变的程式运行它,就像船坞对 待集装箱一样,拿一个一样大小的夹子,夹起来,放到卡车上

Docker's technical components

  • docker需要x64位的Linux kernel支持(推荐version3.8以后版本)
  • docker的一些基本要求如下:
    • Linux container format: libcontainer
    • Linux kernel namespces: 用来隔绝filesystem, process, network
    • Filesystem isolation: 每个container都有自己的root filesystem
    • Process isolation: 每个container都有自己的process系统
    • Network isolation: 不同的container有不同的virtual interface 和 IP Address
    • Resource isolation and grouping: 像CPU和memory这种资源的分配,靠的是cgroups 命令(Linux下面的特性)
    • Copy-on-Write: 文件系统是copy-on-write的,也就是所有container用一套基础,有 改动才增加一层.
    • Logging: STDOUT, STDERR, STDIN都会被保存然后留以后进行分析
    • Interactive shell: 可以创建一个shell连接STDIN

Chapter 2: Installing Docker

Requirements

  • Docker的安装需要一些基本的要求:
    • 64-bit architecture, 32-bit的不支持
    • 需要Linux 3.8 以上版本的内核(某些2.6版本的可能也行)
    • The kernel 必须支持一些storage driver:
      1. Device Mapper (默认支持)
      2. AUFS
      3. vfs
      4. btrfs

Boot2Docker installation on Windows and OSX

  • Windows和Mac是没有Linux kernel支持的,所以需要virtualbox的支持, virtualbox其 实内部就是装了一个tinyCoreLinux
  • 安装了virtualBox的tinyCoreLinux以后,你要能够连接这个Linux的话,那么就得有个 command line连接这个tinyCoreLinux.这个工具就是The Docker client

Using Boot2Docker with this book

  • 如果是Boot2Docker来运行本书的例子的话,有时候你要连接localhost, 本书里面的 localhost并不是127.0.01,而是tinyCoreLinux,所以要知道这个tinyCoreLinux的ip地 址(也就是VirtualBox虚拟机的地址),需要如下命令
    c:\code>boot2docker ip
    boot2docker ip
    
    The VM's Host only interface IP address is: 192.168.59.103
    
  • boot2docker是不支持-v这个参数的,因为tinyCoreLinux里面的盘分享给docker instance 是没有意义的.

The Docker daemon

  • 安装Docker以后,我们必须确认Docker daemon是否在运行
  • Docker的daemon是root-privileged的
  • docker 命令行命令其实就是作为这个daemon(server)的client, 也同时需要root权限
  • docker daemon是监听如下的一个Unix socket来接受incoming Docker request
    > ls -al /var/run/docker.sock
    srw-rw----    1 root     docker           0 Mar 15 03:49 /var/run/docker.sock
    
  • 从上面的输出我们可以看到:如果一个机器上面有个用户组名字是docker, 那么这个这 个group docker就会被设置成/var/run/docker.sock的owner,也就不用sudo就可以调用 了, 在linux下安装docker不一定会创建docker group的,但是boot2docker默认为我们 创建了docker group
    > cat /etc/group
    root:x:0:
    lp:x:7:lp
    nogroup:x:65534:
    staff:x:50:docker
    docker:x:100:docker
    
  • 需要极为注意的是docker group虽然用起来方便,但的确是一个太高权限的group,有可 能成为他人利用漏洞, 在向此group加成员的时候,要十分小心

Configuring the Docker daemon

  • 默认情况下, docker daemon是绑定了某个端口的(比如2376)
    > sudo netstat -ltnp
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      623/sshd
    tcp        0      0 :::22                   :::*                    LISTEN      623/sshd
    tcp        0      0 :::2376                 :::*                    LISTEN      701/docker
    
  • 如果我们想把docker dameon, 换到2375这个端口,那么要使用参数-H, 下面这个例子 就说明docker已经成功启动了.
    sudo netstat -ltnp
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      623/sshd
    tcp        0      0 :::22                   :::*                    LISTEN      623/sshd
    tcp        0      0 :::2376                 :::*                    LISTEN      701/docker
    sudo kill -9 701
    sudo netstat -ltnp
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      623/sshd
    tcp        0      0 :::22                   :::*                    LISTEN      623/sshd
    sudo docker -d -H tcp://0.0.0.0:2375
    2015/03/15 13:05:53 docker daemon: 1.3.1 4e9bbfa; execdriver: native; graphdriver:
    [ccef5f24] +job serveapi(tcp://0.0.0.0:2375)
    [info] Listening for HTTP on tcp (0.0.0.0:2375)
    [info] /!\ DON'T BIND ON ANOTHER IP ADDRESS THAN 127.0.0.1 IF YOU DON'T KNOW WHAT YOU'RE DOING /!\
    [ccef5f24] +job init_networkdriver()
    [ccef5f24] -job init_networkdriver() = OK (0)
    [info] Loading containers:
    ..[info] : done.
    [ccef5f24] +job acceptconnections()
    [ccef5f24] -job acceptconnections() = OK (0)
    
  • 我们甚至可以使用-H来指定不是/var/run/docker.sock的另外的一个unix socket文件
    $ sudo /usr/bin/docker -d -H unix://home/docker/docker.sock
    
  • 需要注意的是-d参数的作用是开启"debug模式", 你会在前一个例子中发现大量的[info] 等,就是开启debug模式的结果

Checking that the Docker daemon is running

Ubuntu like

  • 可以使用如下命令来查看docker的状态
    > sudo status docker
    [ OK ]
    
  • 可以使用start 和stop来启动docker
    > sudo stop docker
    > sudo start docker
    

RedHat like

  • 可以使用如下命令开启关闭
    > sudo service docker stop
    > sudo service docker start
    

Chapter 3: Getting Started with Docker

Ensuring Docker is ready

  • 首先,我们要确认docker binary存在并且运行良好
    > docker info
    Containers: 2
    Images: 18
    Storage Driver: aufs
     Root Dir: /mnt/sda1/var/lib/docker/aufs
     Dirs: 22
    Execution Driver: native-0.2
    Kernel Version: 3.16.4-tinycore64
    Operating System: Boot2Docker 1.3.1 (TCL 5.4); master : 9a31a68 - Fri Oct 31 03:14:34 UTC 2014
    Debug mode (server): true
    Debug mode (client): false
    Fds: 11
    Goroutines: 11
    EventsListeners: 0
    Init Path: /usr/local/bin/docker
    
  • docker这个binary在前面的章节是server的作用,在这里已经是client的作用了.就是 发送request去docker daemon,然后得到反馈以后进行处理

Building our first container

  • 我们下面使用docker run来创建Docker container(从image变成container),没有image 下载的过程是因为原来下载过ubuntu image.
    docker run -i -t ubuntu /bin/bash
    root@1cdeb856c365:
    
  • 分析一下这个命令:
    • docker run是命令主体.是创建container(从image开始)
    • -i和-t两个参数的意思是: -i保证STDIN为container开启. -t保证为container提供 一个pseudo-tty,也就是给container一个interactive shell
    • 下面ubuntu的意思是我们要使用image ubuntu, 这个image是base image(也就是没 有x/y这种结构,而是只有y).base image是docker inc提供的.我们这里没有网络操作 是因为本地有image, 如果没有image,那么会从网络下载
    • /bin/bash, docker得到这个image以后,会在当前file system里面创建一个新的container 然后在这个container的/bin/bash命令,也就是
      root@1cdeb856c365:
      
  • Note: 如果我们需要所有的run的用法可以使用
    docker help run
    
    Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
    
    Run a command in a new container
    
      -a, --attach=[]            Attach to STDIN, STDOUT or STDERR.
      --add-host=[]              Add a custom host-to-IP mapping (host:ip)
      -c, --cpu-shares=0         CPU shares (relative weight)
      --cap-add=[]               Add Linux capabilities
      --cap-drop=[]              Drop Linux capabilities
      --cidfile=""               Write the container ID to the file
      --cpuset=""                CPUs in which to allow execution (0-3, 0,1)
      -d, --detach=false         Detached mode: run the container in the background and print the new container ID
      --device=[]                Add a host device to the container (e.g. --device=/dev/sdc:/dev/xvdc)
      --dns=[]                   Set custom DNS servers
      --dns-search=[]            Set custom DNS search domains
      -e, --env=[]               Set environment variables
      --entrypoint=""            Overwrite the default ENTRYPOINT of the image
      --env-file=[]              Read in a line delimited file of environment 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
      --link=[]                  Add link to another container in the form of 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 | containerPort
                                   (use 'docker port' to see the actual mapping)
      --privileged=false         Give extended privileges to this container
      --restart=""               Restart policy to apply when a container exits (no, on-failure[:max-retry], always)
      --rm=false                 Automatically remove the container when it exits (incompatible with -d)
      --security-opt=[]          Security Options
      --sig-proxy=true           Proxy received signals to the process (even in non-TTY mode). SIGCHLD, SIGSTOP, and SIGKILL are not proxied.
      -t, --tty=false            Allocate a pseudo-TTY
      -u, --user=""              Username or 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
    

Working with our first container

  • 我们来详细的看看,我们在这个shell里面能做什么, root@后面有一系列的ID,其实是 这个新的container的ID,也是它的hostname
    root@1cdeb856c365:/# hostname
    hostname
    1cdeb856c365
    
  • hostname也一般会反映在文件/etc/hosts里面
    root@1cdeb856c365:/# cat /etc/hosts
    cat /etc/hosts
    172.17.0.2  1cdeb856c365
    fe00::0 ip6-localnet
    ff00::0 ip6-mcastprefix
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters
    127.0.0.1   localhost
    ::1 localhost ip6-localhost ip6-loopback
    
  • 这个container的网络配置也是完整的: 一个localhost, 一个eth0, 其IP地址为172.17.0.2
    root@1cdeb856c365:/# ip a
    ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host
           valid_lft forever preferred_lft forever
    6: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.2/16 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::42:acff:fe11:2/64 scope link
           valid_lft forever preferred_lft forever
    
  • 可以查看当前运行的进程
    root@1cdeb856c365:/# ps -aux
    ps -aux
    USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    root         1  0.0  0.1  18168  3240 ?        Ss   12:06   0:00 /bin/bash
    root        23  0.0  0.1  15568  2092 ?        R+   12:21   0:00 ps -aux
    
  • 还能安装文件
    root@1cdeb856c365:/# apt-get install vim
    apt-get install vim
    Reading package lists... Done
    Building dependency tree
    Reading state information... Done
    The following extra packages will be installed:
      libgpm2 libpython2.7 libpython2.7-minimal libpython2.7-stdlib vim-runtime
    Suggested packages:
      gpm ctags vim-doc vim-scripts
    The following NEW packages will be installed:
      libgpm2 libpython2.7 libpython2.7-minimal libpython2.7-stdlib vim
      vim-runtime
    0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
    Need to get 9083 kB of archives.
    After this operation, 42.9 MB of additional disk space will be used.
    Do you want to continue? [Y/n]
    
  • 如果你不想使用这个container了以后,就输入exit,然后这个container就stop运行了 可以通过docker ps -a(不加-a就只显示running的container)来查看所有的container, 以及他们的状态
    docker ps -a
    CONTAINER ID        IMAGE                              COMMAND                CREATED             STATUS                      PORTS                     NAMES
    2eb46e8ca9ff        dockerfile/ubuntu-desktop:latest   "bash -c 'vncserver    33 hours ago        Exited (0) 22 minutes ago   0.0.0.0:5901->5901/tcp    determined_einstein
    a7c56bda446d        creack/firefox-vnc:latest          "x11vnc -forever -us   33 hours ago        Exited (0) 22 minutes ago   0.0.0.0:49153->5900/tcp   jolly_fermat
    1cdeb856c365        ubuntu:14.04                       "/bin/bash"            5 days ago          Exited (0) 18 seconds ago                             cocky_yonath
    
  • docker ps -l是上一次运行的container,非常好用
    docker ps -l
    CONTAINER ID        IMAGE                              COMMAND                CREATED             STATUS                      PORTS                    NAMES
    2eb46e8ca9ff        dockerfile/ubuntu-desktop:latest   "bash -c 'vncserver    33 hours ago        Exited (0) 23 minutes ago   0.0.0.0:5901->5901/tcp   determined_einstein
    

Container naming

  • ps -a的最后一行就是NAMES, 如果你在创建container的时候输入名字,这个名字就是 随机的, 我们可以使用–name来"取名字"
    > docker run --name terminal_test -i -t ubuntu /bin/bash
    > docker ps -l
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
    24497ca19cb1        ubuntu:14.04        "/bin/bash"         39 seconds ago      Exited (0) 33 seconds ago                       terminal_test
    

Staring a stopped container

  • 一旦你exit, 这个docker的status就是Exited了,所以你得start(或者restart)它
    > docker ps -l
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
    24497ca19cb1        ubuntu:14.04        "/bin/bash"         39 seconds ago      Exited (0) 33 seconds ago                       terminal_test
    > docker start terminal_test
    terminal_test
    > docker ps -l
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    24497ca19cb1        ubuntu:14.04        "/bin/bash"         2 minutes ago       Up 11 seconds                           terminal_test
    

Attaching to a container

  • 一旦这个container进入了start的状态,那么下一步就是attach到它,所以我们又可以 进入它的bash命令行了
    docker ps -l
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    24497ca19cb1        ubuntu:14.04        "/bin/bash"         2 minutes ago       Up 11 seconds                           terminal_test
    docker attach terminal_test
    
    root@24497ca19cb1:/# hostname
    hostname
    24497ca19cb1
    

Creating daemonized containers

  • 一般来说,在linux上面, 我们需要创建interactive container的需求,远不如创建后台 运行的longer-running container的需求多, 这个时候是使用参数-d
    sudo docker run --name daemon_dave -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
    1d1dd2f1477189f9d2c1d7acc0b382a1e8af5d0f6dcc5b46ab6b22aa7066c328
    docker ps -l
    CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS               NAMES
    1d1dd2f14771        ubuntu:14.04        "/bin/sh -c 'while t   4 seconds ago       Up 3 seconds                            daemon_dave
    
  • 刚才的时候,我们是有interactive的shell的,所以attach了以后,就立马联系到terminal 而这里没有terminal,我们就返回新创建的container的ID而已

Seeing what's happening inside our container

  • 我可以使用logs命令来查看,terminal里面已经输出了什么. 这个命令的结果是不变的
    docker logs daemon_dave
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    
  • 我们还可以像tail -f 一样, 使用log -f查看动态的文件改动
    docker logs -f daemon_dave
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    ...
    
  • –tail参数可以查看某些行的信息
    docker logs --tail 3 daemon_dave
    hello world
    hello world
    hello world
    
  • 参数-t是加上时间戳
    docker logs -t --tail 3 daemon_dave
    2015-03-22T12:52:04.366423061Z hello world
    2015-03-22T12:52:05.376884111Z hello world
    2015-03-22T12:52:06.387534534Z hello world
    

Inspecting the container's processes

  • 我们也可以使用top命令来查看container里面的process情况
    docker top daemon_dave
    PID                 USER                COMMAND
    1110                root                /bin/sh -c while true; do echo hello world; sleep 1; done
    2143                root                sleep 1
    

Stopping a daemonized container

  • 杀掉一个container的方法就是:
    • docker stop (发送SIGTERM signal)
    • docker kill (发送SIGKILL signal)
  • 下面是stop的例子(注意docker ps -n x是查看最近x个container的情况)
    docker stop daemon_dave
    daemon_dave
    docker ps -n 3
    CONTAINER ID        IMAGE                              COMMAND                CREATED             STATUS                       PORTS                    NAMES
    1d1dd2f14771        ubuntu:14.04                       "/bin/sh -c 'while t   20 minutes ago      Exited (-1) 34 seconds ago                            daemon_dave
    24497ca19cb1        ubuntu:14.04                       "/bin/bash"            31 minutes ago      Exited (0) 21 minutes ago                             terminal_test
    2eb46e8ca9ff        dockerfile/ubuntu-desktop:latest   "bash -c 'vncserver    33 hours ago        Exited (0) 57 minutes ago    0.0.0.0:5901->5901/tcp   determined_einstein
    

Finding out more about our container

  • 使用inspect会得到更多关于container的信息, 以json数组的形式返回
    docker inspect daemon_dave
    [{
        "Args": [
            "-c",
            "while true; do echo hello world; sleep 1; done"
        ],
        "Config": {
            "AttachStderr": false,
            "AttachStdin": false,
            "AttachStdout": false,
            "Cmd": [
                "/bin/sh",
                "-c",
                "while true; do echo hello world; sleep 1; done"
            ],
            "CpuShares": 0,
            "Cpuset": "",
            "Domainname": "",
            "Entrypoint": null,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "ExposedPorts": null,
            "Hostname": "1d1dd2f14771",
            "Image": "ubuntu",
            "Memory": 0,
        ...
    }
    ]
    
  • 当然了不是每个人都会使用Emacs的shell,如果我们想知道其中某些部分的信息, 我们 可以使用-f(–format)参数来取得一部分的信息
    docker start daemon_dave
    daemon_dave
    docker inspect --format '{{.NetworkSettings.IPAddress}}' daemon_dave
    172.17.0.7
    docker inspect --format '{{.State.Running}}' daemon_dave
    true
    
  • 我们还可以同时inspect两个container, 如果不加format就是返回一个json数组,不过 成员不再是一个,而是两个
    docker inspect --format '{{.State.Running}}' daemon_dave terminal_test
    true
    false
    

Deleting a container

  • 我们使用rm命令来删除container,但是container必须是stop状态的
    docker ps -a
    CONTAINER ID        IMAGE                              COMMAND                CREATED             STATUS                         PORTS                     NAMES
    1d1dd2f14771        ubuntu:14.04                       "/bin/sh -c 'while t   31 minutes ago      Up 3 minutes                                             daemon_dave
    24497ca19cb1        ubuntu:14.04                       "/bin/bash"            42 minutes ago      Exited (0) 33 minutes ago                                terminal_test
    2eb46e8ca9ff        dockerfile/ubuntu-desktop:latest   "bash -c 'vncserver    34 hours ago        Exited (0) About an hour ago   0.0.0.0:5901->5901/tcp    determined_einstein
    a7c56bda446d        creack/firefox-vnc:latest          "x11vnc -forever -us   34 hours ago        Exited (0) About an hour ago   0.0.0.0:49153->5900/tcp   jolly_fermat
    1cdeb856c365        ubuntu:14.04                       "/bin/bash"            5 days ago          Exited (0) 46 minutes ago                                cocky_yonath
    5273e0466f56        dockerui/dockerui:latest           "./dockerui"           6 days ago          Exited (0) 5 days ago          0.0.0.0:9000->9000/tcp    ecstatic_mcclintock
    docker stop daemon_dave
    daemon_dave
    docker rm daemon_dave
    daemon_dave
    docker ps -a
    CONTAINER ID        IMAGE                              COMMAND                CREATED             STATUS                         PORTS                     NAMES
    24497ca19cb1        ubuntu:14.04                       "/bin/bash"            42 minutes ago      Exited (0) 33 minutes ago                                terminal_test
    2eb46e8ca9ff        dockerfile/ubuntu-desktop:latest   "bash -c 'vncserver    34 hours ago        Exited (0) About an hour ago   0.0.0.0:5901->5901/tcp    determined_einstein
    a7c56bda446d        creack/firefox-vnc:latest          "x11vnc -forever -us   34 hours ago        Exited (0) About an hour ago   0.0.0.0:49153->5900/tcp   jolly_fermat
    1cdeb856c365        ubuntu:14.04                       "/bin/bash"            5 days ago          Exited (0) 46 minutes ago                                cocky_yonath
    5273e0466f56        dockerui/dockerui:latest           "./dockerui"           6 days ago          Exited (0) 5 days ago          0.0.0.0:9000->9000/tcp    ecstatic_mcclintock
    
  • 还有一个命令特别厉害可以删除所有的container
    > docker ps -a
    CONTAINER ID        IMAGE                              COMMAND                CREATED             STATUS                         PORTS                     NAMES
    24497ca19cb1        ubuntu:14.04                       "/bin/bash"            42 minutes ago      Exited (0) 33 minutes ago                                terminal_test
    2eb46e8ca9ff        dockerfile/ubuntu-desktop:latest   "bash -c 'vncserver    34 hours ago        Exited (0) About an hour ago   0.0.0.0:5901->5901/tcp    determined_einstein
    a7c56bda446d        creack/firefox-vnc:latest          "x11vnc -forever -us   34 hours ago        Exited (0) About an hour ago   0.0.0.0:49153->5900/tcp   jolly_fermat
    1cdeb856c365        ubuntu:14.04                       "/bin/bash"            5 days ago          Exited (0) 46 minutes ago                                cocky_yonath
    5273e0466f56        dockerui/dockerui:latest           "./dockerui"           6 days ago          Exited (0) 5 days ago          0.0.0.0:9000->9000/tcp    ecstatic_mcclintock
    > docker rm `docker ps -a -q`
    24497ca19cb1
    2eb46e8ca9ff
    a7c56bda446d
    1cdeb856c365
    5273e0466f56
    docker ps -a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    

Chapter 4: Working with Docker images and repositories

What is a Docker image?

  • Docker image是由多个filesystem layer组成的.最底层的filesystem是bootfs(也就 相当于Linux分区里面的/boot)
  • bootfs的上面一层是rootfs
  • TODO

Listing Docker images

  • 列出docker所有的images的方法如下
    > docker images
    REPOSITORY           TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
    ubuntu               trusty              d0955f21bf24        2 weeks ago         188.3 MB
    ubuntu               trusty-20150320     d0955f21bf24        2 weeks ago         188.3 MB
    ubuntu               14.04               d0955f21bf24        2 weeks ago         188.3 MB
    ubuntu               14.04.2             d0955f21bf24        2 weeks ago         188.3 MB
    ubuntu               latest              d0955f21bf24        2 weeks ago         188.3 MB
    ubuntu               precise             9c5e4be642b7        2 weeks ago         131.9 MB
    ubuntu               precise-20150320    9c5e4be642b7        2 weeks ago         131.9 MB
    ubuntu               12.04               9c5e4be642b7        2 weeks ago         131.9 MB
    ubuntu               12.04.5             9c5e4be642b7        2 weeks ago         131.9 MB
    creack/firefox-vnc   latest              a41e7b939b8a        23 months ago       557.6 MB
    
  • 首先我们注意到的是我们列出image,但是第一行确实repository. 我们可以把repository 理解为一类image的集合
  • repository是建立在不同的registry上面的(但是默认的都是Docker Hub,我们也就不 再考虑其他registry了)
  • 可以看到,我们有两种image集合(repository):
    • 类似ubuntu这种image是top-level repository, 是Docker Inc管理,由相应vender 提供的. 这种image具有公信力.
    • 类似creack/firefox-vnc是由一个username=> creack提供的名字叫做firefox-vnc 的image. 叫做user repository, 当然这个username是Docker Hub上面的username
  • 同一类image(repository)里面,区分不同版本的方法是:tag. 比如这里ubuntu repository就有很多tag:
    • 14.04
    • 14.04.2
    • trusty
    • 12.04
    • 12.04.5
    • precise
  • 除了TAG以外,我们还发现了Image ID, 而且我们发现所谓的14.04, 14.04.2, trusty等 等都是一个Image ID, 这也就说明了一个问题,这些tag虽然不同,但是指的缺是同一个 image. 好比git也是可以给commit打tag的,不同tag也可以打给同一个commit, 但是ID 是唯一的!
  • 既然已经类比了git,那么我们就类比多一点(以后会发现相似的地方更多):
    • docker repository <==> git repository
    • docker image <==> git commit
    • docker image id <==> git commit hash id
    • docker tag <==> git tag

Pulling images

  • 我们可以使用pull command来更新repository(git也是使用git pull来<rep>更新某个 repository)
    docker pull fedora
    

Searching for images

  • 当然我们可以搜索image啦, 所谓搜索image,其实叫做搜索repository更合适,因为其实 github搜索项目名字,搜索的其实也就是repository的列表. 而我们这里搜索出来的其 实就是repository的列表
    docker search puppet
    NAME                                 DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    devopsil/puppet                      Dockerfile for a container with puppet ins...   6                    [OK]
    layerworx/puppetmaster               Standard dockerized Puppetmaster server bu...   5                    [OK]
    macadmins/munki-puppet               Basic munki nginx image with Puppet used f...   5                    [OK]
    devopsil/puppet-yum                                                                  4                    [OK]
    layerworx/puppet                     A Puppet enabled container running the 3.7...   3                    [OK]
    macadmins/puppetmaster               Simple puppetmaster based on CentOS 6           3                    [OK]
    rfkrocktk/puppet                                                                     2                    [OK]
    simpledrupalcloud/puppet                                                             1                    [OK]
    devopsil/puppetmaster                                                                1                    [OK]
    lukasz/docker-puppet-openssl-nginx   This image is derived from https://index.d...   1                    [OK]
    scrothers/puppet                                                                     1                    [OK]
    farodin91/puppet                                                                     0                    [OK]
    razic/puppet                                                                         0                    [OK]
    kassis/puppet-spec                                                                   0                    [OK]
    m0ikz/puppet                                                                         0                    [OK]
    solict/provisionous-puppet-centos    CentOS provisions with Puppet included          0                    [OK]
    solict/provisionous-puppet-debian    Debian provisions with Puppet included          0                    [OK]
    solict/provisionous-puppet-ubuntu    Ubuntu provisions with Puppet included          0                    [OK]
    muccg/puppet-base                    Base images that use puppet and librarian-...   0                    [OK]
    jeyk/puppet                                                                          0                    [OK]
    fr3nd/puppet                                                                         0                    [OK]
    pataquets/puppet                                                                     0                    [OK]
    pmoust/puppet                        Puppet docker image based on Ubuntu 14.04 ...   0                    [OK]
    viljaste/puppet                                                                      0                    [OK]
    vmule/puppet-apt                                                                     0                    [OK]
    
  • 我们来下载其中一个image集合(repository),如下
    docker@boot2docker:~$ docker search jamtur01/puppetmaster
    NAME                           DESCRIPTION   STARS     OFFICIAL   AUTOMATED
    jamtur01/docker-puppetmaster                 1                    [OK]
    jamtur01/puppetmaster                        0
    docker@boot2docker:~$ docker pull jamtur01/puppetmaster
    Pulling repository jamtur01/puppetmaster
    99200e07340a: Download complete
    511136ea3c5a: Download complete
    3e76c0a80540: Download complete
    be88c4c27e80: Download complete
    bfab314f3b76: Download complete
    e809f156dc98: Download complete
    0ef6ede68afa: Download complete
    Status: Downloaded newer image for jamtur01/puppetmaster:latest
    
  • 然后,我们可以看到已经在image里面了
    docker images
    REPOSITORY              TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
    ubuntu                  trusty              d0955f21bf24        2 weeks ago         188.3 MB
    ubuntu                  trusty-20150320     d0955f21bf24        2 weeks ago         188.3 MB
    ubuntu                  14.04               d0955f21bf24        2 weeks ago         188.3 MB
    ubuntu                  14.04.2             d0955f21bf24        2 weeks ago         188.3 MB
    ubuntu                  latest              d0955f21bf24        2 weeks ago         188.3 MB
    ubuntu                  precise             9c5e4be642b7        2 weeks ago         131.9 MB
    ubuntu                  precise-20150320    9c5e4be642b7        2 weeks ago         131.9 MB
    ubuntu                  12.04               9c5e4be642b7        2 weeks ago         131.9 MB
    ubuntu                  12.04.5             9c5e4be642b7        2 weeks ago         131.9 MB
    jamtur01/puppetmaster   latest              99200e07340a        10 months ago       312.4 MB
    creack/firefox-vnc      latest              a41e7b939b8a        23 months ago       557.6 MB
    

Building our own images

  • 创建一个image的办法有两个:
    • docker commit (已经被弃用)
    • docker build with Dockerfile

Building images with a Dockerfile

  • Dockerfile就是专门为docker专门准备的一门DSL
  • 我们来先看看第一个例子