用容器重新定義 Java 虛擬化部署

容器是一個用于構(gòu)建、分發(fā)、運(yùn)行分布式應(yīng)用的開源平臺。容器化的應(yīng)用可以在開發(fā)者的電腦上運(yùn)行,并能夠被部署到生產(chǎn)的云環(huán)境中,容器正以前所未有的方式在持續(xù)集成和持續(xù)部署中發(fā)揮著巨大作用。希云認(rèn)為:在未來的工作中,容器這個平臺是每個開發(fā)者都應(yīng)該熟悉的。

開源 Java項目把容器帶給 Java 開發(fā)者,后面會解釋為什么容器對 Java 開發(fā)者那么重要,引導(dǎo)大家在容器中安裝并部署 Java 應(yīng)用,并讓大家看到如何把容器集成到構(gòu)建流程中。

容器快速指南

容器有它自己的術(shù)語,這些術(shù)語會在本文中反復(fù)用到,請先花一些時間去熟悉它們:

容器引擎( Docker engine ):在服務(wù)器上的一個守護(hù)進(jìn)程,它是你和容器應(yīng)用與所依賴的操作系統(tǒng)的橋梁。

Dockerfile: 一個文本文件,內(nèi)容是用于構(gòu)建容器鏡像的指令。

鏡像: 構(gòu)建一個 Dockerfile 的產(chǎn)物,構(gòu)建過程中執(zhí)行 Dockerfile 中的命令,會生成一個鏡像。它首先會基于一個根系統(tǒng)(基礎(chǔ)鏡像)構(gòu)建,然后安裝應(yīng)用,接著執(zhí)行一系列命令來準(zhǔn)備啟動應(yīng)用的環(huán)境。 Docker 鏡像作為容器的基礎(chǔ),相當(dāng)于容器的一個靜態(tài)模塊。

容器: 一個 Docker 鏡像的運(yùn)行時實例, Docker 鏡像類似于模塊的概念(從 Dockerfile 構(gòu)建,這個 Dockerfile 包含了根系統(tǒng),應(yīng)用以及一系列構(gòu)建鏡像的命令),容器是那個鏡像的一個實際能運(yùn)行的實例。

宿主 : 一個物理機(jī)或者虛擬機(jī),在此系統(tǒng)上運(yùn)行著容器引擎,維持著容器所依賴的 Dockerhub 。

DockerHub : 官方的 Docker 鏡像倉庫,把 DockerHub 想象為 GitHub 倉庫,對于 Git 來說是中央倉庫, DockerHub 是官方保存及提供 Docker 鏡像的中央倉庫。

cSphereHub: 希云官方的 Docker 微鏡像倉庫, DockerHub 中有非常多的鏡像,但 cSphereHub 中存放了精心挑選出來的,并精心制作的鏡像。

Docker 簡介

在二十多年前,軟件應(yīng)用曾經(jīng)是非常龐大并且復(fù)雜的,會被部署在大型的計算機(jī)上。在 Java 的世界里邊,我們開發(fā)的企業(yè)軟件包( EAR )中,包含企業(yè) JavaBean( EJB ) 和 web 組件( WAR ),然后會部署在大型應(yīng)用服務(wù)器上。為了能盡量有效地利用這些大型計算機(jī)上的資源,我們會盡最大能力去設(shè)計這些應(yīng)用。

在 21 世紀(jì)早期,隨著云計算的出現(xiàn),開發(fā)者們開始使用虛擬機(jī)以及服務(wù)器集群,去擴(kuò)展應(yīng)用以滿足需求。要以虛擬化的方式部署應(yīng)用,應(yīng)用必須被設(shè)計得與傳統(tǒng)方式有所不同,輕量級,面向?qū)ο蟮膽?yīng)用成為新標(biāo)準(zhǔn)。我們學(xué)會了把軟件做成各種能互聯(lián)的服務(wù)集合,將各組件盡可能地設(shè)計成無狀態(tài)。可擴(kuò)展架構(gòu)的概念和實現(xiàn)都發(fā)生了變化,不再是依賴于單臺大型計算機(jī)的垂直擴(kuò)展,開發(fā)者和架構(gòu)師開始思考以水平擴(kuò)展方式實現(xiàn):如何把單個應(yīng)用部署到數(shù)個輕量級的計算機(jī)上。

