你所不了解的的Docker

關注微信公眾號【非同步圖書】,每日贈送非同步新書

本文摘自人民郵電出版社非同步社區《Docker實踐-圖書 - 非同步社區》

本文主要內容

  • Docker是什麼
  • Docker的使用以及它如何能節省時間和金錢
  • 容器與鏡像之間的區別
  • Docker的分層特性
  • 使用Docker構建並運行一個to-do應用程序

Docker是一個允許用戶「在任何地方構建、分發及運行任何應用」的平台。它在極短的時間內發展壯大,目前已經被視為解決軟體中最昂貴的方面之一——部署的一個標準方法。

在Docker出現之前,開發流水線通常由用於管理軟體活動的不同技術組合而成,如虛擬機、配置管理工具、不同的包管理系統以及各類依賴庫複雜的網站。所有這些工具需要由專業的工程師管理和維護,並且多數工具都具有自己獨特的配置方式。

Docker改變了這一切,允許不同的工程師參與到這個過程中,有效地使用同一門語言,這讓協作變得輕而易舉。所有東西通過一個共同的流水線轉變成可以在任何目標平台上使用的單一的產出——無須繼續維護一堆讓人眼花繚亂的工具配置,如圖1-1所示。

與此同時,只要現存的軟體技術棧依然有效,用戶就無須拋棄它——用戶可以將其原樣打包到一個Docker容器內供其他人使用。由此獲得的額外好處是,用戶能看到這些容器是如何構建的,因此如果需要深入其細節,完全沒問題。

在本文中,讀者將了解到Docker是什麼、為什麼它很重要,並開始使用它。

圖1-1 Docker如何消除了工具維護的負擔

1.1 Docker是什麼以及為什麼用Docker

在動手實踐之前,我們將對Docker稍做討論,以便讀者了解它的背景、「Docker」名字的來歷以及為什麼使用它!

1.1.1 Docker是什麼

要理解Docker是什麼,從一個比喻開始會比技術性解釋來得簡單,而且這個Docker的比喻非常有說服力。Docker原本是指在船隻停靠港口之後將商品移進或移出的工人。箱子和物品的大小和形狀各異,而有經驗的碼頭工人能以合算的方式手工將商品裝入船隻,因而他們倍受青睞(見圖1-2)。僱人搬東西並不便宜,但除此之外別無選擇。

對在軟體行業工作的人來說,這聽起來應該很熟悉。大量時間和精力被花在將奇形怪狀的軟體放置到裝滿了其他奇形怪狀軟體、大小各異的船隻上,以便將其賣給其他地方的用戶或商業機構。

圖1-2 標準化集裝箱前後的航運對比

在Docker出現之前,部署軟體到不同環境所需的工作量巨大。即使不是採用手工運行腳本的方式在不同機器上進行軟體配備(還是有很多人這麼做),用戶也不得不全力應付那些配置管理工具,它們掌管著渴求資源且快速變化的環境的狀態。即便將這些工作封裝到虛擬機中,還是需要花費大量時間來部署這些虛擬機、等待它們啟動並管理它們所產生的額外的資源開銷。

使用Docker,配置工作從資源管理中分離了出來,而部署工作則是微不足道的:運行docker run,環境的鏡像會被拉取下來並準備運行,所消耗的資源更少並且是內含的,因此不會干擾其他環境。

讀者無須擔心容器是將被分發到Red Hat機器、Ubuntu機器還是CentOS虛擬機鏡像中,只要上面有Docker,就沒有問題。

圖1-3展示了使用Docker概念時如何能節省時間和金錢。

圖1-3 使用Docker前後軟體交付的對比

1.1.2 Docker有什麼好處

幾個重要的實際問題出現了:為什麼要使用Docker,Docker用在什麼地方?針對「為什麼」的簡要答案是:只需要一點點付出,Docker就能快速為企業節省大量金錢。部分方法(肯定不是所有的)將在隨後的幾節中討論。我們已經在實際工作環境中切身體會到所有這些益處。

