1. 程式人生 > >Docker最全教程——從理論到實戰(一)

Docker最全教程——從理論到實戰(一)

容器是應用走向雲端之後必然的發展趨勢,因此筆者非常樂於和大家分享我們這段時間對容器的理解、心得和實踐。

本篇教程持續編寫了2個星期左右,只是為了大家更好地瞭解、理解和消化這個技術,能夠搭上這波車。

你可以關注我們的公眾號“magiccodes”給我們留言,也可以加入我們的QQ群(85318032)一起討論,我們希望能夠多多交流,多多分享。

如果覺得不錯,請多多點贊或者請我們喝杯咖啡,你們的支援是我們前進的最大動力!

640?wx_fmt=png

640?wx_fmt=png

 

前言

隨著生產力的發展尤其是彈性架構的廣泛應用(比如微服務),許多一流開發者都將應用託管到了應用容器上,比如Google、微軟、亞馬遜、騰訊、阿里、京東和新浪。

 

 

640?wx_fmt=png640?wx_fmt=png640?wx_fmt=png640?wx_fmt=png640?wx_fmt=png640?wx_fmt=png

從未來的發展方向來看,容器引擎將會越來越成為主流,哪怕不是彈性架構,託管到應用容器也將是一種趨勢——因為更低的開發運維和託管成本以及對伺服器的資源的優化配置。而且未來一個很大的趨勢是——無伺服器計算服務。

因為相對於軟體、硬體在本地裝置中的分裂,雲端計算的一大特性就是將服務構建在雲上,供多種裝置同時無縫呼叫。但事實上,雲服務在發展的過程中還沒能實現共融共通的理想——比如,各家的雲服務是相對割裂的,開發者基於Google雲服務構建的軟體拿到亞馬遜的AWS上也許就不能用了,阿里雲的應用遷移到騰訊雲可能就存在問題了;在任務執行層面,為防止互相干擾,雲服務廠商在同一臺伺服器上執行多個任務時也會將它們隔離進行。很明顯,這樣的實際情況和雲服務的初始理念相去甚遠。而利用容器技術,軟體可以快速在各類雲服務和基礎設施上轉換。而且,當割裂問題被解決之後,軟體也有望在瞬間獲取大量的計算能力。

640?wx_fmt=jpeg

而Docker,就是容器引擎中的佼佼者,並且已經得到了廣泛的實踐和應用。有了Docker之後,軟體的開發工作將會變得更加容易。比如,開發者們在膝上型電腦上寫完一個軟體後,可以將它轉移到雲服務上執行而無需做出更改;無論是自己的伺服器、資料中心還是Google、微軟、阿里雲的雲端計算伺服器,開發人員都可以按自己的想法在任何基礎設施之間轉移自己的軟體。這也是未來的一個願景——機器和基礎設施是可以互相替代的,整個網際網路就是一個巨大的計算機。

Docker是如此令人嚮往和引人深入,但是在國內,開發者普遍遷移到雲端基本上也都是隻用到了虛擬機器等基礎設施,其實大家都聽說過Docker,但是總是有一道門檻擋在大家面前導致大家無法逾越或者產生了一些偏見:

  • 缺乏完整的系統的教程和實踐,開發者普遍認為使用Docker很麻煩,只有大公司能用,門檻很高;

  • 雲端容器服務產品使用者體驗不夠,對於初學者門檻太高——這個太高指的是消化這些概念和理念,並且能夠掌握和可控;

  • 對容器服務的認知還不夠,對它的好處以及吸引之處還不太瞭解;

  • 認為對現有系統、架構改造太大,成本太高;

  • 認為Docker只是一種單純的相對先進的技術,並不能給現有的開發帶來什麼改變;

 

什麼是Docker

Docker 是一個開源的應用容器引擎,可以輕鬆的為任何應用建立一個輕量級的、可移植的、自給自足的容器。開發者在本地編譯測試通過的容器可以批量地在生產環境中部署,包括VMs(虛擬機器)、bare metal、OpenStack 叢集和其他的基礎應用平臺。

簡單的理解,Docker類似於集裝箱,各式各樣的貨物,經過集裝箱的標準化進行託管,而集裝箱和集裝箱之間沒有影響。也就是說,Docker平臺就是一個軟體集裝箱化平臺,這就意味著我們自己可以構建應用程式,將其依賴關係一起打包到一個容器中,然後這容器就很容易運送到其他的機器上進行執行,而且非常易於裝載、複製、移除,非常適合軟體彈性架構。

640?wx_fmt=jpeg

因此,就像船隻、火車或卡車運輸集裝箱而不論其內部的貨物一樣,軟體容器充當軟體部署的標準單元,其中可以包含不同的程式碼和依賴項。 按照這種方式容器化軟體,開發人員和 IT 專業人員只需進行極少修改或不修改,即可將其部署到不同的環境。

總而言之,Docker 是一個開放平臺,使開發人員和管理員可以在稱為容器的鬆散隔離的環境中構建映象、交付和執行分散式應用程式。以便在開發、QA 和生產環境之間進行高效的應用程式生命週期管理。

Docker和虛擬機器的區別

640?wx_fmt=png640?wx_fmt=png640?wx_fmt=png

如上圖所示,由於容器所需的資源要少得多(例如,它們不需要一個完整的 OS),所以它們易於部署且可快速啟動。這使你能夠具有更高的密度,也就是說,這允許你在同一硬體單元上執行更多服務,從而降低了成本。

在同一核心上執行的副作用是,你獲得的隔離比 VM 要少。

