Docker新手入门:基本用法

来源:互联网 发布:jquery post 数组 编辑:程序博客网 时间:2024/06/06 03:32

目录(?)[-]

  1. Docker新手入门基本用法
  2. Docker简介
    1. 1 第一本Docker书
    2. 2 Docker是什么
    3. 3 Docker与容器和虚拟机
  3. Docker安装与32位问题
    1. 1 安装Docker
    2. 2 32位版镜像
  4. 入门实战
    1. 1 核心概念
    2. 2 搜索下载镜像
    3. 3 创建启动容器
    4. 4 制作上传镜像
      1. 41 用commit制作镜像
      2. 42 用Dockerfile制作镜像
      3. 43 上传镜像到Hub
  5. 附Docker相关技术

Docker新手入门:基本用法


1.Docker简介

1.1 第一本Docker书

工作中不断碰到Docker,今天终于算是正式开始学习了。在挑选系统学习Docker以及虚拟化技术的书籍时还碰到了不少麻烦,主要就是没有特别经典的书!Docker的《第一版Docker书》和《Docker技术入门与实战》普遍评价不高,而《Docker开发实践》和《Dockeru源码分析》又是2015年最近才出的,评价不是很多。综合看了下,最终还是选择了《Docker开发实践》,以下都主要以这本书作为学习资料。

1.2 Docker是什么?

《Docker开发实践》中讲了个故事:20世纪60年代以前的海运,货物都放置在一起,很容易挤压受损。同时,不同的运输方式之间的转运也很麻烦,例如从码头和火车汽车转运卸货时。不同货物和不同交通工具之间的组合是一个巨大的二维矩阵。海运界最后达成了一致,制定了国际标准集装箱来解决这个棘手的问题。所有货物都打包进集装箱互相隔离,所有交通工具都通过集装箱转运,极大地提供了运输的安全性和效率。

在软件开发中我们也经常碰到同样的问题,使用了各种各样技术框架的应用程序,从前端静态网站到后端数据库,从PHP到Java,以及多种多样的部署环境,从测试服务器到线上环境,从虚拟机到公有云等等。Docker,正是这个集装箱,而Docker的logo也的确是个集装箱。

1.3 Docker与容器和虚拟机

很自然地我们会问,Docker跟虚拟机有什么区别啊?这个问题可以拆成两部分。因为Docker并不是什么完全独创的技术,而是属于很早便有了的容器技术,所以第一个问题就是容器与虚拟机的区别?同属于容器技术,Docker的兄弟姐妹还有Solaris Zones、BSD jails、LXC等。但Docker现在这么火,自然有它的独到之处,所以第二个问题就是Docker与其他容器的区别?

关于第一个问题比较简单,容器是一种轻量级的虚拟技术。它不像虚拟机那样具有一套完整的CPU、内存和磁盘,对操作系统有绝对的权限。容器和宿主主机共享内核,所有容器共享操作系统,在一台物理机上可以运行成百上千的容器。第二个问题稍麻烦一些,与LXC相比,Docker对配置进行了抽象,使应用在任何平台上的运行环境都一致。同时提供了版本控制、镜像托管等类似Git的现代化设施和生态圈。

总体来看,Docker的应用场景有:

  • 加速本地开发:快速搭建好开发环境和运行环境。
  • 自动打包和部署应用。
  • 创建轻量级的私有Paas环境。
  • 自动化测试和持续集成。
  • 创建安全沙盒。

2.Docker安装与32位问题

2.1 安装Docker

Docker对Linux环境有两个要求,一是64位系统,二是内核在3.8以上。而我使用的是Linux Mint 17的32位版,所以下载了源码包准备编译安装。正愁找不到编译安装的资料时,发现Ubuntu软件库提供了已经编译好的Docker 32位版,真是太好了!再看一下我的内核版本是3.13,也符合要求,于是直接用apt安装。

