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

這就是今天的內容。保持反饋!

相關文章
相關標籤/搜索