在 Ubuntu 上面安装部署 docker

Description: 本篇博客简单记录一下在 ubuntu 上安装部署 docker 的流程,以及 docker 常用的命令

Docker-Hub 管理镜像的方式和 github 管理代码的方式类似,你可在 Docker-Hub 网站上面申请一个账号

便可以 push 自己创建的系统镜像,或是 search,pull 他人的系统镜像到本地了,十分方便。


官网上下载 docker

打开终端,可以通过输入 docker 命令来检查当前系统中是否已经安装有 docker ,如果没有安装系统会显示出

apt-get install docker.io 

的提示语句消息,按照提示输入命令来在 ubuntu 上面安装 docker
如果您想在 windows 上面部署 docker 环境,只需要到官网上面下载 docker-install.exe 文件即可,

该文件提供 windows 系统下面 docker 运行所需要的软件,包括 Virtual-Box ,Git 和 docker-hub 图形界面工具,

不过这里介绍的是基于 ubuntu 请打算在 windows 上面部署的同学绕行。


docker 中的镜像和容器

在动手 pull 一个镜像之前,还要啰嗦一下,那就是对 docker 中的镜像容器 这两个名词的理解。

如果将镜像文件比作是 Java 编程语言中的类(文件)的话,那么容器便是基于 Java 类所实例化(new) 的一个对象实例。

镜像文件是不会被轻易改变的,它由唯一ID号码所标识,该 ID 号码和远程 pull 该镜像文件的镜像库中的文件 ID 号码保持一致。

而通过镜像文件实例化的容器一旦被创建,运行之后便是时刻处于变化状态。当然如果你如果想保存容器的当前状态的话,

也可以通过docker 提供的命令,将容器X(当前的状态)写入镜像文件中,这样再次通过镜像文件生成容器实例的时候,

该被生成的容器实例所处状态便和容器 X 是保持一致的。但是在这里也需要知道容器也是由不同的 ID 号码所唯一标识的,

就如同 Java 编程中每个类对象都由不同的 hashCode来标识一样。


使用 docker

在 docker 安装好了之后,输入 docker 命令之后会有很多参数提示信息,在这里介绍几个十分常用的命令:

docker -h

该命令用来显示 docker 的帮助选项

docker version

用来显示当前 Docker 的版本信息,啰嗦一句, docker 在 1.8 版本之后才能够支持本地向 docker-hub 上面提交 docker 镜像文件。
所以有些时候查看 docker version 还是很有必要的(曾经使用 1.2 的 docker 提交镜像文件一个整下午失败的教训)

docker info

该命令用来显示当前系统中 Docker 的信息,镜像文件和被创建的容器数目等信息

docker login

该命令在你想 docker-hub 上面注册信息之后,可以在命令行通过该命令远程登录,

如同 github 上面注册信息并添加ssh-key 之后通过 ssh 远程登录一样。

Username: kylin27
Password: *******************
Email: kylin27@outlook.com

你的登录信息存放在 .dockercfg 这个文件中

docker logout

注销当前登录的账号

该命令用来在 docker-hub 上面寻找符合描述信息的 docker 镜像文件
比如我想搜索已经安装部署了

  • 被其他用户收藏超过 10 次
  • 列出信息的时候会显示了该镜像完整的描述信息
  • java8
  • 并且能够自动化构建镜像
  • 的docker 镜像的话可以
docker search -s 10 --automated --no-trunc java8

# -s 10  搜查出被其他用户收藏(s short for stars) >= 10 次的 docker 镜像
# --automated 支持自动化构建镜像
# -- no-trunc 在显示被搜索的信息时,需要显示出完整的镜像描述信息
# java8 镜像描述信息

docker pull

将 docker-hub 中的镜像拉去(pull) 到本地镜像库

docker tag

为本地的某个镜像文件打标签,说到打标签就不得不啰嗦几句了,在 docker-hub 中通常将镜像文件按照标签来存放,
根据标签来存放镜像文件可以最大化的减少服务器端冗余的数据。 不过打标签是需要遵循一定的格式的:

docker tag username/image_name

## 其中 username 便是你使用 docker login 命令的时候使用的用户名
## image_name 便是你想为当前镜像文件起的名字

docker push

便是将当前系统中的镜像文件’推送’到docker-hub 上面的命令,
推送之后,你便可以通过网页的 docker-hub 登录自己的账户查看了(就是等同于 github 上面查看自己推送的代码一样)

推送之后,也就意味着这个镜像文件交个 docker-hub 来’托管’, 通过使用 docker search 命令也可以搜索得到的。
docker push 命令推送镜像之前,最好(一定要)使用 docker tag 命令来为它打上标签

docker images

