Docker新手入门:基本用法

Docker新手入门:基本用法


.Docker简介

1.1 第一本Docker书

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

1.2 Docker是什么?

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

在软件开发中我们也经常碰到同样的问题,使用了各种各样技术框架的应用程序,从前端静态网站到后端数据库,从PHPJava,以及多种多样的部署环境,从测试服务器到线上环境,从虚拟机到公有云等等。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 -a
Linux dell 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:30:01 UTC 2014 i686 i686 i686 GNU/Linux

cdai@dell ~ $ apt-cache search docker
docker.io - Linux container runtime
kdocker - lets you dock any application into the system tray
vim-syntax-docker - Docker container engine - Vim highlighting syntax files

cdai@dell ~ $ sudo apt-get install docker.io
cdai@dell ~ $ docker -v
Docker 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 images
REPOSITORY          TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
32bit/ubuntu        14.04               c062cc00654e        About a minute ago   295.3 MB
 
  
  
  • 1

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


3.入门实战

3.1 核心概念

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

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


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




3.2 搜索下载镜像

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

cdai ~ $ docker search ubuntu
NAME                           DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
ubuntu                         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]      
    ...


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


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


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


  • [namespace/ubuntu]:当你在Docker Hub上注册账户时,账户名就自动成为你的namespace,它是用来区分不同用户的镜像的。
  • [ubuntu]:这种只有仓库名的可以认为它属于顶级namespace,这种仓库只用于官方的镜像。
  • [dl.dockerpool.com:5000/ubuntu]:URL路径表示镜像是放置在第三方搭建的Hub上。

cdai ~ $ docker images
REPOSITORY                      TAG             IMAGE ID         CREATED          VIRTUAL SIZE
dl.dockerpool.com:5000/ubuntu   14.04           5506de2b643b     10 months ago      199.3 MB
dl.dockerpool.com:5000/centos   latest          87e5b6b3ccc1     11 months ago      224 MB


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


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

cdai ~ $ docker ps -a
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS                     PORTS               NAMES
328aa6305d82


3.4 制作上传镜像


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

3.4.1 用commit制作镜像

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

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



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



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的命令都相当于构建出一个临时镜像,最后一步会生成最终的目标镜像。



3.4.3 上传镜像到Hub

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



4.附:Docker相关技术

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



 
 


猜你喜欢

转载自blog.csdn.net/superiorpengFight/article/details/55253100