本文旨在让大家了解什么是Docker,并带领大家体验Docker使用的整个流程。
开启Docker学习之旅前,我们简单描述几个场景,应该很多人都有碰到过:
小凹同学开发了一个web应用,服务器环境是: centos 7
+ nginx
+ node4.6
+ mongodb3.2.3
最近要上线了。
【场景1】:刚好公司有一台服务器可以用,但是服务器上有一些其他服务,而且已经装了node3.31
和mongodb2.3
,小凹蒙了,到底是直接升级环境呢?还是改一个适配低版本的应用呢?
【场景2】:终于花了很久时间部署上了,慢慢的项目需求越来越多,小凹的同事小凸也准备一起迭代这个项目,小凸又要重新配置一遍应用环境到本地做测试,随着越来越多的同事参与进来,每个人都要配置一遍本地测试环境,重复工作,时间又白白浪费掉。
【场景3】:随着项目越做越大,现有服务器配置和带宽已经不能满足了,小凹需要把这个项目迁移出去并做水平扩展,然后又得重复配置环境到多台服务器,而且这些服务器有可能还是会重复前面的场景1。
【场景4】:运维要清理一些服务器,整理出来,把没有完全利用的服务器,分给新的项目用,要罗列出来每台服务器的服务,然后删除掉不需要的,这时候发现完全无从下手。
上面的场景经常发生,也许就发生在你我身边,而且无比头疼,但对Docker来说解决这些问题都易如反掌,下面我们就一步步来了解并使用Docker。
什么是Docker?
Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机)、bare metal、OpenStack 集群和其他的基础应用平台。
官方的描述是:Build, Ship, and Run Any App, Anywhere 在任何地方部署,传输,运行任何应用。
其实很像虚拟机,但是跟虚拟机比起来 更灵活,速度更快,CPU/内存消耗更低,关键是更方便管理。
上图就是一张Docker层级图, 最下面是核心系统,文件系统等构成Dokcer底层,上面的是镜像(image),分为基础镜像和普通镜像,所有镜像可以直接启动生成一个实例(container),container我们可以理解为一个可以直接运行的虚拟机了。
其中基础image 启动后生成container,然后添加一些应用如 apache
,emacs
,可以通过提交操作直接生成普通的image。 我们可以共享这个image到任何地方,并启动它。
使用Docker
1.安装
Docker 可以安装在 Linux
, Mac OS
, Windows
上,详细安装步骤可以参考 官方安装文档 。
注:本文就不一一举例所有的安装方法,就以操作系统 centos 为例。
由于docker 只支持 centos6
以上,64
位的版本操作系统,所以安装前可以用以下命令查看服务器系统。
1
2
3
4
|
$ getconf LONG_BIT //查看操作系统是多少位
> 64
$ cat /etc/redhat-release //查看操作系统版本
> CentOS Linux release 7.0.1406 (Core)
|
上面是我使用的机器 centos7
64
位系统,我就以这个为例讲下面的使用步骤。
1
2
|
$ curl -fsSL https://get.docker.com/ | sh //安装
$ docker version // 查看是否安装成功
|
如果 安装失败 可以尝试使用阿里云的代理安装。
1
|
$ curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -
|
其他更详细的阿里云Docker代理加速器文档,可以点击这里
安装成功后启动Docker,并设置开机启动。
1
2
|
$ sudo service docker start //开启Docker 服务
$ sudo chkconfig docker on //开机启动
|
获取基础镜像
注:假定我需要部署一个基于centos
的应用,当然也可以换成别的,比如:Redis
或者 Ubuntu
,可以是任何镜像来当做基础镜像,跟本机原有系统无关,只与所要部署的应用有关。
首先搜索需要获取的 镜像,这是官方Docker Hub
提供的镜像资源。
比如,我选择获取 centos最新版本
1
|
$ docker pull centos //获取centos最近版本的镜像
|
使用命令 docker images
就能查到刚才获取的 centos
的镜像,如上图。
配置新的镜像
注:为了方便演示,假定我们的服务只需要安装一个zip
的centos
系统。
将上面获取的 centos
镜像,启动生成container,并在container中安装zip。
1
|
[root@AY130809220512304015Z image]# docker run -t -i centos /bin/bash
|
docker run
启动容器,-t
:为容器重新分配一个伪输入终端,通常与 -i 同时使用; -i
:以交互模式运行容器,通常与 -t 同时使用;centos
为镜像名, 镜像名通常以 镜像名:版本 来使用,因为centos没有版本所以省略, 后面 /bin/bash
是启动container后运行的程序。
1
2
3
4
5
6
7
|
[root@e44ea4258885 /]# zip //先运行zip,发现是没有安装的
bash: zip: command not found
[root@90934d1f4225 /]# yum install zip //安装zip
[root@90934d1f4225 /]# zip //查看zip,安装成功
Copyright (c) 1990-2008 Info-ZIP - Type 'zip "-L"' for software license.
Zip 3.0 (July 5th 2008). Usage:
...
|
使用container命令行安装zip
成功。
1
|
[root@90934d1f4225 /]# exit
|
退出容器命令行,因为不是后台运行,所以退出后,container也随即关闭了。-d
可以让container在后台运行,并可以随时通过docker attach
命令进入容器,具体例子可以看这里,因为不是本文重点就不展开说明了。
docker ps
命令可以查看当前启动的 container, -a
启动和没启动的都会展示。
1
2
3
|
[root@AY130809220512304015Z image]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8f08b2b67380 centos "/bin/bash" 21 minutes ago Exited (0) 20 minutes ago lonely_euler
|
有一个id为 8f08b2b67380的container,这个就是我们刚才安装了zip,并退出的container。
1
2
|
[root@AY130809220512304015Z image]# docker commit -m "Added zip install" 8f08b2b67380 test:1
sha256:8f1d192a4ea2a80801e33cd5fadb5f37180bb718f729f77a404a347b977d753c
|
docker commit
将container提交生成image, -m
:为描述, 后面紧接着的是container的id, test:1
是提交的镜像名称和版本。
1
2
3
4
|
[root@AY130809220512304015Z image]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test 1 8f1d192a4ea2 About a minute ago 266.7 MB
centos latest 0f0be3675ebb 7 days ago 196.6 MB
|
再查看的时候已经多了一个image了,这个image就是我们安装了zip的image,到此我们已经生成一个新的image。
我们可以直接通过这个新的镜像启动容器,还是前面介绍过的命令docker run
并测试下zip,如下:
1
2
3
4
5
|
[root@AY130809220512304015Z image]# sudo docker run -t -i o2team-test:2 /bin/bash
[root@2f1f28be351c /]# zip
Copyright (c) 1990-2008 Info-ZIP - Type 'zip "-L"' for software license.
Zip 3.0 (July 5th 2008). Usage:
...
|
好了这个镜像已经制作完成,当然实际情况下,安装的肯定不仅仅只有zip这么简单。
但是在一个团队里,仅仅给我们image,我们可能不知道这个镜像到底做了什么,所以还有一种方法使用 配置文件Dockerfile
,build出来一个镜像,这样更易于团队协作,下面我将介绍一下这种方式。
通过Dockerfile 配置新的image
开始之前顺便介绍删除image和container的命令,它们分别是docker rmi
删除image 和 docker rm
删除container,后面都是跟对应的id或者名称,为了后面的操作我们这里通过命令 docker rmi 8f1d192a4ea2
删除掉刚才建的image。
注:如果发现删不掉image,可能被某些容器引用了,可以通过上面介绍的docker ps -a
查看container,并用 docker rm
删除掉这个container。
接着我们创建Dockerfile
1
2
3
|
$ mkdir o2team
$ cd o2team
$ touch Dockerfile
|
下面是 Dockerfile
中的内容
1
2
3
4
5
|
# Dockerfile for o2team
# http://aotu.io/
FROM centos
MAINTAINER lizhi <fanlizhi@jd.com>
RUN yum -y install zip
|
#
为注释,FROM centos
为基础镜像来源,MAINTAINER
为作者信息, RUN
则为 运行某些 命令,编辑完成后保存,然后我们就可以直接构建我们新的image,Dockerfile详细使用文档可以参看这里。
1
|
[root@AY130809220512304015Z o2team-test]# docker build -t test:1 .
|
docker build
就是通过Dockfile来创建一个新的Image,其中 -t
:为新image的名字这里命名为test:1, "."
则会在当前的目录下找 Dockerfile
文件,当然这里也可以指定路径。
1
2
3
4
|
[root@AY130809220512304015Z o2team-test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test 1 8975f3fb142e 8 seconds ago 266.7 MB
centos latest 0f0be3675ebb 9 days ago 196.6 MB
|
就这样,通过docker images
也能生成一个新的镜像了,这种用Dockerfile的方式更加适合团队使用,环境配置更清晰。
到这里,我们只需要管理我们的镜像就好了,比如同步镜像给其他人,或者其他机器。
其实docker就给我们提供了这样一整套的解决方案,我们可以把我们的镜像提交到 Docker Hub,类似 github
一样的远程仓库,当我们需要的时候只需要 pull下来启动就好了。
提交
我们就把这个test镜像提交到Docker Hub
首先我们得先注册:https://hub.docker.com/
注册成功后就可以docker login
登录了
1
2
3
4
5
|
[root@AY130809220512304015Z o2team-test]# docker login
> Username: a569171010
> Password: xxx
> Email: fanlizhi@jd.com
Login Succeeded
|
填完登录后就可以push了,注意这里push之前得确保名称是 youruser/xxx
比如我的用户名是 a569171010 所以我需要将刚才的image 重命名成 a569171010/test:1,这里可以用docker tag
命令重命名。
1
2
|
[root@AY130809220512304015Z o2team-test]# docker tag test:1 a569171010/test:1
[root@AY130809220512304015Z o2team-test]# docker push a569171010/test:1
|
然后就发布出去了,在 Docker Hub 上就可以看到下面多了这一条记录,当我们要获取的时候就直接 docker pull a569171010/test
就可以了,因为是公用库所以任何人都可以获取并使用。
我们已经基本熟悉,了解了整个Docker使用的流程,回过头来看看开始我们抛出的那几个曾经很棘手的问题,是不是都能迎刃而解呢?因为image的可移植和隔离性,我们不仅可以轻松迁移扩展,还能轻松了解现在机器上各个服务运行情况。
下图为Docker整个使用流程:
本文参考资料
Docker 官方文档 Docker 中文指南 dockone.io 国内比较活跃的Docker论坛 Docker 入门介绍 Docker github 阿里镜像使用文档 *
还想了解的
这篇文章只是带领大家了解Docker的整个使用流程和体验,关于其他的一些细节问题比如:后台运行container,各container之间的通讯,端口映射,文件共享等都没有涉及到,最近docker1.1.0
发布又有很多新的特性和性能优化,如果有兴趣的同学可以参考这些:
利用Docker构建开发环境 Docker-从入门到实践 Docker-学习资料 Docker 1.1.0新特性