1.替代虛擬機(VM)

Docker可以在很多情況下替代虛擬機。如果用戶只關心應用程序,而不是操作系統,可以用Docker替代虛擬機,並將操作系統交給其他人去考慮。Docker不僅啟動速度比虛擬機快,遷移時也更為輕量,同時得益於它的分層文件系統,與其他人分享變更時更簡單、更快捷。而且,它牢牢地紮根在命令行中,非常適合腳本化。

2.軟體原型

如果想快速體驗軟體,同時避免干擾目前的設置或配備一個虛擬機的麻煩,Docker可以在幾毫秒內提供一個沙箱環境。在親身體驗之前,很難感受到這種解放的效果。

3.打包軟體

因為對Linux用戶而言,Docker鏡像實際上沒有依賴,所以非常適合用於打包軟體。用戶可以構建鏡像,並確保它可以運行在任何現代Linux機器上——就像Java一樣,但不需要JVM。

4.讓微服務架構成為可能

Docker 有助於將一個複雜系統分解成一系列可組合的部分,這讓用戶可以用更離散的方式來思考其服務。用戶可以在不影響全局的前提下重組軟體使其各部分更易於管理和可插拔。

5.網路建模

由於可以在一台機器上啟動數百個(甚至數千個)隔離的容器,因此對網路進行建模輕而易舉。這對於現實世界場景的測試非常有用,而且所費無幾。

6.離線時啟用全棧生產力

因為可以將系統的所有部分捆綁在Docker容器中,所以用戶可以將其編排運行在筆記本電腦中移動辦公,即便在離線時也沒問題。

7.降低調試支出

不同團隊之間關於軟體交付的複雜談判在業內司空見慣。我們親身經歷過不計其數的這類討論:失效的庫、有問題的依賴、更新被錯誤實施或是執行順序有誤,甚至可能根本沒執行以及無法重現的錯誤等。估計讀者也遇到過。Docker讓用戶可以清晰地說明(即便是腳本的形式)在一個屬性已知的系統上調試問題的步驟,錯誤和環境重現變得更簡單,而且通常與所提供的宿主機環境是分離的。

8.文檔化軟體依賴及接觸點

通過使用結構化方式構建鏡像,為遷移到不同環境做好準備,Docker 強制用戶從一個基本出發點開始明確地記錄軟體依賴。即使用戶不打算在所有地方都使用Docker,這種對文檔記錄的需要也有助於在其他地方安裝軟體。

9.啟用持續交付

持續交付(continuous delivery,CD)是一個基於流水線的軟體交付范型,該流水線通過一個自動化(或半自動化)流程在每次變動時重新構建系統然後交付到生產環境中。

因為用戶可以更準確地控制構建環境的狀態,Docker 構建比傳統軟體構建方法更具有可重現性和可複製性。使持續交付的實現變得更容易。通過實現一個以Docker為中心的可重現的構建過程,標準的持續交付技術,如藍/綠部署(blue/green deployment,在生產環境中維護「生產」和「最新」部署)和鳳凰部署(phoenix deployment,每次發布時都重新構建整個系統)變得很簡單。

現在,讀者對Docker如何能夠提供幫助有了一定了解。在進入一個真實示例之前,讓我們來了解一下幾個核心概念。

1.1.3 關鍵的概念

在本節中,我們將介紹一些關鍵的Docker概念,如圖1-4所示。

圖1-4 Docker的核心概念

在開始運行Docker命令之前,將鏡像、容器及層的概念牢記於心是極其有用的。簡而言之,容器運行著由鏡像定義的系統。這些鏡像由一個或多個(或差異集)加上一些Docker的元數據組成。

讓我們來看一些核心的Docker命令。我們將把鏡像轉變成容器,修改它們,並添加層到我們即將提交的新鏡像中。如果這一切聽上去有點兒混亂,不用太擔心。在本文結束時,一切都將更加清晰。

1.關鍵的Docker命令

Docker的中心功能是構建、分發及在任何具有Docker的地方運行軟體。