cdai@dell ~ $ uname -aLinux dell 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:30:01 UTC 2014 i686 i686 i686 GNU/Linuxcdai@dell ~ $ apt-cache search dockerdocker.io - Linux container runtimekdocker - lets you dock any application into the system trayvim-syntax-docker - Docker container engine - Vim highlighting syntax filescdai@dell ~ $ sudo apt-get install docker.iocdai@dell ~ $ docker -vDocker version 1.0.1, build 990021a
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2.2 32位版镜像

尽管Docker能用了,但是官方Docker Hub中的镜像都是为64位系统准备的,下载这些镜像后创建启动容器时会报”finalize namespace drop capabilities operation not permitted”的错误。所以我们可以用官方提供的Dockerfile构建出32位版本的镜像,才能在32位系统上使用。(镜像构建的具体讲解请参见第3.4节)

以构建32位版的Ubuntu为例,执行官方GitHub上提供的Shell脚本即可。经过漫长的等待后,就能看到32位的Ubuntu镜像已经成功安装到我们本地了,官方的脚本果然还是挺靠谱的。

cdai ~ $ docker imagesREPOSITORY          TAG                 IMAGE ID            CREATED              VIRTUAL SIZE32bit/ubuntu        14.04               c062cc00654e        About a minute ago   295.3 MB
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

注意:这里为了在我的老本子上学习研究Docker而做了workaround,真正应用时当然还是一定要在64位机器上使用Docker的。


3.入门实战

3.1 核心概念

在开始使用Docker之前,首先要了解Docker中的概念和它们之间的关系,否则直接上手可能会搞得一头雾水。Docker中最重要的三个概念就是:镜像、容器、库。

  • 镜像:是一个包含了应用程序和其运行时依赖环境的只读文件。
  • 容器:它是构建容器的模板,通过一个镜像我们可以构造出很多相互独立但运行环境一样的容器。
  • :Docker提供了Hub来保存公有或私有的镜像,也允许第三方搭建。

下面就是典型的Docker工作流,从这张图中能清晰地理解这三个重要概念之间的关系。本节接下来就根据这个Workflow逐一介绍常用的操作。

docker-workflow

3.2 搜索下载镜像

首先用docker search [keyword]命令查看Docker Hub上都有哪些镜像可以下载,search后可以用通配符表示关键字:

cdai ~ $ docker search ubuntuNAME                           DESCRIPTION                                     STARS     OFFICIAL   AUTOMATEDubuntu                         Ubuntu is a Debian-based Linux operating s...   2179      [OK]       ubuntu-upstart                 Upstart is an event-based replacement for ...   31        [OK]       torusware/speedus-ubuntu       Always updated official Ubuntu docker imag...   25                   [OK]tleyden5iwx/ubuntu-cuda        Ubuntu 14.04 with CUDA drivers pre-installed    17                   [OK]ubuntu-debootstrap             debootstrap --variant=minbase --components...   12        [OK]       neurodebian                    NeuroDebian provides neuroscience research...   11        [OK]           ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

接下来用docker pull [repository/url:tag]命令下载镜像。因为从官方Docker Hub下载非常慢,所以这里从国内的镜像站http://dockerpool.com/下载,速度非常快。(注:后面会讲到用docker run命令创建容器,其实如果镜像不存在Docker会自动去下载,这里为了学习pull命令所以手动下载镜像)

cdai ~ $ docker pull dl.dockerpool.com:5000/ubuntu:14.04cdai ~ $ docker pull dl.dockerpool.com:5000/centos:latest
  • 1
  • 2
  • 1
  • 2

下载完成后,就可以用docker images查看本地都有哪些镜像。这里的REPOSITORY列可能有三种类型:

  • [namespace/ubuntu]:当你在Docker Hub上注册账户时,账户名就自动成为你的namespace,它是用来区分不同用户的镜像的。
  • [ubuntu]:这种只有仓库名的可以认为它属于顶级namespace,这种仓库只用于官方的镜像。
  • [dl.dockerpool.com:5000/ubuntu]:URL路径表示镜像是放置在第三方搭建的Hub上。
