Docker容器及Spring Boot微服務應用
1 什麼是Docker
1.1 Docker的出現
- 問題一:專案實施環境複雜問題
傳統專案實施過程中經常會出現“程式在我這跑得好好的,在你那怎麼就不行呢?! ”
這是一個典型的應用場景,Docker image中包含了程式需要的所有的執行時依賴,比如java的程式,肯定要在image中包含jdk;比如Python的程式,肯定要在image中包含對應版本的Python直譯器。Docker把整個執行時環境打包放到image中,所以搞定了環境依賴問題!
Docker解決了執行環境和配置問題,方便釋出,也就方便做持續整合。
- 問題二:系統多使用者的資源隔離問題
Linux本身就是個多租戶的作業系統,可以多人共用,但是如果某個程式狂吃記憶體和
所以虛擬機器出現了,做了良好的資源隔離,不同使用者之間不會相互影響。但是,虛擬機器有缺點:建立速度慢,遷移起來麻煩,因為中間加了一層guest os,有了效能損耗,很牛的物理機也就建立幾十個虛擬機器,太浪費了……
相對虛擬機器的重量級虛擬化方案, Docker出現了,讓虛擬化變得輕量了起來,建立一個container瞬間完成,秒級!
Docker是更輕量的虛擬化,節省了虛擬機器的效能損耗。
1.2 Docker概述
Docker 專案的目標是實現輕量級的作業系統虛擬化解決方案。Docker 的基礎是 Linux
在 LXC 的基礎上 Docker 進行了進一步的封裝,讓使用者不需要去關心容器的管理,使得操作更為簡便。使用者操作 Docker 的容器就像操作一個快速輕量級的虛擬機器一樣簡單。
下面的圖片比較了 Docker 和傳統虛擬化方式的不同之處,可見容器是在作業系統層面上實現虛擬化,直接複用本地主機的作業系統,而傳統方式則是在硬體層面實現。
(每個虛擬機器都將擁有自己的作業系統以及應用程式必須的執行時環境)
(多個容器公用宿主機作業系統,每個容器擁有獨立的應用程式執行時環境)
1.3 Docker的優勢
Docker 容器的啟動可以在秒級實現,這相比傳統的虛擬機器方式要快得多。 其次,
容器除了執行其中應用外,基本不消耗額外的系統資源,使得應用的效能很高,同時系統的開銷儘量小。傳統虛擬機器方式執行 10 個不同的應用就要起 10 個虛擬機器,而Docker 只需要啟動 10 個隔離的應用即可。
具體說來,Docker 在如下幾個方面具有較大的優勢。
- 更快速的交付和部署
對開發和運維(devop)人員來說,最希望的就是一次建立或配置,可以在任意地方正常執行。
開發者可以使用一個標準的映象來構建一套開發容器,開發完成之後,運維人員可以直接使用這個容器來部署程式碼。 Docker 容器很輕很快!容器的啟動時間是秒級的,大量地節約開發、測試、部署的時間。
- 更高效的虛擬化
Docker 容器的執行不需要額外的 hypervisor(虛擬化管理程式)支援,它是核心級的虛擬化,因此可以實現更高的效能和效率。
- 更輕鬆的遷移和擴充套件
Docker 容器幾乎可以在任意的平臺上執行,包括物理機、虛擬機器、公有云、私有云、個人電腦、伺服器等。 這種相容性可以讓使用者把一個應用程式從一個平臺直接遷移到另外一個。
特性 |
容器(Docker) |
虛擬機器(VM) |
啟動 |
秒級 |
分鐘級 |
硬碟使用 |
MB級 |
GB級 |
效能 |
接近原生 |
弱於 |
系統支援量 |
單機支援上千個容器 |
單機支援幾十個 |
1.4 Docker的侷限
Docker並不是全能的,設計之初也不是KVM之類虛擬化手段的替代品,簡單總結幾點:
- Docker是基於Linux 64bit的,無法在windows/unix或32bit的linux環境下使用
- LXC是基於linux kernel的,因此container的guest系統只能是linux base的
- 隔離性比KVM虛擬化方案還是有些欠缺,所有container公用一部分的執行庫
- 網路管理相對簡單,主要是基於namespace隔離
- cgroup的cpu功能相比KVM的等虛擬化方案相比難以度量
- docker對disk的管理比較有限
- container隨著使用者程序的停止而銷燬,container中的log等使用者資料不便收集
1-2,有windows base應用的是不能使用Docker的
3-5主要是看使用者的需求,到底是需要一個container還是一個VM, 同時也決定了docker作為 IaaS 不太可行
6-7雖然是docker本身不支援的功能,但是可以通過其他手段解決(disk quota, mount --bind)。總之,選用container還是vm, 就是在隔離性和資源複用性上做權衡
1.5 Docker VS VM
- 傳統虛擬化中分為兩個型別
Type-1型是指在伺服器的硬體平臺上先部署虛擬機器管理層(Hypervisor),再在Hypervisor之上生成虛擬機器,每個虛擬機器再安裝作業系統、執行庫與相關的應用.Type-1虛擬化比較常見的是VMware的vSphere、微軟的Hyper-V、Linux的KVM以及Xen.
Type-2型則在裸機之上先安裝作業系統(比如Linux或Windows),再安裝Hypervisor。Type-2的典型代表是VMware的Workstation以及Oracle的VirtualBOX。
由於Type-1型Hypervisor更接近硬體底層,所以可以降低更多的系統開銷,但就Hypervisor本身來說,仍然要有一層基本的OS“墊底”,這也是其仍然會有系統開銷的原因。
而對於容器技術來說,由於本身就源於作業系統的核心(Linux Kernel),所以也就基本不存在Hypervisor所帶來的開銷
- 容器虛擬化技術
與傳統的伺服器虛擬化相比,Docker的一重要特點就是在實現應用間隔離的同時,沒有了對於傳統虛擬化來說是必須的Hypervisor虛擬化管理層,因為從本質上來講Docker的核心與Linux是一體的。Docker的根基——LXC就是一個將Linux執行時、庫以及其他軟體執行支撐環境與相關應用進行封閉的技術。從Linux的核心來看,LXC就相當於系統的一個本地程序,實質上與一個裸機(無虛擬化)應用沒有什麼區別,從而無需額外的虛擬化指令以及相應的系統虛擬化開銷。因為在傳統的虛擬化平臺中,無論Hypervisor做得再輕薄,虛擬機器都要先經過本地的OS再透過Hypervisor呼叫伺服器的物理硬體資源,這與直接以系統程序出現的LXC相比,肯定會造成額外的效能影響。
1.6 Docker生命體系
從Docker的應用封裝架構中,可以看出其最基礎的執行核心與底層映象就源於Linux的核心,使用者可以將利用Dockerfile生成好的應用映象,上傳至遠端的Docker Registry(比如Docker公司自己運營的雲服務,或是私建的Docker Registry),也可以從Docker Registry裡下拉一個別人已經建立好的映象直接投入到容器中進行執行,相比之下Docker顯然帶給了LXC更靈活的部署與快速應變的能力
在Docker體系中,最關鍵的就是兩個——Docker Registry(通過Docker Hub進行索引)以及Docker Engine,前者在遠端(或稱雲端)負責收集與分發Docker的應用映象(Images),後者則在客戶端負責構建Docker應用容器,這明顯就是一個雲服務的AAS理念,當然使用者也可以在自己的資料中心內部建立私有的Docker Registry,以方便在私有云內迅速生成自己的Docker叢集,以應對靈活的、大規模的應用擴充套件需求。此時,也相當於在企業資料中心內部形成了一個雲+端的Docker架構。
Docker在英語裡的意思為“碼頭工人”,而其Logo就好似一艘酷似鯨魚的大船運送一堆集裝箱前往各地的碼頭。而從其理論上看,Docker就像是一個集裝箱,利用LXC技術來整合不同規模、型別、層級的應用映象,先通過集中彙總再有序的分發——每個碼頭就是一臺伺服器(或VM),大船就是Registry,碼頭的工人就是核心Engine,進行集裝箱的裝配,當然它還需要一系列的外圍的支援(比如最重要的管理)。但從總體的 場景來說,Docker的名字還是非常貼切的。
1.7 Docker 關鍵字解析
Docker Image:
Docker image是一個只讀模板,用於建立Docker容器。Image中可以包含linux作業系統、Apache或者Web應用程式等等,使用者可以下載已經建立好的Docker image,也可以建立Docker image給其他使用者使用。每個image是由很多層組成,Docker通過Union File Systems將這些層繫結在一個image中。每個image都以一個初級image做為基礎,然後通過操作指令在這些初級image上新增新層,操作指令可以是執行的命令、新增檔案或目錄或者建立可用操作環境等。這些操作指令都被儲存在“Dockerfile”檔案中。
Docker Container:
Docker image的執行例項。Docker Containers可以執行、啟動、停止或者被刪除,每個container都是隔離的安全應用平臺。
Docker registries:
Docker registries用於儲存Docker image,也分公用和私用二種。公用的Docker registry就是Docker Hub,使用者也可以建立私有的Docker registry,為其他使用者提供Docker images下載。
Dockerfiles:
Dockerfile是對Docker Container建立過程的描述指令碼。每個Dockerfile詳細說明了開始的基礎映象,以及隨後一系列在容器中執行的命令和新增到容器中的檔案。Dockerfile也可以說明容器對外的埠,啟動時的工作目錄和預設執行的命令。
LXC:(Linux Container)
Linux Container容器是一種核心虛擬化技術,可以提供輕量級的虛擬化,以便隔離程序和資源,而且不需要提供指令解釋機制以及全虛擬化的其他複雜性。相當於C++中的NameSpace。容器有效地將由單個作業系統管理的資源劃分到孤立的組中,以更好地在孤立的組之間平衡有衝突的資源使用需求。
VM:(Virtual Machines)
指通過軟體模擬的具有完整硬體系統功能的、執行在一個完全隔離環境中的完整計算機系統。
Host OS:
指物理存在的計算機上執行的作業系統。宿主機作業系統。
Guest OS:
指執行在VM上的作業系統。例如在一臺安裝了Windows NT的計算機上安裝了Vmware,那麼,HOST指的是安裝Windows NT的這臺計算機,其Host′s OS為Windows NT。VM上執行的是Linux,那麼Linux即為Guest OS。
Hypervisor:
Hypervisor是一種執行在物理伺服器和作業系統之間的中間軟體層,可允許多個作業系統和應用共享一套基礎物理硬體,因此也可以看作是虛擬環境中的“元”作業系統,它可以協調訪問伺服器上的所有物理裝置和虛擬機器,也叫虛擬機器監視器。當伺服器啟動並執行Hypervisor時,它會給每一臺虛擬機器分配適量的記憶體、CPU、網路和磁碟,並載入所有虛擬機器的客戶作業系統。
目前市場主要廠商及產品:VMware vSphere、微軟Hyper-V、Citrix XenServer 、IBM PowerVM、Red Hat Enterprise Virtulization、Huawei FusionSphere、開源的KVM、Xen、VirtualBSD等。
Bootfs:(Boot File System)
主要包含 bootloader 和 kernel, bootloader主要是引導載入kernel, 當boot成功後 kernel 被載入到記憶體中後 bootfs就被解除安裝了.
Rootfx:(Root File System)
rootfs包含的就是典型 Linux 系統中的 /dev(外設訪問介面資訊),/proc(系統裝置資訊),/bin(系統工具集), /etc(APP配置資訊) 等標準目錄和檔案。對於不同的linux發行版, bootfs基本是一致的, 但rootfs會有差別, 因此不同的發行版可以公用bootfs。
2 Docker及微服務架構
2.1 微服務概念
微服務架構風格是一種使用一套小服務來開發單個應用的方式途徑,每個服務執行在自己的程序中,通過輕量的通訊機制聯絡,經常是基於HTTP資源API,這些服務基於業務能力構建,能夠通過自動化部署方式獨立部署,這些服務自己有一些小型集中化管理,可以是使用不同的程式語言編寫,正如不同的資料儲存技術一樣。
2.2 基於Docker的微服務架構
Docker的細粒度鬆耦合能夠讓我們用一個Docker容器裝載一個場景功能,也就是按照功能角色分類,每個Docker裡面裝一個服務或應用,一個伺服器上可以執行多個Docker,或者多個Docker分散到多個伺服器上執行。整個專案架構可以按照業務邏輯的規劃以細粒度的方式分散在各個Docker容器中,並根據HTTP REST API的方式進行整合聯動。
(Docker為基礎的微服務架構)
本圖由上到下分別由:Nginx負載均衡層,綜合業務服務層,單業務服務層,資料庫層等共同組成Docker為基礎的微服務架構。圖中每個服務節點均裝載入單獨的Docker Container中執行,並對外暴露基於Http協議的Port供外界訪問(資料庫容器仍然是基於JDBC的資料庫連線池方式對其訪問)。
- 負載均衡及反向代理層:可採用Nginx作為負載均衡及反向代理伺服器,並且作為靜態資源(HTML,影象檔案,JS/CSS等靜態資源)訪問的伺服器。Nginx的反向代理配置功能強大,可以根據使用者訪問路徑或訪問的服務資源進行路由轉發,將使用者的請求對映到其下的綜合業務服務層對應的REST API介面中。
- 綜合業務服務層:綜合業務服務層是根據專案具體業務需求劃分的多個單業務服務節點的整合。對訪問者提供一組綜合性業務邏輯REST API介面。其特點是隻通過HTTP REST API方式呼叫其下的單業務服務層介面,而不與資料庫通訊。
- 單業務服務層:單業務服務層中每個服務節點都是對業務邏輯相對獨立,功能相對集中一組REST API的封裝。其特點是業務功能相對獨立,與其他兄弟節點的功能耦合度低,並直接訪問其下的資料庫儲存層。
- 資料庫儲存層:以Docker Contain為單位的資料儲存層。
此框架實現重點為,在專案前期通過詳細的功能需求分析並按業務邏輯的耦合度劃分成多個服務節點,依靠Docker的獨立且低耦合特性在物理層面上實現專案的細粒度分解。
其優點是:
- 1.可以根據使用者的訪問併發量在每個層次進行水平動態擴充,實現訪問壓力負載均衡。
- 2.對業務邏輯的多層次劃分可很大程度上提高專案的複用性。
- 3.一旦將業務抽象成產品後,即可實現“使用者按功能選購”的能力。
- 4.由於Docker的開發環境封裝特性,可以簡化專案部署成本,減少運維人員工作負擔。
- 5.由於服務節點採用HTTP REST API的通訊方式,節點的實現可以採用不同執行時環境不同語言不同架構,比如可採用Spring,Play等多種架構方式。
缺點為,在專案設計前期,需要花費較多的時間進行詳細的業務邏輯劃分及系統分析。
接下來,我們將實現該架構圖中的每個Docker節點的關鍵技術。
3 Docker 與 Spring Boot
3.1 Spring Boot 簡介
Spring Boot充分利用了JavaConfig的配置模式以及“約定優於配置”的理念,能夠極大的簡化基於Spring MVC的Web應用和REST服務開發。
Spring 4倡導微服務的架構,微服務架構倡導將功能拆分到離散的服務中,獨立地進行部署,Spring Boot能夠很方便地將應用打包成獨立可執行的JAR<