對終端用戶而言,Docker是一個用於運行的命令行程序。就像git(或任何源代碼控制工具)一樣,這個程序具有用於執行不同操作的子命令。

表1-1中列出了將在宿主機上使用的主要的Docker子命令。

表1-1 Docker子命令

命  令目  的

docker build

構建一個Docker鏡像

docker run

以容器形式運行一個Docker鏡像

docker commit

將一個Docker容器作為一個鏡像提交

docker tag

給一個Docker鏡像打標籤

2.鏡像與容器

如果讀者不熟悉Docker,這可能是第一次聽說本文所說的「容器」和「鏡像」這兩個詞。它們很可能是Docker中最重要的概念,因此有必要花點兒時間明確其差異。

在圖1-5中,讀者將看到這些概念的展示,裡面有從一個基礎鏡像啟動的3個容器。

圖1-5 Docker鏡像與容器

看待鏡像和容器的一種方式是將它們類比成程序與進程。一個進程可以視為一個被執行的應用程序,同樣,一個Docker容器可以視為一個運行中的Docker鏡像。

如果讀者熟悉面向對象原理,看待鏡像和容器的另一種方法是將鏡像看作類而將容器看作對象。對象是類的具體實例,同樣,容器是鏡像的實例。用戶可以從單個鏡像創建多個容器,就像對象一樣,它們之間全都是相互隔離的。不論用戶在對象內修改了什麼,都不會影響類的定義——它們從根本上就是不同的東西。

1.2 構建一個Docker應用程序

現在,我們要動手使用Docker來構建一個簡單的「to-do」應用程序(todoapp)鏡像了。在這個過程中,讀者會看到一些關鍵的Docker功能,如Dockerfile、鏡像復用、埠暴露及構建自動化。這是接下來10分鐘讀者將學到的東西:

  • 如何使用Dockerfile來創建Docker鏡像;
  • 如何為Docker鏡像打標籤以便引用;
  • 如何運行新建的Docker鏡像。

to-do應用是協助用戶跟蹤待完成事項的一個應用程序。我們所構建的應用將存儲並顯示可被標記為已完成的信息的簡短字元串,它以一個簡單的網頁界面呈現。

圖1-6展示了如此操作將得到的結果。

圖1-6 構建一個Docker應用程序

應用程序的細節不是重點。我們將演示從我們所提供的一個簡短的Dockerfile開始,讀者可以放心地在自己的宿主機上使用與我們相同的方法構建、運行、停止和啟動一個應用程序,而無須考慮應用程序的安裝或依賴。這正是 Docker 賦予我們的關鍵部分——可靠地重現並簡便地管理和分享開發環境。這意味著用戶無須再遵循並迷失在那些複雜的或含糊的安裝說明中。

to-do應用程序 這個to-do應用程序將貫穿本文,多次使用,它非常適合用於實踐和演示,因此值得讀者熟悉一下。

1.2.1 創建新的Docker鏡像的方式

創建Docker鏡像有4種標準的方式。表1-2逐一列出了這些方法。

表1-2 創建Docker鏡像的方式

方  法描  述詳見技巧

Docker命令/「手工」

使用docker run啟動一個容器,並在命令行輸入命令來創建鏡像。使用docker commit來創建一個新鏡像

詳見技巧14

Dockerfile

從一個已知基礎鏡像開始構建,並指定一組有限的簡單命令來構建

稍後討論

Dockerfile及配置管理(configuration management,CM)工具

與Dockerfile相同,不過將構建的控制權交給了更為複雜的CM工具

詳見技巧47

從頭創建鏡像並導入一組文件

從一個空白鏡像開始,導入一個含有所需文件的TAR文件

詳見技巧10

如果用戶所做的是概念驗證以確認安裝過程是否正常,那麼第一種「手工」方式是沒問題的。在這個過程中,用戶應對所採取的步驟做記錄,以便在需要時回到同一點上。

到某個時間點,用戶會想要定義創建鏡像的步驟。這就是第二種方式(也就是我們這裡所用的方式)。