列出本地镜像库中所有的镜像文件,当本地镜像库中镜像文件增多的时候,
推荐使用 docker images [镜像文件起始名称] 命令来查找(筛选)特定的镜像文件

docker ps

这个命令用来显示当前系统中所有运行的容器

docker rmi

这个命令用来删除本地镜像文件

docker rm

删除本地容器对象,镜像文件就像是母鸡,删了就不能生蛋(容器)了,但蛋砸了(容器删了)只要是母鸡(生成该容器的镜像文件)还在,一切都好说。

如果当前容器的状态没有同步到镜像文件中,那… 就当我啥也没说好了.

docker [start| stop | restart]

docker 容器运行系列命令,分别是启动,停止,重启一个容器

docker pause

暂停某个容器中的所有进程,但是该docker容器的进程并不停止 停止docker容器中的进程 != 杀死 docker 容器

docker unpause

将 docker 容器中被暂停的进程重新恢复运行

docker kill

杀死 docker 某个容器进程,杀死 != 移除

docker save

将镜像文件进行归档保存,后接参数 -o (output file) 用来指定归档文件的名称
第一个参数是生成归档的文件名称,

第二个参数是本地镜像文件名称,这里的冒号后面对应是为同一个镜像文件的不同变动所加上的标签 ;

我通常是按照对当前镜像文件作出的改变,或者是镜像文件生成的日期来添加标签(好记…)
同时归档文件还可以使用 .tag.gz ; .tgz, bzip 等等多种压缩文件类型

docker save -o kylin27_java8.tar kylin27/ubuntu:java8

docker load

将归档(docker save 生成的 .tar 文件之后)的docker 镜像文件,重新生成 docker 经常文件(save 的逆向操作)
后接参数 -i (input file)

docker load -i kylin27_java8.tar

docker export

刚刚介绍的拿对是 镜像文件 <=> 归档文件的相互转换, 接下来的这两个命令便是容器 => 归档文件 ; 归档文件 => 镜像的相互转换。
docker export -o 命令是将当前的容器进行归档,

docker export -o kylin27_container_java8.tar 30484q39as30

上述的命令是将 ID 号码为 30484q39as30 的容器归档生成名为 kylin27_container_java8.tar 的文件

docker import

将容器归档文件生成镜像文件

cat ./kylin27_container_java8.jar | sudo docker import - kylin27_ubuntu:java8

上述的命令是用来将数据信息从归档文件 kylin27_java8.jar 中读出来,然后调用 docker import 命令生成名为 kylin27_ubuntu:java8 的镜像文件

docker commit

将当前处于运行状态的容器中所有被变动的状态同步给镜像文件,也就是将这个容器进行模板化,将容器中所有的信息写入(更新)到
镜像文件中(该镜像文件既可以是原来的镜像文件,也可以写入到一个新的镜像文件中)

docker commit [容器ID] [要被更新的镜像文件名称|新创建的镜像文件名称]

docker inspect

在刚才介绍的命令中,比较一般的登录到运行容器中的方法是 docker run 后接登录之后执行的程序,

在上述命令中介绍的是一登录容器边启动它的命令控制台的交互程序,还有一种方式是先使用 run 方法来登录然后修改容器的 IP 地址,

在通过 ssh 的方式来登录。 不过官方推荐的方式是,使用 docker inspect + 容器 ID 号码来提取正处于运行状态的容器 PID 号码

(对的就是容器的进程号), 然后通过 nsenter 这个程序来直接切入到容器进程中; 我们接下来就介绍这种方法:

nsenter 在 Ubuntu-14.4 和它之前的版本均不支持,如果您的 Ubuntu 版本要小于等于 14.4 那么通过下面的命令来安装(更新)

cd /tmp
curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz | tar -zxf-cd util-linux-2.24./configure --without-ncursesmake nsentercp nsenter /usr/local/bin

不得不说,有人曾经很详细的了解 docker 用来存放镜像和容器的底层文件,发现 docker 底层是通过使用 json-schema 格式的文件来存放镜像和容器
所处的状态的,而当前所介绍的这个 docker inspect 命令便是抽取 docker 容器对应的 json-schema 格式的文件内容,而后面的通过参数来指定
需要获取的是底层文件中的哪种属性信息字段
输入上述命令之后,便可以获取当前运行容器的进程 PID 号码

$docker inspect --format param  容器 ID 号
上述的param 使用冒号中括号中括号.State.PID 中括号中括号冒号 来替代,我的博客格式显示有点问题,没办法直接表示 输入上述命令之后,便可以获取当前运行容器的进程 PID 号码
$nsenter --target $PID --mount --uts --ipc --net --pid 

上面的 $PID 使用输入 docker inspect 命令之后显示出来的数据结果来替代


docker 命令使用案例