cdai ~ $ docker imagesREPOSITORY                      TAG                 IMAGE ID            CREATED             VIRTUAL SIZEdl.dockerpool.com:5000/ubuntu   14.04               5506de2b643b        10 months ago       199.3 MBdl.dockerpool.com:5000/centos   latest              87e5b6b3ccc1        11 months ago       224 MB
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

如果想要查看镜像的详细信息,可以用docker inspect [image-id]命令查看。(注:下面容器一节会看到,这个命令也能够用来查看容器的详细信息)

cdai ~ $ docker inspect 5506de2b643b[{    "Architecture": "amd64",    "Author": "",    "Comment": "",    "Config": {        "AttachStderr": false,        "AttachStdin": false,        "AttachStdout": false,        "Cmd": [            "/bin/bash"        ],        ...    },    "Container": "201ae89099c20e577dd9c60cb9199c2dac0688d49efa676bf3eeb859666294bd",    "ContainerConfig": {        "AttachStderr": false,        "AttachStdin": false,        "AttachStdout": false,        ...    },    "Created": "2014-10-23T23:53:59.03271073Z",    "DockerVersion": "1.3.0",    "Id": "5506de2b643be1e6febbf3b8a240760c6843244c41e12aa2f60ccbb7153d17f5",    "Os": "linux",    "Parent": "22093c35d77bb609b9257ffb2640845ec05018e3d96cb939f68d0e19127f1723",    "Size": 0}]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

3.3 创建启动容器

了解了镜像的基本操作后,我们就可以创建容器了。首先用docker create创建容器或者用docker run [repository:tag]创建并运行容器。容器可以分为两种类型:

  • 交互型容器:前台运行,可以通过控制台与容器交互。如果创建该容器的终端被关闭,则容器就变为停止状态。此外,在容器控制台中输入exit或者通过docker stopdocker kill也能终止容器。
  • 后台型容器:后台运行,创建启动之后就与终端无关了,需要用docker stopdocker kill来终止。

说明:因为我的老本子是32位的,即便从第三方Hub安装了镜像也都是64位的无法使用,所以这里的例子都使用第一节中手动构建出的32位Ubuntu镜像。

首先我们创建运行一个交互型容器试试,在容器的控制台里简单的输出个”Hello,Docker”。怎么样?Docker容器非常轻量级,启动非常快吧!用docker ps可以查看正在运行的容器,用docker ps -a查看所有容器,包括未启动的容器。(-l和-n=x能列出最后创建的一个或x个容器)

cdai ~ $ docker run -i -t 32bit/ubuntu:14.04 /bin/bashroot@328aa6305d82:/# echo "Hello, Docker!"Hello, Docker!root@328aa6305d82:/# exitexitcdai ~ $ docker ps -aCONTAINER ID        IMAGE                COMMAND             CREATED             STATUS                     PORTS               NAMES328aa6305d82        32bit/ubuntu:14.04   /bin/bash           24 seconds ago      Exited (0) 4 seconds ago                       stupefied_curie     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

现在再创建运行一个后台型容器。可以用restart参数设置容器异常退出时自动重启:”always”不管什么返回码都尝试重启容器;”on-failure:x”则只在返回码非0时才会重启,并尝试x次。最后可以接上一个容器启动后执行的命令。这里为了做一个例子学习,所以用一个循环每隔5秒输出”hello world”。(Docker 1.3后提供了docker exec用于在容器运行之后中途启动另一个程序)

cdai ~ $ docker run -d 32bit/ubuntu:14.04 /bin/bash -c "while true; do echo hello world; sleep 5; done"5c40590cc23cfa02bd6c0220da77b601973f01f8bc430baca22315ef68d81e44cdai ~ $ docker psCONTAINER ID        IMAGE                COMMAND                CREATED             STATUS              PORTS               NAMES5c40590cc23c        32bit/ubuntu:14.04   /bin/bash -c while    5 seconds ago       Up 5 seconds                            evil_bartik         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