對於更複雜的構建,用戶需要使用第三種方式,特別是在Dockerfile功能還不足以滿足鏡像要求的時候。

最後一種方式從一個空鏡像開始,通過疊加一組運行鏡像所需要的文件進行構建。如果用戶想導入一組在其他地方創建好的自包含的文件,這將非常有用,不過這在主流應用中非常罕見。

現在,我們來看一下Dockerfile方法,其他方法將在本文後面再說明。

1.2.2 編寫一個Dockerfile

Dockerfile是一個包含一系列命令的文本文件。本示例中我們將使用的Dockerfile如下:

FROM node  ?--- ? 定義基礎鏡像

MAINTAINER ian.miell@gmail.com  ?--- ? 聲明維護人員

RUN git clone -q github.com/docker-in-pr  ?--- ? 克隆todoapp代碼

WORKDIR todo  ?--- ? 移動到新的克隆目錄

RUN npm install /dev/null  ?--- ? 運行node包管理器的安裝命令(npm)

EXPOSE 8000  ?--- ? 指定從所構建的鏡像啟動的容器需要監聽這個埠

CMD [npm,start]  ?--- ? 指定在啟動時需要運行的命令

Dockerfile的開始部分是使用FROM命令定義基礎鏡像?。本示例使用了一個Node.js鏡像以便訪問Node.js程序。官方的Node.js鏡像名為node

接下來,使用MAINTAINER命令聲明維護人員?。在這裡,我們我們使用的是其中一個人的電子郵件地址,讀者也可以替換成自己的,因為現在它是你的Dockerfile了。這一行不是創建可工作的Docker鏡像所必需的,不過將其包含進來是一個很好的做法。到這個時候,構建已經繼承了node容器的狀態,讀者可以在它上面做操作了。

接下來,使用RUN命令克隆todoapp代碼?。這裡使用指定的命令獲取應用程序的代碼:在容器內運行git。在這個示例中,Git是安裝在基礎node鏡像里的,不過讀者不能對這類事情做假定。

現在移動到使用WORKDIR命令新克隆的目錄中?。這不僅會改變構建環境中的目錄,最後一條WORKDIR命令還決定了從所構建鏡像啟動容器時用戶所處的默認目錄。

接下來,運行node包管理器的安裝命令(npm)?。這將為應用程序設置依賴。我們對輸出的信息不感興趣,所以將其重定向到/dev/null上。

由於應用程序使用了8000埠,使用EXPOSE命令告訴Docker從所構建鏡像啟動的容器應該監聽這個埠?。

最後,使用CMD命令告訴Docker在容器啟動時將運行哪條命令?。

這個簡單的示例演示了Docker及Dockerfile的幾個核心功能。Dockerfile是一組嚴格按順序運行的有限的命令集的簡單序列。它們影響了最終鏡像的文件和元數據。這裡的RUN命令通過簽出並安裝應用程序影響了文件系統,而EXPOSECMDWORKDIR命令影響了鏡像的元數據。

1.2.3 構建一個Docker鏡像

讀者已經定義了自己的Dockerfile的構建步驟。現在可以鍵入圖1-7所示的命令從而構建Docker鏡像了。

圖1-7 Docker build命令

讀者將看到類似下面這樣的輸出:

Sending build context to Docker daemon 178.7 kB   ?--- Docker會上傳docker build指定目錄下的文件和目錄

Sending build context to Docker daemon

Step 0 : FROM node   ?--- 每個構建步驟從 0 開始按順序編號,並與命令一起輸出 --- fc81e574af43   ?--- 每個命令會導致一個新鏡像被創建出來,其鏡像ID在此輸出

Step 1 : MAINTAINER ian.miell@gmail.com

--- Running in 21af1aad6950 --- 8f32669fe435

Removing intermediate container 21af1aad6950   ?--- 為節省空間,在繼續前每個中間容器會被移除

Step 2 : RUN git clone github.com/ianmiell/tod

--- Running in 0a030ee746ea