容器的出現(xiàn)使虛擬化更向前邁進(jìn)了一步,提供了一個輕量級的層,處于應(yīng)用和所依賴的硬件中間,容器把應(yīng)用當(dāng)作是宿主系統(tǒng)的一個進(jìn)程來運(yùn)行。圖一對比了傳統(tǒng)虛擬機(jī)和容器。

圖1 虛擬機(jī)與容器的比較

傳統(tǒng)的虛擬機(jī)會在宿主系統(tǒng)運(yùn)行著一個虛擬機(jī)監(jiān)視器,并在虛擬機(jī)中運(yùn)行著一個完整的客戶系統(tǒng)( GuestOS ),應(yīng)用依賴的所有包都在客戶系統(tǒng)中。

相反地, 容器有個容器引擎,也是一個運(yùn)行在宿主系統(tǒng)的守護(hù)進(jìn)程。容器引擎把容器中的系統(tǒng)調(diào)用,翻譯成宿主系統(tǒng)的原生調(diào)用。一個 Docker 鏡像,作為容器的創(chuàng)建模板,只是包含了操作系統(tǒng)的最小層,以及僅僅是應(yīng)用所需要的依賴庫。

大家看起來感覺這些差異似乎不大,但實際上卻是天壤之別。容器的優(yōu)勢很大一部分都是在這點(diǎn)體現(xiàn)出來的!

理解進(jìn)程虛擬化

我們仔細(xì)分析一下虛擬機(jī)中的操作系統(tǒng),我們會留意到虛擬機(jī)中的資源,例如 CPU 和內(nèi)存。但當(dāng)我們運(yùn)行一個容器,我們會直接看到宿主機(jī)上的資源。我把容器看成是進(jìn)程級的虛擬化平臺,而不是系統(tǒng)級的虛擬化平臺。基本上,應(yīng)用是作為一個獨(dú)立的自包含進(jìn)程運(yùn)行在宿主機(jī)上,容器通過借助著 Linux 上幾個強(qiáng)大的組件,實現(xiàn)了隔離性,確保了每個進(jìn)程都是操作系統(tǒng)上的獨(dú)立進(jìn)程。

因為容器化的應(yīng)用與宿主機(jī)上的進(jìn)程運(yùn)行方式類似,所以設(shè)計上也和虛擬機(jī)中的應(yīng)用不同。舉個例子說,我們通常會在一個虛擬機(jī)上運(yùn)行 Tomcat 和 MySQL 數(shù)據(jù)庫,但容器的實踐中,我們會把 app 服務(wù)器與數(shù)據(jù)庫分別部署,各自運(yùn)行在不同的容器中。這樣讓容器更好地管理宿主系統(tǒng)上的獨(dú)立單元,這意味著要更有效率地使用容器,我們需要以適當(dāng)?shù)牧6仍O(shè)計應(yīng)用,例如微服務(wù)的方式。

Docker 中的微服務(wù)

簡單來說,微服務(wù)是一種可以促進(jìn)系統(tǒng)模塊化的架構(gòu)方式。在微服務(wù)架構(gòu)中,復(fù)雜的應(yīng)用以更小的獨(dú)立進(jìn)程組成,各個進(jìn)程有一個或多個特定的功能,應(yīng)用與語言無關(guān)的API和其他進(jìn)程通信。

微服務(wù)是通過粒度非常小,高度解耦的服務(wù)集合,來提供單一或多個相關(guān)聯(lián)的功能。例如,如果你正在管理著一個用戶中心和購物車,那你很可能是選擇把它們設(shè)計成獨(dú)立的服務(wù),如用戶中心服務(wù)和購物車服務(wù);而不是把兩個模塊打成一個包作為一個服務(wù)運(yùn)行。更具體來說,使用微服務(wù)意味著構(gòu)建 web services,而且是最常見的RESTful web service,并把它們按功能分組。在 Java 中,我們會把這些服務(wù)打成 WAR 包,并部署到一個容器中,例如 Tomcat,然后運(yùn)行 Tomcat 和容器中的服務(wù)。

