Day 21:Docker 入门教程

几个月之前,红帽(Red Hat)宣布了在 Docker 技术上和 dotCloud 创建合做关系。在那时候,我并无时间去学习关于 Docker 的知识,因此在今天,趁着这个 30 天的挑战,我决定去学习一下 Docker 到底是怎样的。这篇博文并非说之后怎么在 OpenShift 上用 Docker 的。请阅读由 Mike McGrath 撰写的 "关于 OpenShift 和 Docker 的技术思考"。也能够看看这个 Stackoverflow 的问题,了解一下 Docker 和 OpenShift 的差异。css

什么是 Docker?

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

可是我已经在使用虚拟机(VMs)了

到如今为止,要把程序可靠地移植的惟一选择是虚拟机(Virtual Machines,VMs)。虚拟机如今已经很常见了,但虚拟机是很是低级,它提供的是完整的操做系统环境。虚拟机的问题是,迁移的时候太大了。它们包含了大量相似硬件驱动、虚拟处理器、网络接口等等并不须要的信息。 虚拟机也须要比较长时间的启动,同时也会消耗大量的内存、CPU 资源。docker

Docker 相比起来就很是轻量级了。运行起来就和一个常规程序差很少。这个容器不只仅运行快,建立一个镜像和制做文件系统快照也很快。它能够在 EC2, RackSpace VMs 那样的虚拟环境中运行。事实上,在 Mac 和 Windows 系统上使用 Docker 的更好方式是使用 Vagrant。Docker 的初衷实际上是发挥相似 VM 的做用,但它启动得更快和须要更少的资源。express

它就像 Vagrant 同样吗?

我遇到的一个疑问是,我应该用 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 经过不只仅打包应用程序,也打包应用程序的依赖环境来解决这个问题。

开始使用 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

这就是今天的内容。保持反馈!

相关文章
相关标签/搜索