Cloning into todo...

--- 783c68b2e3fc

Removing intermediate container 0a030ee746ea

Step 3 : WORKDIR todo

--- Running in 2e59f5df7152 --- 8686b344b124

Removing intermediate container 2e59f5df7152

Step 4 : RUN npm install --- Running in bdf07a308fca

npm info it worked if it ends with ok   ?--- 構建的調試信息在此輸出(限於篇幅,本代碼清單做了刪減)

[...]

npm info ok

--- 6cf8f3633306

Removing intermediate container bdf07a308fca

Step 5 : RUN chmod -R 777 /todo

--- Running in c03f27789768 --- 2c0ededd3a5e

Removing intermediate container c03f27789768

Step 6 : EXPOSE 8000 --- Running in 46685ea97b8f --- f1c29feca036

Removing intermediate container 46685ea97b8f

Step 7 : CMD npm start --- Running in 7b4c1a9ed6af --- 66c76cea05bb

Removing intermediate container 7b4c1a9ed6af

Successfully built 66c76cea05bb   ?---  此次構建的最終鏡像ID,可用於打標籤

現在,擁有了一個具有鏡像ID(前面示例中的「66c76cea05bb」,不過讀者的ID會不一樣)的Docker鏡像。總是引用這個ID會很麻煩,可以為其打標籤以方便引用。

輸入圖1-8所示的命令,將66c76cea05bb替換成讀者生成的鏡像ID。

圖1-8 Docker tag命令

現在就能從一個Dockerfile構建自己的Docker鏡像副本,並重現別人定義的環境了!

1.2.4 運行一個Docker容器

讀者已經構建出Docker鏡像並為其打上了標籤。現在可以以容器的形式來運行它了:

docker run -p 8000:8000 --name example1 todoapp   ?---? docker run子命令啟動容器,-p將容器的 8000 埠映射到宿主機的8000埠上,--name給容器賦予一個唯一的名字,最後一個參數是鏡像

npm install

npm info it worked if it ends with ok

npm info using npm@2.14.4 npm info using node@v4.1.1 npm info prestart todomvc-swarm@0.0.1

todomvc-swarm@0.0.1 prestart /todo   ?--- 容器的啟動進程的輸出被發送到終端中

make all

npm install

npm info it worked if it ends with ok

npm info using npm@2.14.4 npm info using node@v4.1.1 npm WARN package.json todomvc-swarm@0.0.1 No repository field.

npm WARN package.json todomvc-swarm@0.0.1 license should be a

? valid SPDX license expression

npm info preinstall todomvc-swarm@0.0.1 npm info package.json statics@0.1.0 license should be a valid

? SPDX license expression

npm info package.json react-tools@0.11.2 No license field.

npm info package.json react@0.11.2 No license field.

npm info package.json node-jsx@0.11.0 license should be a valid

? SPDX license expression

npm info package.json ws@0.4.32 No license field.

npm info build /todo

npm info linkStuff todomvc-swarm@0.0.1 npm info install todomvc-swarm@0.0.1 npm info postinstall todomvc-swarm@0.0.1 npm info prepublish todomvc-swarm@0.0.1 npm info ok

if [ ! -e dist/ ]; then mkdir dist; fi

cp node_modules/react/dist/react.min.js dist/react.min.js

 

LocalTodoApp.js:9: // TODO: default english version

LocalTodoApp.js:84: fwdList =

