架構雜談《八》

AjuPrince發表於2019-07-29

架構雜談《八》

Docker 架構 

一、Docker 引擎的三大元件

  1)Docker 後臺服務(Docker Daemon):是長時間執行在後臺的守護程式,是Docker的核心服務,可以通過命令dockerd與它進行互動通訊。

  2)REST 介面(REST API):程式可以通過REST的介面來訪問後臺服務或向它傳送操作指令。

  3)互動式命令列介面(Docker CLI):我們大多數時間都在使用命令列介面與Docker進行互動(以docker為開頭的所有命令的操作)而命令列介面又是通過呼叫REST的介面來控制和操作Docker後臺服務的。

  Docker 是C/S結構的架構,客戶端通過與後臺服務互動來編譯、執行和釋出容器。Docker的客戶端可以連線到本機的Docker服務上也可以連線到遠端的Docker服務上。Docker客戶端是使用REST介面來和後臺服務通訊的,它通過使用UNIX Socket連線或者網路介面實現。

  (1)Docker 後臺服務監聽REST介面的請求,管理Docker的物件(如:Docker的映象、容器、網路和磁碟卷)。一個Docker後臺服務可以和其他Docker後臺服務進行通訊。從而對它們進行管理。

  (2)Docker客戶端(Docker Client)是我們和Docker後臺服務互動的主要工具,在使用docker run 命令時,客戶端把命令傳送到Docker後臺服務,再由後臺服務執行該命令。Docker客戶端可以連線多個後臺服務並與它們通訊。

  (3)Docker倉庫(Docker Registry)是用來儲存Docker映象的,Docker Hub和Docker Cloud是所有人都能夠使用的公共的Docker倉庫。Docker預設從Docker Hub下載映象,當然我們也可以自己搭建私有倉庫。當我們使用 docker pull 或 docker run 命令時,就會從我們配置的 Docker 倉庫下載映象,當使用 docker push 命令時,我們的映象會被推送到Docker倉庫中。

  (4)Docker物件(Docker Object)包括映象、容器、網路、磁碟卷和外掛等。我們在使用Docker時,就會建立和使用Docker物件。

      a)映象(image)是隻讀的指令模板,用於建立Docker容器(container)通常一個映象會繼承另一個映象,然後擴充套件自定義的指令,如,我們可以建立一個繼承自Ubuntu的映象,再安裝一個 Apache Tomcat服務和自己的應用程式,同時修改些配置使我們的程式能夠執行起來。為了建立自己的映象,我們可以建立一個Dockerfile檔案,通過一些簡單的指令來定義如何建立和執行映象,Dockerfile中的每個指令在映象中都會建立為一個層(layer),當我們修改Dockerfile檔案然後重新編譯它時,僅有那些被修改的層(layer)才會被重新編譯,這就是Docker映象是輕量級的、體積非常小、速度非常塊的原因。

      b)容器(container)是映象執行的一個例項,我們可以使用Docker的API或CLI來建立、執行、停止、移動或者刪除容器。我們可以為容器繫結一個或多個網路(network)或掛載一個磁碟卷(volume),也可以通過繼承它來建立一個新的映象。通常一個容器與另一個容器或它的宿主機都是相對獨立和隔離的。在容器停止執行後,它其中的所有改變的狀態如果沒有儲存則都會消失。

      c)Docker服務(server)允許我們在多個Docker後臺服務中伸縮擴充套件容器,這些容器組成一個擁有多主多從模式的叢集。叢集中的每個成員都是一個Docker後臺服務,它們之間通過Docker介面通訊。我們可以通過Docker服務來定義叢集的引數,如:叢集中容器的副本個數。在預設情況下,叢集的負載是面向所有容器節點的。而對於使用者來說,Docker叢集就像一個大例項。

  (5)名稱空間(Namespace),Docker使用名稱空間為容器提供了很好的隔離性,當我們執行容器時,Docker會為容器建立一組名稱空間,每個容器都是一個獨立的名稱空間,容器僅僅限制於在自己的名稱空間中訪問許可權。Docker使用了Linux的如下名稱空間:

    a)pid 名稱空間(pid namespace):用來隔離程式的ID空間,使得不同的pid名稱空間裡的程式ID可以重複且相互之間不受影響。

    b)net 名稱空間(net namespace):用於管理網路協議棧的多個例項。

    c)ipc 名稱空間(ipc namespace):用於管理和訪問IPC資源。

    d)mnt 名稱空間(mnt namespace):用於管理 檔案系統的掛載點。

    e)uts 名稱空間(uts namespace):用於隔離核心和版本資訊。

  (6)cgroups(control groups),Docker 採用了一種被稱為 cgroups 的技術,實現了不同應用之間的隔離性。讓每個應用只能訪問屬於自己的資源。cgroups 可以確保將可用的硬體資源共享給所有容器,並且可以對容器限制硬體資源,如:可以限制每個容器訪問的記憶體大小。

  (7)UnionFS(Union File Systems),是Docker在建立層時採用的檔案系統。這種檔案系統使Docker變得很輕量級並且執行速度非常快。Docker可以使用多種型別的UnionFS,如:AUFS、vfs、btrfs和DeviceMapper。

  (8)容器格式(container format),Docker 將namespace、contor groups 和 UnionFS 封裝成 container format,我們將其稱為容器,預設的容器型別是libcontainer。