现在容器已经在后台运行起来了,没有控制台我们怎样能查看容器的状态呢?Docker提供了一些很实用的容器内操作命令,例如docker logs [Container-name]能够查看容器内标准输出流中的内容,docker top [container-name]查看容器中的所有进程。下面就用这两个命令查看一下刚才启动的容器运行得怎么样了?注意:启动容器时如果没用name参数指定容器名称的话,Docker会自动生成一个,下面的命令都用这个名称作为参数。

cdai ~ $ docker logs -f evil_bartikhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello world^Ccdai ~ $ docker top evil_bartikUID                 PID                 PPID                C                   STIME               TTY                 TIME                CMDroot                26803               1700                0                   21:54               ?                   00:00:00            /bin/bash -c while true; do echo hello world; sleep 5; doneroot                26859               26803               0                   21:55               ?                   00:00:00            sleep 5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

可以看到我们的容器运行良好,循环体在不断输出”hello world”到输出流中。之前学习镜像说过docker inspect也可以用于容器,现在就用它查看一下容器的详细信息。从输出可以清晰地看到启动命令、环境参数、网络等信息。

cdai ~ $ docker inspect evil_bartik[{    "Args": [        "-c",        "while true; do echo hello world; sleep 5; done"    ],    "Config": {        "AttachStderr": false,        "AttachStdin": false,        "AttachStdout": false,        "Hostname": "5c40590cc23c",        "Image": "32bit/ubuntu:14.04",        ...    },    "Created": "2015-09-03T13:54:03.389202827Z",    "Driver": "aufs",    ...    "MountLabel": "",    "Name": "/evil_bartik",    "NetworkSettings": {        "Bridge": "docker0",        "Gateway": "172.17.42.1",        "IPAddress": "172.17.0.5",        "IPPrefixLen": 16,        "PortMapping": null,        "Ports": {}    },    ...}]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

容器学习的差不多了,现在就把它停下来了吧。之前说过,对于后台型容器有docker stop [container-name]docker kill [container-name]两种方法。那它们有什么区别呢?前者会给容器内的进程发送SIGTERM信号,默认行为是容器退出,当然容器内的程序也可以捕获该信号后自行处理。而后者会给容器内的进程发送SIGKILL信号,导致容器直接退出。

cdai ~ $ docker stop evil_bartikevil_bartikcdai ~ $ docker ps -aCONTAINER ID        IMAGE                COMMAND                CREATED             STATUS                      PORTS               NAMES5c40590cc23c        32bit/ubuntu:14.04   /bin/bash -c while    3 minutes ago       Exited (-1) 5 seconds ago                       evil_bartik         328aa6305d82        32bit/ubuntu:14.04   /bin/bash              11 minutes ago      Exited (0) 11 minutes ago                       stupefied_curie     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.4 制作上传镜像

本地镜像的制作有使用commit命令和编写Dockerfile两种方式。下面就先分别介绍这两种制作方式,然后学习一下如何把我们自己制作的本地镜像上传到Docker Hub上。

3.4.1 用commit制作镜像

首先启动我们之前创建的交互型容器stupefied_curie。启动成功后会发现我们并没有进入容器的控制台,这时就要使用之前没有介绍的一个容器内使用的命令,attach命令,帮我们重新进入一个已启动容器的控制台。(注意:执行attach后,要按一次回车才会出现容器的控制台界面。而且后台型容器是无法attach的)

cdai ~ $ docker ps -aCONTAINER ID        IMAGE                COMMAND                CREATED             STATUS                    PORTS               NAMES328aa6305d82        32bit/ubuntu:14.04   /bin/bash              10 hours ago        Exited (0) 10 hours ago                       stupefied_curie     
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

