几个月之前,红帽(Red Hat)宣布了在 Docker 技术上和 dotCloud 创建合做关系。在那时候,我并无时间去学习关于 Docker 的知识,因此在今天,趁着这个 30 天的挑战,我决定去学习一下 Docker 到底是怎样的。这篇博文并非说之后怎么在 OpenShift 上用 Docker 的。请阅读由 Mike McGrath 撰写的 "关于 OpenShift 和 Docker 的技术思考"。也能够看看这个 Stackoverflow 的问题,了解一下 Docker 和 OpenShift 的差异。css
Docker 提供了一个能够运行你的应用程序的封套(envelope),或者说容器。它本来是 dotCloud 启动的一个业余项目,并在前些时候开源了。它吸引了大量的关注和讨论,致使 dotCloud 把它重命名到 Docker Inc。它最初是用 Go 语言编写的,它就至关因而加在 LXC(LinuX Containers,linux 容器)上的管道,容许开发者在更高层次的概念上工做。html
Docker 扩展了 Linux 容器(Linux Containers),或着说 LXC,经过一个高层次的 API 为进程单独提供了一个轻量级的虚拟环境。Docker 利用了 LXC, cgroups 和 Linux 本身的内核。和传统的虚拟机不一样的是,一个 Docker 容器并不包含一个单独的操做系统,而是基于已有的基础设施中操做系统提供的功能来运行的。这里有一个 Stackoverflow 的答案,里面很是详细清晰地描述了全部 Docker 不一样于纯粹的 LXC 的功能特性node
Docker 会像一个可移植的容器引擎那样工做。它把应用程序及全部程序的依赖环境打包到一个虚拟容器中,这个虚拟容器能够运行在任何一种 Linux 服务器上。这大大地提升了程序运行的灵活性和可移植性,不管需不须要许可、是在公共云仍是私密云、是否是裸机环境等等。linux
Docker 由下面这些组成:
1. Docker 服务器守护程序(server daemon),用于管理全部的容器。
2. Docker 命令行客户端,用于控制服务器守护程序。
3. Docker 镜像:查找和浏览 docker 容器镜像。它也访问这里获得:https://index.docker.io/git
Docker 之因此有用,是由于把代码从一个机器迁移到另外一个机器常常是困难的。它尝试去使得软件迁移的过程变得更加可信和自动化。Docker 容器能够移植到全部支持运行 Docker 的操做系统上。github
能够看这篇文章了解更多:how the Fedora Project is embracing Dockersql
到如今为止,要把程序可靠地移植的惟一选择是虚拟机(Virtual Machines,VMs)。虚拟机如今已经很常见了,但虚拟机是很是低级,它提供的是完整的操做系统环境。虚拟机的问题是,迁移的时候太大了。它们包含了大量相似硬件驱动、虚拟处理器、网络接口等等并不须要的信息。 虚拟机也须要比较长时间的启动,同时也会消耗大量的内存、CPU 资源。docker
Docker 相比起来就很是轻量级了。运行起来就和一个常规程序差很少。这个容器不只仅运行快,建立一个镜像和制做文件系统快照也很快。它能够在 EC2, RackSpace VMs 那样的虚拟环境中运行。事实上,在 Mac 和 Windows 系统上使用 Docker 的更好方式是使用 Vagrant。Docker 的初衷实际上是发挥相似 VM 的做用,但它启动得更快和须要更少的资源。express
我遇到的一个疑问是,我应该用 Vagrant 仍是 Docker 去为个人下一个项目建立沙箱环境?答案再一次是同样的。npm
Docker 比起 Vagrant 来讲,运行起来会更加省资源。Vagrant 提供的环境实际上是基于 Virtual Box 提供的虚拟机。能够阅读 Stackoverflow 的这个回答了解更多。
当第一次读到 Docker 打包应用程序时,我困惑了。咱们为何须要再多一个应用打包系统(packaging system)?我早已经把个人 Java 程序打包成 JAR 或 WAR 了。在花了些时间阅读了关于 Docker 的资料后,我明白了 Docker 应用包(application package)的含义。Docker 就是虚拟机和你的像 WAR 或 JAR 那样的应用包之间的桥梁。一方面来讲,虚拟机是很是重量级的(耗资源),由于移植时要附带些不须要的东西。另外一方面来讲,应用代码包(the application code packages)是很是的轻量的,并无附带足够可靠地运行起来的信息。Docker 很好地平衡了这两方面。
在 Docker 中,应用程序包(application package)意味着一个包含了应用程序代码和所需部署环境的包。例如,在 Java 中咱们通常把咱们的 Web 应用程序打包在一个 WAR 文件中。这个 WAR 文件是一个很是简约的软件包,它仅仅包含了应用程序的代码。但应用程序须要特定部署的环境去高效地运行起来。有时候部署的环境和开发时的环境是不一样的。例如开发者使用 Java 7 开发程序,但部署时的环境是在 OpenJDK Java 6 中;又或者是在 Mac 上开发的,但在 RHEL 上部署。状况也有多是:有一些系统库(system libraries)在开发环境和模拟环境(staging environment)中,在不一样的应用程序上有不一样的效果。Docker 经过不只仅打包应用程序,也打包应用程序的依赖环境来解决这个问题。
在 Fedora 机器上使用这篇博文中的指令安装 Docker
$ vagrant up $ vagrant ssh
而后安装 Docker Fedora 镜像:
$ sudo docker pull mattdm/fedora
上面的命令会从 https://index.docker.io/ 上下载 Docker Fedora 镜像。
安装了 Docker Fedora 镜像后,咱们可使用下面命令列出全部的镜像:
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
shekhargulati/node_image_007 latest e12b3054d981 50 minutes ago 470.3 MB (virtual 601.8 MB)
mattdm/fedora 12.04 8dbd9e392a96 7 months ago 131.5 MB (virtual 131.5 MB)
上面列表中第一个镜像就是我之前建立的。它打包了 NodeJS 及 Express Fremework。第二个镜像就是存储的 Docker Fedora 镜像了。
如今,咱们在 Docker 容器内运行一个脚本:
$ sudo docker run -t -i -p 3000 mattdm/fedora /bin/bash
在运行完上面的命令后,咱们就在 Docker 的容器里面了。咱们能够经过 ls
命令列出全部的命令。
如今咱们建立下面的目录结构 /home/shekhar/dev
:
$ mkdir -p home/shekhar/dev $ cd home/shekhar/dev
如今,我会安装 NodeJS。运行下面的命令去在 Fedora Docker 镜像上安装 Node:
$ sudo yum install npm
接着,咱们安装 Express 框架:
$ npm install express -g
Express 框架安装后,咱们建立一个新的 Express 程序,而后运行它:
$ express myapp $ cd myapp $ npm install $ node app.js
上面会在 3000
端口启动 NodeJS Express 程序。
如今打开另外一个命令行标签,列出全部的 Docker 进程:
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4a5715a915e5 mattdm/fedora /bin/bash 5 minutes ago Up 5 minutes 0.0.0.0:49157->3000/tcp red_duck
你会注意到,3000
端口和本机上的 49157
绑定了。你能够经过下面所示的 curl
命令测试 Express 应用:
$ curl 0.0.0.0:49157 <!DOCTYPE html><html><head><title>Express</title><link rel="stylesheet" href="/stylesheets/style.css"></head><body><h1>Express</h1><p>Welcome to Express</p></body></html>
如今 commit 镜像,而后 push 到 Docker 镜像注册表(registry)。在你作这步以前,你必须经过https://index.docker.io/account/signup/ 去注册一个 Docker 注册表。
$ sudo docker commit 4a5715a915e5 shekhargulati/node_image_007
$ sudo docker push shekhargulati/node_image_007
请使用你本身的用户名和镜像名。
因此,个人第一个镜像已经上传到 Docker 注册表上面了:https://index.docker.io/u/shekhargulati/node_image_007/
你可使用 pull
命令下载这个镜像:
$ docker pull shekhargulati/node_image_007
这就是今天的内容。保持反馈!