安裝容器

在我們深入研究容器之前,先讓我們把本地環(huán)境搭建起來。如果你正在使用 Linux 系統(tǒng),那非常好,你可以直接安裝并運(yùn)行容器。對于那些使用 Windows 或者 Mac 的用戶來說,容器可以通過一個叫 Docker Toolbox 的工具來使用,這個工具會安裝一個虛擬機(jī)(使用 Oracle 的 Virtual Box ),這個虛擬機(jī)中會運(yùn)行著包含容器守護(hù)進(jìn)程的 Linux 系統(tǒng)。我們可以使用容器客戶端把指令發(fā)送給守護(hù)進(jìn)程處理,注意,你不需要管理這個虛擬機(jī),只要安裝這個工具并執(zhí)行容器命令行工具即可。

開始從MacWindows,或Linux相應(yīng)的文檔里下載 Docker

我的電腦是 Mac,所以我下載并運(yùn)行了 Mac 版的 Docker Toolbox 安裝包,之后我運(yùn)行了 Docker Quickstart 終端,這樣會啟動一個 Virtual Box 鏡像和一個命令行終端。這個安裝過程與 Windows 下的基本相同,更多請參考 Windows 版的文檔。

DockerHub: Docker的鏡像倉庫

我們開始使用容器之前,先花幾分鐘去訪問一下cSphereHub,這個鏡像倉庫。瀏覽一下 cSphereHub ,你會發(fā)現(xiàn)上邊有數(shù)個鏡像,精挑細(xì)選的微鏡像。如果使用 cSphere 管理平臺,添加微鏡像倉庫后,倉庫里面包含了 docker 官方的一些鏡像。鏡像倉庫中有基礎(chǔ)系統(tǒng),如 Alpine、 Ubuntu,或者 Java 相關(guān)的如 Tomcat、 jdk、 jre 等等。你還可以發(fā)現(xiàn)幾乎所有流行的應(yīng)用上邊都會有,包括 MySQL、 MongoDB、 Neo4j、 Redis、 Memcached、 Postgres、 Nginx、 Node.js、 WordPress、 PHP、 Perl、 Ruby 等等。在你打算自行構(gòu)建一個新鏡像之前,請確認(rèn) cSphereHub 或者 DockerHub 上有沒有。

作為一個練習(xí),我們運(yùn)行一個簡單的 CentOS 鏡像,在 Docker Toolbox 的命令行中輸入:

sh $ docker run -it centos

這個容器命令是你與Docker守護(hù)進(jìn)程的主要接口。run 指令告訴容器去下載并運(yùn)行指定的鏡像(假設(shè)在本地還沒有這個鏡像)。又或者,你可以用 pull 命令直接下載一個鏡像但不運(yùn)行它。有兩個參數(shù):i 會讓Docker用交互模式運(yùn)行,t 會讓它創(chuàng)建一個TTY終端。注意非官方的鏡像使用既定的格式"用戶名/鏡像名",而官方的鏡像會省略用戶名,所以我們只需要指定"centos"來運(yùn)行鏡像即可。另外,也可以在鏡像名后加“:版本號”指定版本號,例如,centos:7。每個鏡像默認(rèn)使用的都是最新版本,當(dāng)前CentOS最新版本號是7.

在運(yùn)行$ docker run -it centos 之后,你會見到Docker開始下載這個鏡像,完成后會見到類似以下的輸出:

sh$dockerrun-itcentos[root@dcd69de89aad/]#

因為我們用了交互模式去運(yùn)行,它顯示了一個 root 用戶的 shell 命令提示符。查看一下這個系統(tǒng),然后使用exit退出。

可以用docker images命令來查看系統(tǒng)中已下載好的鏡像:

sh $ docker imagesREPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZEjava 8 5282faca75e8 4 weeks ago 817.6 MBtomcat latest 71093fb71661 8 weeks ago 347.7 MBcentos latest 7322fbe74aa5 11 weeks ago 172.2 MB

你可以看到我已經(jīng)有了的CentOS、Tomcat 和 Java 8。希云(http://csphere.cn)以后會為大家推薦更多精美文章,請大家繼續(xù)關(guān)注!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容