Day 21:Docker 入门教程
幾個(gè)月以前,紅帽(Red Hat)宣布了在 Docker 技術(shù)上和 dotCloud 建立合作關(guān)系。在那時(shí)候,我并沒(méi)有時(shí)間去學(xué)習(xí)關(guān)于 Docker 的知識(shí),所以在今天,趁著這個(gè) 30 天的挑戰(zhàn),我決定去學(xué)習(xí)一下 Docker 究竟是怎樣的。這篇博文并不是說(shuō)以后怎么在 OpenShift 上用 Docker 的。請(qǐng)閱讀由 Mike McGrath 撰寫(xiě)的 "關(guān)于 OpenShift 和 Docker 的技術(shù)思考"。也可以看看這個(gè)Stackoverflow 的問(wèn)題,了解一下 Docker 和 OpenShift 的差別。
什么是 Docker?
Docker 提供了一個(gè)可以運(yùn)行你的應(yīng)用程序的封套(envelope),或者說(shuō)容器。它原本是 dotCloud 啟動(dòng)的一個(gè)業(yè)余項(xiàng)目,并在前些時(shí)候開(kāi)源了。它吸引了大量的關(guān)注和討論,導(dǎo)致 dotCloud 把它重命名到 Docker Inc。它最初是用 Go 語(yǔ)言編寫(xiě)的,它就相當(dāng)于是加在 LXC(LinuX Containers,linux 容器)上的管道,允許開(kāi)發(fā)者在更高層次的概念上工作。
Docker 擴(kuò)展了 Linux 容器(Linux Containers),或著說(shuō) LXC,通過(guò)一個(gè)高層次的 API 為進(jìn)程單獨(dú)提供了一個(gè)輕量級(jí)的虛擬環(huán)境。Docker 利用了 LXC, cgroups 和 Linux 自己的內(nèi)核。和傳統(tǒng)的虛擬機(jī)不同的是,一個(gè) Docker 容器并不包含一個(gè)單獨(dú)的操作系統(tǒng),而是基于已有的基礎(chǔ)設(shè)施中操作系統(tǒng)提供的功能來(lái)運(yùn)行的。這里有一個(gè)Stackoverflow 的答案,里面非常詳細(xì)清晰地描述了所有 Docker 不同于純粹的 LXC 的功能特性
Docker 會(huì)像一個(gè)可移植的容器引擎那樣工作。它把應(yīng)用程序及所有程序的依賴(lài)環(huán)境打包到一個(gè)虛擬容器中,這個(gè)虛擬容器可以運(yùn)行在任何一種 Linux 服務(wù)器上。這大大地提高了程序運(yùn)行的靈活性和可移植性,無(wú)論需不需要許可、是在公共云還是私密云、是不是裸機(jī)環(huán)境等等。
Docker 由下面這些組成:
1. Docker 服務(wù)器守護(hù)程序(server daemon),用于管理所有的容器。
2. Docker 命令行客戶(hù)端,用于控制服務(wù)器守護(hù)程序。
3. Docker 鏡像:查找和瀏覽 docker 容器鏡像。它也訪問(wèn)這里得到:https://index.docker.io/
我為什么要關(guān)心這些?
Docker 之所以有用,是因?yàn)榘汛a從一個(gè)機(jī)器遷移到另一個(gè)機(jī)器經(jīng)常是困難的。它嘗試去使得軟件遷移的過(guò)程變得更加可信和自動(dòng)化。Docker 容器可以移植到所有支持運(yùn)行 Docker 的操作系統(tǒng)上。
可以看這篇文章了解更多:how the Fedora Project is embracing Docker
但是我已經(jīng)在使用虛擬機(jī)(VMs)了
到現(xiàn)在為止,要把程序可靠地移植的唯一選擇是虛擬機(jī)(Virtual Machines,VMs)。虛擬機(jī)現(xiàn)在已經(jīng)很常見(jiàn)了,但虛擬機(jī)是非常低級(jí),它提供的是完整的操作系統(tǒng)環(huán)境。虛擬機(jī)的問(wèn)題是,遷移的時(shí)候太大了。它們包含了大量類(lèi)似硬件驅(qū)動(dòng)、虛擬處理器、網(wǎng)絡(luò)接口等等并不需要的信息。 虛擬機(jī)也需要比較長(zhǎng)時(shí)間的啟動(dòng),同時(shí)也會(huì)消耗大量的內(nèi)存、CPU 資源。
Docker 相比起來(lái)就非常輕量級(jí)了。運(yùn)行起來(lái)就和一個(gè)常規(guī)程序差不多。這個(gè)容器不僅僅運(yùn)行快,創(chuàng)建一個(gè)鏡像和制作文件系統(tǒng)快照也很快。它可以在 EC2, RackSpace VMs 那樣的虛擬環(huán)境中運(yùn)行。事實(shí)上,在 Mac 和 Windows 系統(tǒng)上使用 Docker 的更好方式是使用 Vagrant。Docker 的初衷其實(shí)是發(fā)揮類(lèi)似 VM 的作用,但它啟動(dòng)得更快和需要更少的資源。
它就像 Vagrant 一樣嗎?
我遇到的一個(gè)疑問(wèn)是,我應(yīng)該用 Vagrant 還是 Docker 去為我的下一個(gè)項(xiàng)目創(chuàng)建沙箱環(huán)境?答案再一次是一樣的。
Docker 比起 Vagrant 來(lái)說(shuō),運(yùn)行起來(lái)會(huì)更加省資源。Vagrant 提供的環(huán)境其實(shí)是基于 Virtual Box 提供的虛擬機(jī)。可以閱讀 Stackoverflow 的這個(gè)回答了解更多。
噢,不是!另一個(gè)應(yīng)用程序打包系統(tǒng)
當(dāng)?shù)谝淮巫x到 Docker 打包應(yīng)用程序時(shí),我困惑了。我們?yōu)槭裁葱枰俣嘁粋€(gè)應(yīng)用打包系統(tǒng)(packaging system)?我早已經(jīng)把我的 Java 程序打包成 JAR 或 WAR 了。在花了些時(shí)間閱讀了關(guān)于 Docker 的資料后,我明白了 Docker 應(yīng)用包(application package)的含義。Docker 就是虛擬機(jī)和你的像 WAR 或 JAR 那樣的應(yīng)用包之間的橋梁。一方面來(lái)說(shuō),虛擬機(jī)是非常重量級(jí)的(耗資源),因?yàn)橐浦矔r(shí)要附帶些不需要的東西。另一方面來(lái)說(shuō),應(yīng)用代碼包(the application code packages)是非常的輕量的,并沒(méi)有附帶足夠可靠地運(yùn)行起來(lái)的信息。Docker 很好地平衡了這兩方面。
在 Docker 中,應(yīng)用程序包(application package)意味著一個(gè)包含了應(yīng)用程序代碼和所需部署環(huán)境的包。例如,在 Java 中我們一般把我們的 Web 應(yīng)用程序打包在一個(gè) WAR 文件中。這個(gè) WAR 文件是一個(gè)非常簡(jiǎn)約的軟件包,它僅僅包含了應(yīng)用程序的代碼。但應(yīng)用程序需要特定部署的環(huán)境去高效地運(yùn)行起來(lái)。有時(shí)候部署的環(huán)境和開(kāi)發(fā)時(shí)的環(huán)境是不同的。例如開(kāi)發(fā)者使用 Java 7 開(kāi)發(fā)程序,但部署時(shí)的環(huán)境是在 OpenJDK Java 6 中;又或者是在 Mac 上開(kāi)發(fā)的,但在 RHEL 上部署。情況也有可能是:有一些系統(tǒng)庫(kù)(system libraries)在開(kāi)發(fā)環(huán)境和模擬環(huán)境(staging environment)中,在不同的應(yīng)用程序上有不同的效果。Docker 通過(guò)不僅僅打包應(yīng)用程序,也打包應(yīng)用程序的依賴(lài)環(huán)境來(lái)解決這個(gè)問(wèn)題。
開(kāi)始使用 Docker
在 Fedora 機(jī)器上使用這篇博文中的指令安裝 Docker
$ vagrant up $ vagrant ssh然后安裝 Docker Fedora 鏡像:
$ sudo docker pull mattdm/fedora上面的命令會(huì)從 https://index.docker.io/ 上下載 Docker Fedora 鏡像。
安裝了 Docker Fedora 鏡像后,我們可以使用下面命令列出所有的鏡像:
上面列表中第一個(gè)鏡像就是我以前創(chuàng)建的。它打包了 NodeJS 及 Express Fremework。第二個(gè)鏡像就是存儲(chǔ)的 Docker Fedora 鏡像了。
現(xiàn)在,我們?cè)?Docker 容器內(nèi)運(yùn)行一個(gè)腳本:
$ sudo docker run -t -i -p 3000 mattdm/fedora /bin/bash在運(yùn)行完上面的命令后,我們就在 Docker 的容器里面了。我們可以通過(guò) ls 命令列出所有的命令。
現(xiàn)在我們創(chuàng)建下面的目錄結(jié)構(gòu) /home/shekhar/dev:
$ mkdir -p home/shekhar/dev $ cd home/shekhar/dev現(xiàn)在,我會(huì)安裝 NodeJS。運(yùn)行下面的命令去在 Fedora Docker 鏡像上安裝 Node:
$ sudo yum install npm接著,我們安裝 Express 框架:
$ npm install express -gExpress 框架安裝后,我們創(chuàng)建一個(gè)新的 Express 程序,然后運(yùn)行它:
$ express myapp $ cd myapp $ npm install $ node app.js上面會(huì)在 3000 端口啟動(dòng) NodeJS Express 程序。
現(xiàn)在打開(kāi)另一個(gè)命令行標(biāo)簽,列出所有的 Docker 進(jìn)程:
$ 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你會(huì)注意到,3000 端口和本機(jī)上的 49157 綁定了。你可以通過(guò)下面所示的 curl 命令測(cè)試 Express 應(yīng)用:
$ 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>現(xiàn)在 commit 鏡像,然后 push 到 Docker 鏡像注冊(cè)表(registry)。在你做這步之前,你必須通過(guò) https://index.docker.io/account/signup/ 去注冊(cè)一個(gè) Docker 注冊(cè)表。
$ sudo docker commit 4a5715a915e5 shekhargulati/node_image_007 $ sudo docker push shekhargulati/node_image_007請(qǐng)使用你自己的用戶(hù)名和鏡像名。
所以,我的第一個(gè)鏡像已經(jīng)上傳到 Docker 注冊(cè)表上面了: https://index.docker.io/u/shekhargulati/node_image_007/
你可以使用 pull 命令下載這個(gè)鏡像:
$ docker pull shekhargulati/node_image_007這就是今天的內(nèi)容。保持反饋!
原文:Day 21: Docker--The Missing Tutorial
翻譯整理:Segmentfault
總結(jié)
以上是生活随笔為你收集整理的Day 21:Docker 入门教程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Day 20: 斯坦福CoreNLP —
- 下一篇: Day 22: 使用Spring、Mon