映象的主要目標是使環境(依賴項)在不同的部署中保持不變。 也就是說,可以在計算機上除錯它,然後將其部署到保證具有相同環境的另一臺計算機上。

藉助容器映象,可打包應用或服務並採用可靠且可重現的方式對其進行部署。可以說 Docker 不只是一種技術,還是一種原理和過程。

在使用Docker之前,我們經常會聽到,“這個問題在開發環境是正常的!”。而在使用 Docker 後,你不會聽到開發人員說:“為什麼它能在我的計算機上使用卻不能用在生產中?”。開發人員只需說“它在 Docker 上執行”,因為打包的 Docker 應用程式可在任何支援的 Docker 環境上執行,而且它在所有部署目標(例如,開發、QA、暫存和生產)上都按預期執行。

基本概念

 

映象:一個特殊的檔案系統

作業系統分為核心和使用者空間。對於 Linux 而言,核心啟動後,會掛載 root 檔案系統為其提供使用者空間支援。而 Docker 映象(Image),就相當於是一個 root 檔案系統。

Docker 映象是一個特殊的檔案系統,除了提供容器執行時所需的程式、庫、資源、配置等檔案外,還包含了一些為執行時準備的一些配置引數(如匿名卷、環境變數、使用者等)。

映象不包含任何動態資料,其內容在構建之後也不會被改變。

Docker 設計時,就充分利用 Union FS 的技術,將其設計為分層儲存的架構。 映象實際是由多層檔案系統聯合組成。

映象構建時,會一層層構建,前一層是後一層的基礎。每一層構建完就不會再發生改變,後一層上的任何改變只發生在自己這一層。

比如,刪除前一層檔案的操作,實際不是真的刪除前一層的檔案,而是僅在當前層標記為該檔案已刪除。

在最終容器執行的時候,雖然不會看到這個檔案,但是實際上該檔案會一直跟隨映象。

因此,在構建映象的時候,需要額外小心,每一層儘量只包含該層需要新增的東西,任何額外的東西應該在該層構建結束前清理掉。

分層儲存的特徵還使得映象的複用、定製變的更為容易。甚至可以用之前構建好的映象作為基礎層,然後進一步新增新的層,以定製自己所需的內容,構建新的映象。

容器:映象執行時的實體

映象(Image)和容器(Container)的關係,就像是面向物件程式設計中的類和例項一樣,映象是靜態的定義,容器是映象執行時的實體。容器可以被建立、啟動、停止、刪除、暫停等 。

容器的實質是程序,但與直接在宿主執行的程序不同,容器程序運行於屬於自己的獨立的名稱空間。前面講過映象使用的是分層儲存,容器也是如此。

容器儲存層的生存週期和容器一樣,容器消亡時,容器儲存層也隨之消亡。因此,任何保存於容器儲存層的資訊都會隨容器刪除而丟失。

按照 Docker 最佳實踐的要求,容器不應該向其儲存層內寫入任何資料 ,容器儲存層要保持無狀態化。

所有的檔案寫入操作,都應該使用資料卷(Volume)、或者繫結宿主目錄,在這些位置的讀寫會跳過容器儲存層,直接對宿主(或網路儲存)發生讀寫,其效能和穩定性更高。

資料卷的生存週期獨立於容器,容器消亡,資料卷不會消亡。因此, 使用資料卷後,容器可以隨意刪除、重新 run,資料卻不會丟失。

640?wx_fmt=jpeg

注意:

容器在整個應用程式生命週期工作流中提供以下優點:隔離性、可移植性、靈活性、可伸縮性和可控性。 最重要的優點是可在開發和運營之間提供隔離。

 

倉庫:集中存放映象檔案的地方

映象構建完成後,可以很容易的在當前宿主上執行,但是, 如果需要在其他伺服器上使用這個映象,我們就需要一個集中的儲存、分發映象的服務,Docker Registry 就是這樣的服務。

一個 Docker Registry 中可以包含多個倉庫(Repository);每個倉庫可以包含多個標籤(Tag);每個標籤對應一個映象。

所以說,映象倉庫是 Docker 用來集中存放映象檔案的地方,類似於我們之前常用的程式碼倉庫。

通常,一個倉庫會包含同一個軟體不同版本的映象,而標籤就常用於對應該軟體的各個版本 。

我們可以通過<倉庫名>:<標籤>的格式來指定具體是這個軟體哪個版本的映象。如果不給出標籤,將以 latest 作為預設標籤。

這裡補充一下 Docker Registry 公開服務和私有 Docker Registry 的概念:

Docker Registry 公開服務是開放給使用者使用、允許使用者管理映象的 Registry 服務。

一般這類公開服務允許使用者免費上傳、下載公開的映象,並可能提供收費服務供使用者管理私有映象。

最常使用的 Registry 公開服務是官方的 Docker Hub ,這也是預設的 Registry,並擁有大量的高質量的官方映象,網址為:hub.docker.com/ 。

在國內訪問 Docker Hub 可能會比較慢,國內也有一些雲服務商提供類似於 Docker Hub 的公開服務。

除了使用公開服務外,使用者還可以在本地搭建私有 Docker Registry 。Docker 官方提供了 Docker Registry 映象,可以直接使用做為私有 Registry 服務。

 

開源的 Docker Registry 映象只提供了 Docker Registry API 的服務端實現,足以支援 Docker 命令,不影響使用。但不包含圖形介面,以及映象維護、使用者管理、訪問控制等高階功能。