二、Docker的安裝

  (1):Ubuntu Docker 安裝:https://www.runoob.com/docker/ubuntu-docker-install.html

  (2):Centos Docker 安裝:https://www.runoob.com/docker/centos-docker-install.html

  (3):Windows Docker 安裝:https://www.runoob.com/docker/windows-docker-install.html

  (4):MacOS Docker 安裝:https://www.runoob.com/docker/macos-docker-install.html

三、Docker 的簡單使用

  https://www.runoob.com/docker/docker-hello-world.html

四、容器化專案

  Docker 為應用程式的打包和執行提供了一種便捷的方式,使用Docker容器進行構建、執行、停止、啟動、修改、更新等操作都非常簡單,容器化技術也可以讓應用程式像雲環境的部署變得更為高效,再加上容器本身已經包含應用程式執行所需的大部分依賴,所以執行容器的作業系統也能很好的瘦身,從而執行更快,佔用資源更少。

  1)傳統的應用部署

    傳統的應用程式部署為直接將應用程式安裝到宿主計算機的檔案系統上,然後編寫命令指令碼來執行它。從應用程式的視角來看,其環境包括宿主機上的作業系統、執行環境、檔案系統、網路配置、埠及各種依賴等。

    要讓應用程式執行起來,通常需要安裝與應用程式搭配的額外軟體包,一般來說,這不是問題。但在某些情況下,可能想在同一個系統上執行相同軟體包的不同版本,這可能會引起衝突。應用程式與應用程式之間也會以某種方式發生衝突。如果應用程式是服務,則它可能會預設繫結特定的網路埠。在服務啟動時,它可能還會讀取公共配置檔案,這會導致無法在同一宿主機上執行該服務的多個例項,或者非常棘手,這還讓那些想要繫結到同一埠的其他服務難以執行。直接在宿主機上執行應用程式還有一個缺點,那就是難以遷移應用程式。如果宿主機需要關機或者應用程式需要更多的計算能力,那麼從宿主計算機上獲取所有依賴並將其遷移到另一臺宿主機上也相當困難。

  2)將應用程式部署到虛擬機器上

    使用虛擬機器來執行應用程式,能夠避免直接在宿主機作業系統上執行應用程式所帶來的麻煩。虛擬機器是位於宿主機之上的,它作為獨立的系統執行,同時包含了自己的核心、檔案系統、網路系統等。這樣可以很好地將應用程式和宿主機的作業系統隔離開來,減少了資源、網路、埠等的衝突,因此不會出現那種直接在宿主機上執行應用程式而產生的弊端 。

    比如,可以在宿主機上啟動 5 個不同的虛擬機器來執行 5 個相同的應用程式,雖然每個虛擬機器上的服務監昕了同一個埠號,但是因為每個虛擬機器擁有不同的 IP 地址 , 所以並不會引起衝突 。
    又比如,由於各種原因,如果需要關閉宿主計算機,可以將虛擬機器遷移到其他宿主機上或者直接關閉虛擬機器並在新宿主機上再次啟動它。
    然而, 一個虛擬機器執行一個應用程式的缺點是耗費資源。我們的應用程式可能只需要幾十兆的磁碟空間來執行,但是整個虛擬機器要耗費 GB 級別的空間 。更嚴重的是虛擬機器的啟動時間和 CPU 的使用肯定會比應用程式自身消耗得多很多。
    容器提供了一種在宿主機上或虛擬機器內直接執行應用程式的方式,這種方式能使應用程式執行更快、可移植性更好,更具有擴充套件性。

  3)容器化部署

    容器化部署應用具有靈活、高效的使用資源,容器可以包含其所需的全部檔案,如同在虛擬機器上部署應用程式一樣,可以擁有自己的配置檔案和依賴庫,還可以擁有自己的網路介面。 因此,與在虛擬機器上執行應用程式一樣,容器化應用比直接安裝的應用程式更容易遷移,而且因為應用程式所執行的每個容器均擁有獨立的網路介面,所以也不會出現爭用同一埠的問題 。
    容器在啟動時間、磁碟空間佔用和 CPU 處理能力方面更具有優勢,因為它既沒有執行獨立的作業系統,也沒有包含執行整個作業系統所需的大量軟體。它只包含了應用程式執行所需的軟體,以及其他想隨容器一起執行的工具和少量描述容器的後設資料。容器的管理工具也比較完善,目前比較主流的管理工具有 : Swarm、 Kubernetes 和 Apache Mesos 。
    (1) Swarm 是 Docker 的原生叢集工具,它使用標準的 Docker API,這意味著容器能夠使用 docker run 命令啟動, Swarm 會選擇合適的主機來執行容器,這也意味著其他使用 Docker API的工具比如 Compose 也能在 Swarm 上使用,從而利用其進行叢集而不是在單個主機上執行 。
    (2) Kubemetes (經常被縮寫成 K8s )是 Google 開源的一套自動化容器管理平臺,前身是 Borg ,用於容器的部署、自動化排程和叢集管理。目前 Kubemetes 有以下特性:容器的自動化部署、自動化擴充套件或者縮容、自動化應用及服務升級、容器成組,對外提供服務,支援負載均衡 、 服務的健康檢查、自動重啟。
    (3)Apache Mesos 是由加州大學伯克利分校的 A島。Lab 首先開發的一款開源叢集管理軟體,支援 Hadoop 、Elasticsearch、 Spark、 Storm 和 Kafka 等應用架構 。

說明:

  1、參考書籍:《分散式服務架構:原理、設計與實戰》

  2、如有不合適的地方請反饋。綜合後更改。

  3、https://www.runoob.com/docker/docker-tutorial.html(Docker 入門教程)

  4、Docker:https://www.docker.com/

  

 

相關文章