接下来通过案例的方式来系统学习一下 ubuntu 下面 docker 的使用方法,在案例中,我们要

  • 下载 ubuntu 的镜像文件

    $docker pull ubuntu:14.04
    output message :
    14.04: Pulling from ubuntu
    f15ce52fc004: Downloading 24.85 MB/65.68 MB
    f15ce52fc004: Downloading  25.4 MB/65.68 MB
    f15ce52fc004: Downloading 56.75 MB/65.68 MB
    8693db7e8a00: Download complete
    
  • 显示当前系统中所有 docker 镜像文件

    $docker images 
    output message :
    REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
    ubuntu              14.04               8693db7e8a00        3 weeks ago         187.9 MB
    
  • 通过镜像文件生成容器并登录

    $docker run -i -t ubuntu14.04/bin/bash
    output message :
    root@b4bfcdde7b31:/#    // 这就进入了运行的 ubuntu:14.04 的容器中了 ; 退出的话直接在命令行中输入 exit 即可
    
  • 登录容器之后,安装一个 wget 软件

    root@b4bfcdde7b31:/# apt-get install wget 
    
  • 待到软件安装成功之后,将容器当前状态更新到新创建的镜像文件中

  • 不过首先应该获取到该容器的 ID 号码,打开一个新的 ssh 远程连接/终端窗口输入查看当前系统中所有容器和其ID号码
    $docker ps 
    output message :
    docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    b4bfcdde7b31        ubuntu:14.04        "/bin/bash"         4 minutes ago       Up 4 minutes                            desperate_poitras   
    // b4bfcdde7b31  这个便是容器的 ID 号码,用于在系统中唯一标识容器
    
  • 生成该容器的归档文件

    $docker export -o kylin27_container_wget.tar.gz b4bfcdde7b31 
    # 等待之后,便会在当前路径下面找到名为 kylin27_container_wget.tar.gz 的归档文件
    
  • 生成该容器的镜像文件


    $docker commit b4bfcdde7b31 ubuntu_14:wget
    // 冒号后面的是为镜像文件创建的标签,而冒号前面是该镜像文件对应镜像库的名称

  • 为该镜像文件打标签
    在将镜像文件提交到 docker-hub 上面的时候需要注意两点 1. 确保成功 login 2. 确保 docker 镜像文件所打的标签符合 docker-hub 格式
    必定如果你用过 github 的话(没用过也不会看到这篇搭建在 github 上面的博客)应该熟悉 github 上面的 repository 的命名和路径规则
    通常是用户名+资源库名称,道理放到 docker-hub 上面也是一样的。

    docker tag ubuntu_14:wget kylin27/ubuntu14:wget
    

    再次输入命令 docker images 会看到如下信息

    REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
    ubuntu_14           wget                44552cea1d79        5 minutes ago       187.9 MB
    kylin27/ubuntu14    wget                44552cea1d79        5 minutes ago       187.9 MB
    ubuntu              14.04               8693db7e8a00        3 weeks ago         187.9 MB
    

    看到ubuntu_14 和 kylin27/ubuntu14 这两个镜像文件虽然镜像库名称不同,但是 IMAGE ID 却是相同的,这就是方便区分标识,但却最大程度上减少冗余文件的存储的思想所在。

  • 为该镜像创建文档文件

    $docker save -o kylin27.tar ubuntu_14:wget
    

    随后便可以在当前目录下面看到名为 kylin27.tar 的归档文件

  • 将该镜像文件推送到 docker-hub 上面 在推送镜像文件之前,需要先把系统中生成该镜像文件的容器给停止(血与泪的教训)

    $docker stop b4bfcdde7b31
    $docker push kylin27/ubuntu14:wget
    output message:
    The push refers to a repository [kylin27/ubuntu] (len: 1)
    44552cea1d79: Image already exists 
    8693db7e8a00: Image successfully pushed 
    a4c5be5b6e59: Image successfully pushed 
    c4fae638e7ce: Image successfully pushed 
    f15ce52fc004: Image successfully pushed 
    Digest: sha256:09dd6e67f2c8ec9a0a9e21f4e34f415083dcd29a96e156b5d36fbdd4295f5c2f
    

成功推送信息之后,到自己的 docker-hub 上便可以看到咯~
在页面右边的显示信息便是该镜像文件 pull 的路径,如果你对这个镜像文件感兴趣的话便可以通过该信息将镜像 pull 到本地

  • 再来介绍一个 docker 中实用的批量删除 none 镜像文件的命令
    在频繁创建删除 docker 镜像文件之后便会生成很多名为 none 的镜像文件,在这里可以通过下面的命令将所有无用的 none 镜像文件删除。
    $docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker stop
    $docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker rm
    $docker images|grep none|awk '{print $3 }'|xargs docker rmi
    

end