docker化你的java應用

Docker Java 編程語言 Linux CPU javafirst 2018-12-09

作者:張豐哲;

來源:https://www.jianshu.com/p/66d611657ed6

前言

在各種技術大會(互聯網架構,雲計算等等),哪都少不了docker的身影。docker為啥這麼火?因為它解決了大部分企業的痛點:快速的持續集成,服務的彈性伸縮,部署簡單,方便了運維,而且為企業節省了機器資源,降低了成本。現在在很多企業(騰訊/京東/阿里/小紅書等等)都大規模使用docker。作為開發工程師,咱們或多或少需要接觸docker,因為咱們的程序運行在docker容器當中,瞭解docker,有益無害。下面我們就進入docker的世界吧~

走進docker

docker是什麼?

docker化你的java應用

docker logo

docker的官網是:https://www.docker.com/,上圖是docker的logo:一條鯨魚馱著一些集裝箱在大海中遨遊!(這個logo非常有意思,蘊含了docker的核心思想,稍後分析)

docker官網對docker的一句話定義是:

“Docker is the world’s leading software containerization platform.”

(docker是全球領先的軟件容器化平臺)

大白話就是:docker是一個用來裝應用的容器,就像杯子可以裝水,書包可以放書,筆筒可以放筆....你可以把任何你想得到的程序放到docker中!

docker是跨平臺的,支持linux/macos/windows,不過docker是在ubuntu系統上開發的,對於ubuntu支持最好。

理解docker logo

docker logo裡面是一條鯨魚馱著一些集裝箱在海中遨遊。

想一下,如果沒有集裝箱,那麼貨物是零散的存放,運輸過程中說不定出現破損或者丟失,如果採用集裝箱,因為是密閉的,標準的,貨物運輸會很安全。

鯨魚,游到碼頭拿貨(取集裝箱),然後出發,運輸集裝箱到目的地。這種存儲貨物/運輸貨物的方式很標準,保證從一個地方到另一個地方,不會出現問題。

以前,A機器上運行的程序想部署一套到其他機器上去,如果採取傳統到方式進行文件拷貝等,有可能出現問題,採用集裝箱的方式進行運輸就可以避免。

既然,集裝箱是標準的,就是說它的操作也是標準的,比如打開,關閉。這就意味著我們對應用的啟動、停止等將是統一的命令。(不論是nginx,tomcat等等,它們的啟動,停止都將是統一的命令!這裡說的就是docker的api接口的標準化)

集裝箱和集裝箱之間有隔離性,就好像虛擬機似的。我們知道虛擬機可以有自己的內存/CPU/硬盤/網卡等,docker差不多,不過docker的容器更佳輕量級,它的創建、銷燬非常快。【docker的隔離性最底層還是依賴linux的lxc(Linux Container容器是一種內核虛擬化技術)機制來實現的】

docker化你的java應用

docker思想

docker的思想解決了哪些問題?

“程序在我這裡運行好好的,咋在你那裡就不行了呢?”

一個普通的java web程序跑起來,需要哪些依賴?

操作系統os/jdk/webserver/代碼/配置文件/...

比如,程序中調用了系統命令,現在os變了;

比如,jdk版本,編譯使用的是1.8版本,機器上安裝的是jdk1.6,無法識別class版本;

比如,tomcat版本,有些舊版本的配置新版本不支持;...

針對這種問題,docker的處理方式是,把os/jdk/webserver/代碼等等一個個的放到集裝箱中去,打包放到鯨魚上,由鯨魚給我們送到目的地去,也就是說docker解決了運行環境不一致帶來的問題!

“哪個大哥又寫死循環了,系統又變慢了...”

傳統的方式中,我們一臺機器上部署了很多服務,很可能由於其他服務出現死循環佔領cpu,日誌狂打磁盤爆滿等情況導致我們自己的服務出現異常。

而docker的隔離性可以完全避免這樣的問題,因為docker在啟動的時候,就給限定了最大能使用的cpu,內存,硬盤,如果超出就kill掉。

“雙十一來了,又要部署幾千臺服務,過完節後,還得下線這麼多,累死了...”

對於大部分系統而言,流量並不是均勻的,比如電商系統,在11.11大促期間,就需要臨時擴容機器,之後在下掉,如果是成百上千臺,那就給運維帶來非常大的工作量,有了docker就變得簡單了,從5臺服務器變成500臺,5000臺...都是分分鐘的事情。(也就是說docker解決了快速擴容,彈性伸縮)

docker的三大核心概念

在上面我們大白話說了那麼多,現在我們需要用專業術語來揭開docker的3大核心概念了:鏡像/倉庫/容器。

鏡像(images),就是上面我們說的集裝箱;

倉庫(repository),就是碼頭;

容器(container),就是運行程序的地方;

docker運行一個程序的過程是:去倉庫把鏡像拉到本地,然後用命令把鏡像運行起來,變成容器!(build構建鏡像;ship運輸鏡像;run運行的鏡像就是一個容器)

docker化你的java應用

簡單示例它們之間的關係

本質來說,鏡像就是一系列的文件,docker利用linux的ufs(聯合文件系統)機制進行存儲來達到分層的效果。比如/test1目錄下有a和b兩個文件,test2目錄下有c和d兩個文件,那麼利用ufs可以達到/test下有a、b、c、d四個文件,即ufs是一種分層的文件系統,可以將不同的目錄掛到同一個虛擬文件系統下。每一層鏡像層加載完畢後,會被看成同一個目錄,相當於只有一個文件系統,docker的這種文件系統就被稱作為鏡像。

容器,上面已經提及過,就是一個進程,可以把容器想象成一個虛擬機,會有自己的文件系統。注意容器是可寫的,而鏡像是隻讀的,因為運行中的程序大部分有寫的需求,比如寫日誌,修改一些文件什麼的。如果容器需要對鏡像層的某些文件作修改,該如何處理呢?那麼就把鏡像層中的文件拷貝到容器中,在容器中進行修改,當我們的應用讀取文件的時候,是從對頂層容器開始查找,如果沒有才會開始查找下一層(這樣我們就能讀取到修改的文件了。)

倉庫,這裡有點類似maven倉庫的概念,其實就是為了傳輸鏡像。https://hub.docker.com/這個是docker官網給我們提供的遠程倉庫地址,當然公司內部一般會有自己的私有鏡像中心。

上圖中,可以清楚的看到,同一個鏡像可以生成多個容器運行,容器之間是相互獨立的。

好了,到這裡,本篇博客為大家介紹了docker的一些初步知識,下一篇將帶大家實踐docker以及分析一個springboot項目的docker化。

相關推薦

推薦中...