attach上之后我们就可以在容器内操作了,这里我们安装一个Sqlite数据库并保存一个文本文件,准备好要制作成本地镜像的容器。本以为一切会很顺利,结果却碰到了容器内无法上网的问题,因为默认容器与宿主主机是桥接的关系需要配置一些DNS等设置。上网查了一下最简单的方法就是改一下网络模式,让容器使用与宿主主机一样的网络栈。这里重新创建一个交互型容器,网络模式使用host模式。

cdai ~ $ docker run -i -t --net="host" 32bit/ubuntu:14.04 /bin/bashroot@cdai:/# apt-get install sqlite3Reading package lists... DoneBuilding dependency tree       Reading state information... DoneSuggested packages:  sqlite3-docThe following NEW packages will be installed:  sqlite30 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.Need to get 28.3 kB of archives.After this operation, 161 kB of additional disk space will be used.Get:1 http://archive.ubuntu.com/ubuntu/ trusty-updates/main sqlite3 i386 3.8.2-1ubuntu2.1 [28.3 kB]Fetched 28.3 kB in 2s (10.8 kB/s)                   Selecting previously unselected package sqlite3.(Reading database ... 11535 files and directories currently installed.)Preparing to unpack .../sqlite3_3.8.2-1ubuntu2.1_i386.deb ...Unpacking sqlite3 (3.8.2-1ubuntu2.1) ...Setting up sqlite3 (3.8.2-1ubuntu2.1) ...root@cdai:/# echo "test docker commit" >> hellodockerroot@cdai:/# exitexit
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