? this.host.get(/TodoList#+listId); // TODO fn+id sig

TodoApp.js:117: // TODO scroll into view

TodoApp.js:176: if (i=list.length()) { i=list.length()-1; }

? // TODO .length

local.html:30: !-- TODO 2-split, 3-split --

model/TodoList.js:29:

? // TODO one op - repeated spec? long spec?

view/Footer.jsx:61: // TODO: show the entrys metadata

view/Footer.jsx:80: todoList.addObject(new TodoItem());

? // TODO create default

view/Header.jsx:25:

? // TODO list some meaningful header (apart from the id)

 

npm info start todomvc-swarm@0.0.1

todomvc-swarm@0.0.1 start /todo

node TodoAppServer.js

Swarm server started port 8000

^C   ?--- ? 在此按Ctrl+C終止進程和容器

$ docker ps –a   ?--- ? 運行這個命令查看已經啟動和移除的容器,以及其ID和狀態(就像進程一樣)

CONTAINER ID IMAGE COMMAND CREATED

? STATUS PORTS NAMES

b9db5ada0461 todoapp:latest npm start 2 minutes ago

? Exited (130) 2 minutes ago example1

$ docker start example1   ?--- ? 重新啟動容器,這次是在後台運行

example1

$ docker ps -a

CONTAINER ID IMAGE COMMAND CREATED

? STATUS PORTS NAMES

b9db5ada0461 todoapp:latest npm start 8 minutes ago

? Up 10 seconds 0.0.0.0:8000-8000/tcp example1   ?--- ? 再次運行ps命令查看發生變化的狀態

$ docker diff example1   ?--- ? docker diff子命令顯示了自鏡像被實例化成一個容器以來哪些文件受到了影響

C /todo   ?--- ? 修改了/todo目錄

A /todo/.swarm

A /todo/.swarm/TodoItem

A /todo/.swarm/TodoItem/1tlOc02+A~4Uzcz

A /todo/.swarm/_log   ?--- ? 增加了/todo/.swarm目錄

A /todo/dist

A /todo/dist/LocalTodoApp.app.js

A /todo/dist/TodoApp.app.js

A /todo/dist/react.min.js

docker run子命令啟動容器?。-p標誌將容器的8000埠映射到宿主機的8000埠上,讀者現在應該可以使用瀏覽器訪問http://localhost:8000來查看這個應用程序了。--name標誌賦予了容器一個唯一的名稱,以便後面引用。最後的參數是鏡像名稱。

一旦容器啟動,我們按下CTRL-C終止進程和容器?。讀者可以運行ps命令查看被啟動且未被移除的容器?。注意,每個容器都具有自己的容器 ID 和狀態,與進程類似。它的狀態是Exited(已退出),不過讀者可以重新啟動它?。這麼做之後,注意狀態已經改變為Up(運行中),且容器到宿主機的埠映射現在也顯示出來了?。

docker diff子命令顯示了自鏡像被實例化成一個容器以來哪些文件受到了影響?。在這個示例中,修改了todo目錄?,並增加了其他列出的文件?。沒有文件被刪除,這是另一種可能性。

如讀者所見,Docker「包含」環境的事實意味著用戶可以將其視為一個實體,在其上執行的動作是可預見的。這賦予了Docker寬廣的能力——用戶可以影響從開發到生產再到維護的整個軟體生命周期。這種改變正是本文所要描述的,在實踐中展示Docker所能完成的東西。

接下來讀者將了解Docker的另一個核心概念——分層。

1.2.5 Docker分層

Docker分層協助用戶管理在大規模使用容器時會遇到的一個大問題。想像一下,如果啟動了數百甚至數千個to-do應用,並且每個應用都需要將文件的一份副本存儲在某個地方。

可想而知,磁碟空間會迅速消耗光!默認情況下,Docker在內部使用寫時複製(copy-on-write)機制來減少所需的硬碟空間量(見圖 1-9)。每當一個運行中的容器需要寫入一個文件時,它會通過將該項目複製到磁碟的一個新區域來記錄這一修改。在執行Docker提交時,這塊磁碟新區域將被凍結並記錄為具有自身標識符的一個層。

圖1-9 啟動時複製與寫時複製對比

這部分解釋了Docker容器為何能如此迅速地啟動——它們不需要複製任何東西,因為所有的數據已經存儲為鏡像。

寫時複製 寫時複製是計算技術中使用的一種標準的優化策略。在從模板創建一個新的(任意類型)對象時,只在數據發生變化時才能將其複製進來,而不是複製整個所需的數據集。依據用例的不同,這能省下相當可觀的資源。

圖1-10展示了構建的to-do應用,它具有我們所感興趣的3層。

因為層是靜態的,所以用戶只需要在想引用的鏡像之上進行構建,變更的內容都在上一層中。在這個to-do應用中,我們從公開可用的node鏡像構建,並將變更疊加在最上層。

圖1-10 Docker中to-do應用的文件系統分層

所有這3層都可以被多個運行中的容器共享,就像一個共享庫可以在內存中被多個運行中的進程共享一樣。對於運維人員來說,這是一項至關重要的功能,可以在宿主機上運行大量基於不同鏡像的容器,而不至於耗盡磁碟空間。

想像一下,你將所運行的to-do應用作為在線服務提供給付費用戶,可以將服務擴散給大量用戶。如果你正在開發中,可以一下在本地機器上啟動多個不同的環境。如果你正在進行測試,可以比之前同時運行更多測試,速度也更快。有了分層,所有這些東西都成為了可能。

通過使用Docker構建和運行一個應用程序,讀者開始見識到Docker能給工作流帶來的威力。重現並分享特定的環境,並能在不同的地方落地,讓用戶在開發過程中兼具靈活性和可控性。

1.3 小結

依據讀者以往的Docker經驗不同,本文可能存在一個陡峭的學習曲線。我們在短時間內討論了大量的基礎內容。

讀者現在應該:

  • 理解Docker鏡像是什麼;
  • 知道Docker分層是什麼,以及為什麼它很有用;
  • 能夠從一個基礎鏡像提交一個新的Docker鏡像;
  • 知道Dockerfile是什麼。

我們已經使用這項知識:

  • 創建了一個有用的應用程序;
  • 毫不費力地重現了一個應用程序中的狀態。

接下來,我們將介紹幾個有助於讀者理解Docker如何工作的技巧,然後討論有關Docker用法的一些更廣泛的技術爭論。前兩個介紹性的章節構成了本文其餘部分的基礎,後者涵蓋了從開發到生產的全過程,展示如何使用Docker來提升工作流。


本文摘自:《Docker實踐》

Docker實踐-圖書 - 非同步社區

101個實用技巧,重點解決Docke應用中可能出現的問題

一本Docker技術的進階讀物

這是一本涵蓋了101 個技巧的實操指南,讀者可以用它來獲得Docker 的大部分知識。本書遵循手冊風格的「問題/ 解決方案/ 討論」模式,針對最重要的問題,如輕鬆的伺服器管理和配置、部署微服務、為實驗而創建安全的環境等,為讀者提供了及時有用的解決方案。在閱讀本書的過程中,讀者不但能學到Docker 的基礎知識,還能學到Docker 的最佳實踐,如將Docker 和持續集成過程結合使用、使用Chef 來自動化複雜容器的創建過程以及使用Kubernetes 進行容器編排等。

本書針對的是具有一定Docker知識的中級開發人員。如果讀者對本書的基礎部分較熟悉,可隨意跳到後續章節。本書的目標是揭示Docker所帶來的現實世界的挑戰,並展示其解決之道。不過,首先我們將提供一個Docker自身的快速回顧。如果讀者想了解更全面的Docker基礎,請查閱Jeff Nickoloff編寫的《Docker in Action》一書(Manning Publications,2016)。

在「非同步圖書」後台回復「關注」,即可免費獲得2000門在線視頻課程;推薦朋友關注根據提示獲取贈書鏈接,免費得非同步圖書一本。趕緊來參加哦!

掃一掃上方二維碼,回復「關注」參與活動!

今日話題:你是從事什麼職業的?

轉發本文到朋友圈,非同步圖書君將選出1名讀者贈送文中新書一本。1.8日抽獎選出。

昨日獲獎讀者:哈皮阿獃

請獲獎讀者,在表單中填寫獲獎信息wenjuan.in/s/m2iaqif/

點擊閱讀原文,購買《Docker實踐》


推薦閱讀:

TAG:Docker | DockerCompose | Docker容器与容器云书籍 |