幾個月之前,紅帽(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
這就是今天的內容。保持反饋!