现在就可以用docker commit [container-id]命令将前面准备好的容器制作成镜像了!(为什么有的命令用ID有的用name呢?)执行完成后,就能查我们的镜像已安装到本地库了。这里还发现了一个问题,就是基于32位镜像创建的容器,再制作成镜像好像又是64位了,启动时又会报”finalize namespace drop capabilities operation not permitted”错误,:(

cdai ~ $ docker ps -aCONTAINER ID        IMAGE                COMMAND                CREATED             STATUS                     PORTS               NAMES1718e35463ff        32bit/ubuntu:14.04   /bin/bash              53 seconds ago      Exited (0) 8 seconds ago                       boring_babbage      cdai ~ $ docker commit --author="cdai" 1718e35463ff cdai/sqlite3:v1e10622157a5df7c82bdf148bda021e0fe312c153852f7a6c765c216d4d636ecbcdai ~ $ docker imagesREPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZEcdai/sqlite3        v1                  e10622157a5d        6 seconds ago       321.8 MB32bit/ubuntu        14.04               c062cc00654e        11 hours ago        295.3 MB
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3.4.2 用Dockerfile制作镜像

上面我们在容器的控制台上手动执行一些操作,而Dockerfile是一种更加透明并且可重复的制作方式,因为我们不是手动执行操作,而是将所有操作用Docker提供的命令和语法编写到Dockerfile中。命令名全部大写,常用的Dockerfile命令有:

  • FROM:指定扩展自哪个父级镜像。
  • RUN:执行命令修改镜像。例如RUN apt-get update和RUN [“apt-get”, “update”]。前者在/bin/sh中执行命令,后者直接使用系统调用exec执行。
  • EXPOSE:指明容器内进程对外开放的端口。也可以在容器启动时用-p参数开放一些在Dockerfile里没有列出的端口。
  • ADD:添加宿主主机文件、文件夹或URL指定资源到镜像中。
  • ENV:设置容器运行的环境变量。
  • USER:为容器的运行以及Dockerfile后面的命令指定用户。

其他命令还有:MAINTAINER声明作者信息、WORKDIR指定工作目录(最后一个会作为容器启动后的工作目录)、VOLUME挂载文件、CMD和ENTRYPOINT指定容器启动后执行的命令、ONBUILD指定一些命令在当前镜像构建时不会执行,而是在子镜像构建时触发。

了解了这些常用的命令,下面就可以开始编写Dockerfile了。注意:Dockerfile文件名默认就叫”Dockerfile”,否则执行build命令时Docker会找不到。编写好后,执行docker build .就可以开始构建了,每一条Dockerfile的命令都相当于构建出一个临时镜像,最后一步会生成最终的目标镜像。

cdai $ ls-rw-r--r--  1 root root   17 Sep  4 09:08 abc.txt-rw-r--r--  1 root root  188 Sep  4 09:08 Dockerfilecdai $ cat Dockerfile FROM 32bit/ubuntu:14.04MAINTAINER cdai "XXX@163.com"USER rootRUN apt-get install -y nginxEXPOSE 80 8080RUN touch test.txtADD abc.txt .ENTRYPOINT ["ls"]CMD ["-a", "-l"]cdai $ docker build -t cdai/nginx:v1 .Sending build context to Docker daemon 3.584 kBSending build context to Docker daemon Step 0 : FROM 32bit/ubuntu:14.04 ---> c062cc00654eStep 1 : MAINTAINER cdai "dc_726@163.com" ---> Running in 53ece79679ed ---> 979f81286bbeRemoving intermediate container 53ece79679edStep 2 : USER root ---> Running in f5d29e4895e5 ---> 4965bbb8d8cdRemoving intermediate container f5d29e4895e5Step 3 : RUN apt-get install -y nginx ---> Running in d4e46baff94aReading package lists...Building dependency tree...Reading state information...The following extra packages will be installed:  fontconfig-config fonts-dejavu-core geoip-database libfontconfig1  libfreetype6 libgd3 libgeoip1 libjbig0 libjpeg-turbo8 libjpeg8 libtiff5  libvpx1 libx11-6 libx11-data libxau6 libxcb1 libxdmcp6 libxml2 libxpm4  libxslt1.1 nginx-common nginx-core sgml-base xml-coreSuggested packages:  libgd-tools geoip-bin fcgiwrap nginx-doc sgml-base-doc debhelper  ...Setting up nginx (1.4.6-1ubuntu3.3) ... ---> 73f5d909ac29Removing intermediate container d4e46baff94aStep 4 : EXPOSE 80 8080 ---> Running in 4333d2f3c58c ---> b693316fb774Removing intermediate container 4333d2f3c58cStep 5 : RUN touch test.txt ---> Running in 815dfbfb2005  ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

3.4.3 上传镜像到Hub

首先用docker login命令输入我们在Docker Hub的登录信息,Docker会将其保存到~/.dockercfg中。

cdai $ docker loginUsername: cdaiPassword: Email: XXX@163.comLogin Succeededcdai $ cat ~/.dockercfg {"https://index.docker.io/v1/":{"auth":"XXXXaToxXXXXXXlEYiE=","email":"XXX@163.com"}}cdai $ docker imagesREPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZEcdai/sqlite3        v1                  e10622157a5d        37 minutes ago      321.8 MB32bit/ubuntu        14.04               c062cc00654e        11 hours ago        295.3 MBcdai $ docker push cdai/sqlite3:v1The push refers to a repository [cdai/sqlite3] (len: 1)Sending image listPushing repository cdai/sqlite3 (1 tags)c062cc00654e: Buffering to disk     ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

4.附:Docker相关技术

  • 容器隔离:采用libcontainer取代了LXC作为默认容器。通过内核的pid、net、ipc、mnt和uts等命名空间实现对进程、网络、消息、文件系统和主机名的隔离。
  • 资源调配:通过cgroups控制资源的度量和分配。
  • 可移植性:利用AUFS实现对容器的快速更新。AUFS具有层的概念,每次修改都是在已有的只写层进行增量修改,修改内容形成新的文件层而不影响原有的层。
  • 安全性:通过命名空间的隔离和cgroups审计,并配合一系列工具如SELinux等来保证安全。
0 0
原创粉丝点击