現在一聊到容器技術,大家就默認是指 docker 了。但事實上,在 Docker 出現之前,PaaS社區早就有容器技術了,以 Cloud Foundry、OpenShift 為代表的就是當時的主流。
婁星網站制作公司哪家好,找成都創新互聯公司!從網頁設計、網站建設、微信開發、APP開發、成都響應式網站建設公司等網站項目制作,到程序開發,運營維護。成都創新互聯公司于2013年創立到現在10年的時間,我們擁有了豐富的建站經驗和運維經驗,來保證我們的工作的順利進行。專注于網站建設就選成都創新互聯公司。那為啥最終還是 Docker 火起來了呢?
因為傳統的PaaS技術雖然也可以一鍵將本地應用部署到云上,并且也是采用隔離環境(容器)的形式去部署,但是其兼容性非常的不好。因為其主要原理就是將本地應用程序和啟停腳本一同打包,然后上傳到云服務器上,然后再在云服務器里通過腳本啟動這個應用程序。
這樣的做法,看起來很理想。但是在實際情況下,由于本地與云端的環境差異,導致上傳到云端的應用經常各種報錯、運行不起來,需要各種修改配置和參數來做兼容。甚至在項目迭代過程中不同的版本代碼都需要重新去做適配,非常耗費精力。
然而 Docker 卻通過一個小創新完美的解決了這個問題。在 Docker 的方案中,它不僅打包了本地應用程序,而且還將本地環境(操作系統的一部分)也打包了,組成一個叫做「 Docker鏡像 」的文件包。所以這個「 Docker鏡像 」就包含了應用運行所需的全部依賴,我們可以直接基于這個「 Docker鏡像 」在本地進行開發與測試,完成之后,再直接將這個「 Docker鏡像 」一鍵上傳到云端運行即可。
Docker 實現了本地與云端的環境完全一致,做到了真正的一次開發隨處運行。
一、容器到底是什么?
容器到底是什么呢?也許對于容器不太了解,但我們對虛擬機熟悉啊,那么我們就先來看一下容器與虛擬機的對比區別:
上圖的左側是虛擬機的原理,右側是docker容器的原理。
虛擬機是在宿主機上基于 Hypervisor 軟件虛擬出一套操作系統所需的硬件設備,再在這些虛擬硬件上安裝操作系統 Guest OS,然后不同的應用程序就可以運行在不同的 Guest OS 上,應用之間也就相互獨立、資源隔離了,但是由于需要 Hypervisor 來創建虛擬機,且每個虛擬機里需要完整的運行一套操作系統 Guest OS,因此這個方式會帶來很多額外資源的開銷。
而 Docker容器 中卻沒有 Hypervisor 這一層,雖然它需要在宿主機中運行 Docker Engine,但它的原理卻完全不同于 Hypervisor,它并沒有虛擬出硬件設備,更沒有獨立部署全套的操作系統 Guest OS。
Docker容器沒有那么復雜的實現原理,它其實就是一個普通進程而已,只不過它是一種經過特殊處理過的普通進程。
我們啟動容器的時候(docker run …),Docker Engine 只不過是啟動了一個進程,這個進程就運行著我們容器里的應用。但 Docker Engine 對這個進程做了一些特殊處理,通過這些特殊處理之后,這個進程所看到的外部環境就不再是宿主機的那個環境了(它看不到宿主機中的其它進程了,以為自己是當前操作系統唯一一個進程),并且 Docker Engine 還對這個進程所使用得資源進行了限制,防止它對宿主機資源的無限使用。
那 Docker Engine 具體是做了哪些特殊處理才有這么神奇的效果呢?
二、容器是如何做到資源隔離和限制的?
Docker容器對這個進程的隔離主要采用2個技術點:
Namespace 技術
Cgroups 技術
弄清楚了這兩個技術點對理解容器的原理非常重要,它們是容器技術的核心。
下面來詳細解釋一下:
Namespace 技術
Namespace 并不是一個什么新技術,它是Linux操作系統默認提供的API,包括 PID Namespace、Mount Namespace、IPC Namespace、Network Namespace等等。
以 PID Namespace 舉例,它的功能是可以讓我們在創建進程的時候,告訴Linux系統,我們要創建的進程需要一個新的獨立的進程空間,并且這個進程在這個新的進程空間里的PID=1,也就是說這個進程只看得到這個新進程空間里的東西,看不到外面宿主機環境里的東西,也看不到其它進程(不過這只是一個虛擬空間,事實上這個進程在宿主機里PID該是啥還是啥,沒有變化,只不過在這個進程空間里,該進程以為自己的PID=1)。
打個比方,就像是一個班級,每個人在這個班里都有一個編號,班里有90人,然后來了一位新同學,那他在班里的編號就是91,可是老師為了給這位同學特別照顧,所以在班里開辟了一塊獨立的看不到外面的小隔間,并告訴這個同學他的編號是1,由于這位同學在這個小空間里隔離著,所以他真的以為自己就是班上的第一位同學且編號為1,當然了,事實上這位同學在班上的編號依然是91。
另外,Network Namespace 的技術原理也是類似的,讓這個進程只能看到當前Namespace空間里的網絡設備,看不到宿主機真實情況。同理,其它 Mount、IPC等 Namespace 也是這樣。
Namespace 技術其實就是修改了應用進程的視覺范圍,但應用進程的本質卻沒有變化。
不過,Docker容器里雖然帶有一部分操作系統(文件系統相關),但它并沒有內核,因此多個容器之間是共用宿主機的操作系統內核的。這一點與虛擬機的原理是完全不一樣的。
Cgroups 技術
Cgroup 全稱是 Control Group,其功能就是限制進程組所使用的資源(這些資源可以是 CPU、內存、磁盤等等)。
既然 Namespace 技術 只能改變一下進程組的視覺范圍,并不能真實的對資源做出限制。那么為了防止容器(進程)之間互相搶資源,甚至某個容器把宿主機資源全部用完導致其它容器也宕掉的情況發生。因此,必須采用 Cgroup 技術對容器的資源進行限制。
Cgroup 技術也是Linux默認提供的功能,在Linux系統的 /sys/fs/cgroup 下面有一些子目錄 cpu、memory等,Cgroup技術提供的功能就是可以基于這些目錄實現對這些資源進行限制。
例如:在 /sys/fs/cgroup/cpu 下面創建一個 dockerContainer 子目錄,系統就會自動在這個新建的目錄下面生成一些配置文件,這些配置文件就是用來控制資源使用量的。例如可以在這些配置文件里面設置某個進程ID對CPU的使用率。
Cgroup 對其它內存、磁盤等資源也是采用同樣原理做限制。
三、容器的鏡像是什么?
一個基礎的容器鏡像其實就是一個 rootfs,它包含操作系統的文件系統(文件和目錄),但并不包含操作系統的內核。
rootfs 是在容器里根目錄上掛載的一個全新的文件系統,此文件系統與宿主機的文件系統無關,是一個完全獨立的,用于給容器進行提供環境的文件系統。
對于一個Docker容器而言,需要基于 pivot_root 指令,將容器內的系統根目錄切換到rootfs上,這樣,有了這個 rootfs,容器就能夠為進程構建出一個完整的文件系統,且實現了與宿主機的環境隔離,也正是有了rootfs,才能實現基于容器的本地應用與云端應用運行環境的一致。
另外,為了方便鏡像的復用,Docker 在鏡像中引入了層(Layer)的概念,可以將不同的鏡像一層一層的迭在一起。這樣,如果我們要做一個新的鏡像,就可以基于之前已經做好的某個鏡像的基礎上繼續做。
如上圖,這個例子中最底層是操作系統引導,往上一層就是基礎鏡像層(Linux的文件系統),再往上就是我們需要的各種應用鏡像,Docker 會把這些鏡像聯合掛載在一個掛載點上,這些鏡像層都是只讀的。只有最上面的容器層是可讀可寫的。
這種分層的方案其實是基于 聯合文件系統UnionFS(Union File System)的技術實現的。它可以將不同的目錄全部掛載在同一個目錄下。舉個例子,假如有文件夾 test1 和 test2 ,這兩個文件夾里面的文件 有相同的,也有不同的。然后我們可以采用聯合掛載的方式,將這兩個文件夾掛載到 test3 上,那么 test3 目錄里就有了 test1 和 test2 的所有文件(相同的文件有去重,不同的文件都保留)。
這個原理應用在Docker鏡像中,比如有2個同學,同學A已經做好了一個基于Linux的Java環境的鏡像,同學S想搭建一個Java Web環境,那么他就不必再去做Java環境的鏡像了,可以直接基于同學A的鏡像在上面增加Tomcat后生成新鏡像即可。
以上,就是對微服務架構之「 容器技術 」的一些思考。
當前文章:微服務架構之「容器技術」
轉載注明:http://vcdvsql.cn/article4/chdeoe.html
成都網站建設公司_創新互聯,為您提供定制網站、營銷型網站建設、動態網站、移動網站建設、網站營銷、自適應網站
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