後端技術雜談5:雲計算的前世今生

  • 2019 年 12 月 9 日
  • 筆記

作者簡介: 劉超,網易雲解決方案首席架構師。

10年雲計算領域研發及架構經驗,Open DC/OS貢獻者。

長期專註於kubernetes, OpenStack、Hadoop、Docker、Lucene、Mesos等開源軟體的企業級應用及產品化。曾出版《Lucene應用開發揭秘》。

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到我的倉庫里查看

https://github.com/h2pl/Java-Tutorial 喜歡的話麻煩點下Star哈

文章將同步到我的個人部落格:

www.how2playlife.com

該系列博文會介紹常見的後端技術,這對後端工程師來說是一種綜合能力,我們會逐步了解搜索技術,雲計算相關技術、大數據研發等常見的技術喜提,以便讓你更完整地了解後端技術棧的全貌,為後續參與分散式應用的開發和學習做好準備。

如果對本系列文章有什麼建議,或者是有什麼疑問的話,也可以關注公眾號【Java技術江湖】聯繫我,歡迎你參與本系列博文的創作和修訂。

以下為正文:

雲計算概述

雲計算主要解決了四個方面的內容:計算,網路,存儲,應用。

計算就是CPU和記憶體,例如「1+1」這個最簡單的演算法就是把「1」放在記憶體裡面,然後CPU做加法,返回的結果「2」又保存在記憶體裡面。網路就是你插根網線能上網。存儲就是你下個電影有地方放。本次討論就是圍繞這四個部分來講的。其中,計算、網路、存儲三個是IaaS層面,應用是PaaS層面。

雲計算髮展脈絡

雲計算整個發展過程,用一句話來形容,就是「分久必合,合久必分」。

第一階段:合,即物理設備

物理設備簡介

在互聯網發展初期,大家都愛用物理設備:

  1. 伺服器用物理機,像戴爾、惠普、IBM、聯想等物理伺服器,隨著硬體設備的進步,物理伺服器越來越強大了,64核128G記憶體都算是普通配置;
  2. 網路用的是硬體交換機和路由器,例如思科的,華為的,從1GE到10GE,現在有40GE和100GE,頻寬越來越牛;
  3. 存儲方面有的用普通的磁碟,也有更快的SSD盤。容量從M,到G,連筆記型電腦電腦都能配置到T,更何況磁碟陣列;

物理設備的缺點

部署應用直接使用物理機,看起來很爽,有種土豪的感覺,卻有大大的缺點:

  1. 人工運維。如果你在一台伺服器上安裝軟體,把系統安裝壞了,怎麼辦?只有重裝。當你想配置一下交換機的參數,需要串口連上去進行配置;當你想增加一塊磁碟,要買一塊插進伺服器,這些都需要人工來,而且很大可能要求機房。你們公司在北五環,機房在南六環,這酸爽。
  2. 浪費資源。其實你只想部署一個小小的網站,卻要用128G的記憶體。混著部署吧,就有隔離性的問題。
  3. 隔離性差。你把好多的應用部署在同一台物理機上,他們之間搶記憶體、搶cpu,一個寫滿了硬碟,另一個就沒法用了,一個弄掛了內核,另一個也跟著掛了,如果部署兩個相同的應用,埠還會衝突,動不動就會出錯。

第二階段:分,即虛擬化

虛擬化簡介

因為物理設備的以上缺點,就有了第一次「合久必分」的過程,叫做虛擬化。所謂虛擬化,就是把實的變成虛的:

  1. 物理機變為虛擬機。cpu是虛擬的,記憶體是虛擬的,內核是虛擬的,硬碟是虛擬的;
  2. 物理交換機變為虛擬交換機。網卡是虛擬的,交換機是虛擬的,頻寬也是虛擬的;
  3. 物理存儲變成虛擬存儲。多塊硬碟虛擬成一大塊;

虛擬化解決的問題

虛擬化很好地解決了在物理設備階段存在的三個問題:

  1. 人工運維。虛擬機的創建和刪除都可以遠程操作,虛擬機被玩壞了,刪了再建一個分鐘級別的。虛擬網路的配置也可以遠程操作,創建網卡、分配頻寬都是調用介面就能搞定的;
  2. 資源浪費。虛擬化了以後,資源可以分配地很小很小,比如1個cpu,1G記憶體,1M頻寬,1G硬碟,都可以被虛擬出來;
  3. 隔離性差。每個虛擬機都有獨立的cpu、 記憶體、硬碟、網卡,不同虛擬機之間的應用互不干擾;

虛擬化時代的生態

在虛擬化階段,領跑者是Vmware,可以實現基本的計算、網路、存儲的虛擬化。如同這個世界有閉源就有開源、有windows就有linux、有Apple就有Android一樣,有Vmware,就有Xen和KVM。

在開源虛擬化方面,Xen 的Citrix做的不錯,後來Redhat在KVM發力不少;對於網路虛擬化,有Openvswitch,可以通過命令創建網橋、網卡、設置VLAN、設置頻寬;對於存儲虛擬化,本地盤有LVM,可以將多個硬碟變成一大塊盤,然後在裡面切出一小塊給用戶。

虛擬化的缺點

但是虛擬化也有缺點。通過虛擬化軟體創建虛擬機,需要人工指定放在哪台機器上、硬碟放在哪個存儲設備上,網路的VLAN ID、頻寬的具體配置等,都需要人工指定。所以僅使用虛擬化的運維工程師往往有一個Excel表格,記錄有多少台物理機,每台機器部署了哪些虛擬機。受此限制,一般虛擬化的集群數目都不是特別大。

第三階段:合,即雲計算

雲計算解決的問題

為了解決虛擬化階段遺留的問題,於是有了分久必合的過程。這個過程我們可以形象地稱為池化。虛擬化將資源分得很細,但是如此細分的資源靠Excel去管理,成本太高。池化就是將資源打成一個大的池,當需要資源的時候,幫助用戶自動地選擇,而非用戶指定。這個階段的關鍵點:調度器Scheduler。

私有雲、公有雲的兩極分化

這樣,Vmware有了自己的Vcloud;也有了基於Xen和KVM的私有雲平台CloudStack(後來Citrix將其收購後開源)。

當這些私有雲平台在用戶的數據中心裡賣得奇貴無比、賺得盆滿缽盈的時候,有其他的公司開始了另外的選擇。這就是AWS和Google,他們開始了公有雲領域的探索。

AWS最初就是基於Xen技術進行虛擬化的,並且最終形成了公有雲平台。也許AWS最初只是不想讓自己的電商領域的利潤全部交給私有雲廠商吧,所以自己的雲平台首先支撐起了自己的業務。在這個過程中,AWS嚴肅地使用了自己的雲計算平台,使得公有雲平台並不是對資源的配置更加友好,而是對應用的部署更加友好,最終大放異彩。

私有雲廠商與公有雲廠商的聯繫與區別

如果仔細觀察就會發現,私有雲和公有雲雖然使用的是類似的技術,但在產品設計上卻是完全不同的兩種生物。

私有雲廠商和公有雲廠商也擁有類似的技術,但在產品運營上呈現出完全不同的基因。

私有雲廠商是賣資源的,所以往往在賣私有雲平台的時候伴隨著賣計算、網路、存儲設備。在產品設計上,私有雲廠商往往會對客戶強調其幾乎不會使用的計算、網路、存儲的技術參數,因為這些參數可以在和友商對標的過程中佔盡優勢。私有雲的廠商幾乎沒有自己的大規模應用,所以私有雲廠商的平台做出來是給別人用的,自己不會大規模使用,所以產品往往圍繞資源展開,而不會對應用的部署友好。

公有雲的廠商往往都是有自己大規模的應用需要部署,所以其產品的設計可以將常見的應用部署需要的模組作為組件提供出來,用戶可以像拼積木一樣,拼接一個適用於自己應用的架構。公有雲廠商不必關心各種技術參數的PK,不必關心是否開源,是否兼容各種虛擬化平台,是否兼容各種伺服器設備、網路設備、存儲設備。你管我用什麼,客戶部署應用方便就好。

公有雲生態及老二的逆襲

公有雲的第一名AWS活的自然很爽,作為第二名Rackspace就不那麼舒坦了。

沒錯,互聯網行業基本上就是一家獨大,那第二名如何逆襲呢?開源是很好的辦法,讓整個行業一起為這個雲平台出力。於是Rackspace與美國航空航天局(NASA)合作創始了開源雲平台OpenStack。

OpenStack現在發展的和AWS有點像了,所以從OpenStack的模組組成可以看到雲計算池化的方法。

OpenStack的組件

  1. 計算池化模組Nova:OpenStack的計算虛擬化主要使用KVM,然而到底在哪個物理機上開虛擬機呢,這要靠nova-scheduler;
  2. 網路池化模組Neutron:OpenStack的網路虛擬化主要使用Openvswitch,然而對於每一個Openvswitch的虛擬網路、虛擬網卡、VLAN、頻寬的配置,不需要登錄到集群上配置,Neutron可以通過SDN的方式進行配置;
  3. 存儲池化模組Cinder: OpenStack的存儲虛擬化,如果使用本地盤,則基於LVM,使用哪個LVM上分配的盤,也是通過scheduler來的。後來就有了將多台機器的硬碟打成一個池的方式Ceph,而調度的過程,則在Ceph層完成。

OpenStack帶來私有雲市場的紅海

有了OpenStack,所有的私有雲廠商都瘋了,原來VMware在私有雲市場賺的實在太多了,眼巴巴的看著,沒有對應的平台可以和他抗衡。現在有了現成的框架,再加上自己的硬體設備,幾乎所有的IT廠商巨頭,全部都加入到社區里,將OpenStack開發為自己的產品,連同硬體設備一起,殺入私有雲市場。

公有or私有?網易雲的選擇

網易雲當然也沒有錯過這次風口,上線了自己的OpenStack集群,網易雲基於OpenStack自主研發了IaaS服務,在計算虛擬化方面,通過裁剪KVM鏡像,優化虛擬機啟動流程等改進,實現了虛擬機的秒級別啟動。在網路虛擬化方面,通過SDN和Openvswitch技術,實現了虛擬機之間的高性能互訪。在存儲虛擬化方面,通過優化Ceph存儲,實現高性能雲盤。

但是網易雲並沒有殺進私有雲市場,而是使用OpenStack支撐起了自己的應用,這是互聯網的思維。而僅僅是資源層面彈性是不夠的,還需要開發出對應用部署友好的組件。例如資料庫,負載均衡,快取等,這些都是應用部署必不可少的,也是網易雲在大規模應用實踐中,千錘百鍊過的。這些組件稱為PaaS。

第四階段:分,即容器

現在來談談,應用層面,即PaaS層。

前面一直在講IaaS層的故事,也即基礎設施即服務,基本上在談計算、網路、存儲的事情。現在應該說說應用層,即PaaS層的事情了。

1. PaaS的定義與作用

IaaS的定義比較清楚,PaaS的定義就沒那麼清楚了。有人把資料庫、負載均衡、快取作為PaaS服務;有人把大數據Hadoop,、Spark平台作為PaaS服務;還有人將應用的安裝與管理,例如Puppet、 Chef,、Ansible作為PaaS服務。

其實PaaS主要用於管理應用層。我總結為兩部分:一部分是你自己的應用應當自動部署,比如Puppet、Chef、Ansible、 Cloud Foundry等,可以通過腳本幫你部署;另一部分是你覺得複雜的通用應用不用部署,比如資料庫、快取、大數據平台,可以在雲平台上一點即得。

要麼就是自動部署,要麼就是不用部署,總的來說就是應用層你也少操心,就是PaaS的作用。當然最好還是都不用去部署,一鍵可得,所以公有雲平台將通用的服務都做成了PaaS平台。另一些你自己開發的應用,除了你自己其他人不會知道,所以你可以用工具變成自動部署。

2. PaaS的優點

PaaS最大的優點,就是可以實現應用層的彈性伸縮。比如在雙十一期間,10個節點要變成100個節點,如果使用物理設備,再買90台機器肯定來不及,僅僅有IaaS實現資源的彈性是不夠的,再創建90台虛擬機,也是空的,還是需要運維人員一台一台地部署。所以有了PaaS就好了,一台虛擬機啟動後,馬上運行自動部署腳本,進行應用的安裝,90台機器自動安裝好了應用,才是真正的彈性伸縮。

3. PaaS部署的問題

當然這種部署方式也有一個問題,就是無論Puppet、 Chef、Ansible把安裝腳本抽象的再好,說到底也是基於腳本的,然而應用所在的環境千差萬別。文件路徑的差別,文件許可權的差別,依賴包的差別,應用環境的差別,Tomcat、 PHP、 Apache等軟體版本的差別,JDK、Python等版本的差別,是否安裝了一些系統軟體,是否佔用了哪些埠,都可能造成腳本執行的不成功。所以看起來是一旦腳本寫好,就能夠快速複製了,但是環境稍有改變,就需要把腳本進行新一輪的修改、測試、聯調。例如在數據中心寫好的腳本移到AWS上就不一定直接能用,在AWS上聯調好了,遷移到Google Cloud上也可能會再出問題。

容器的誕生

1. 容器的定義

於是容器便應運而生。容器是Container,Container另一個意思是集裝箱,其實容器的思想就是要變成軟體交付的集裝箱。集裝箱的特點,一是打包,二是標準。設想沒有集裝箱的時代,如果將貨物從A運到B,中間要經過三個碼頭,換三次船的話,貨物每次都要卸下船來,擺的七零八落,然後換船的時候,需要重新擺放整齊,在沒有集裝箱的時候,船員們都需要在岸上待幾天再走。而在有了集裝箱後,所有的貨物都打包在一起了,並且集裝箱的尺寸全部一致,所以每次換船的時候,整體一個箱子搬過去就可以了,小時級別就能完成,船員再也不用長時間上岸等待了。

2.容器在開發中的應用

設想A就是程式設計師,B就是用戶,貨物就是程式碼及運行環境,中間的三個碼頭分別是開發,測試,上線。假設程式碼的運行環境如下:

  1. Ubuntu作業系統
  2. 創建用戶hadoop
  3. 下載解壓JDK 1.7在某個目錄下
  4. 將這個目錄加入JAVA_HOME和PATH的環境變數裡面
  5. 將環境變數的export放在hadoop用戶的home目錄下的.bashrc文件中
  6. 下載並解壓tomcat 7
  7. 將war放到tomcat的webapp路徑下面
  8. 修改tomcat的啟動參數,將Java的Heap Size設為1024M

看,一個簡單的Java網站,就需要考慮這麼多零零散散的東西,如果不打包,就需要在開發,測試,生產的每個環境上查看,保證環境的一致,甚至要將這些環境重新搭建一遍,就像每次將貨物打散了重裝一樣麻煩。中間稍有差池,比如開發環境用了JDK 1.8,而線上是JDK 1.7;比如開發環境用了root用戶,線上需要使用hadoop用戶,都可能導致程式的運行失敗。

容器的誕生

雲計算的前世今生(上)中提到:雲計算解決了基礎資源層的彈性伸縮,卻沒有解決PaaS層應用隨基礎資源層彈性伸縮而帶來的批量、快速部署問題。於是容器應運而生。

容器是Container,Container另一個意思是集裝箱,其實容器的思想就是要變成軟體交付的集裝箱。集裝箱的特點,一是打包,二是標準。

在沒有集裝箱的時代,假設將貨物從A運到B,中間要經過三個碼頭、換三次船。每次都要將貨物卸下船來,擺的七零八落,然後搬上船重新整齊擺好。因此在沒有集裝箱的時候,每次換船,船員們都要在岸上待幾天才能走。

有了集裝箱以後,所有的貨物都打包在一起了,並且集裝箱的尺寸全部一致,所以每次換船的時候,一個箱子整體搬過去就行了,小時級別就能完成,船員再也不能上岸長時間耽擱了。這是集裝箱「打包」、「標準」兩大特點在生活中的應用。下面用一個簡單的案例來看看容器在開發部署中的實際應用。

假設有一個簡單的Java網站需要上線,程式碼的運行環境如下:

看,一個簡單的Java網站,就有這麼多零零散散的東西!這就像很多零碎地貨物,如果不打包,就需要在開發、測試、生產的每個環境上重新查看以保證環境的一致,有時甚至要將這些環境重新搭建一遍,就像每次將貨物卸載、重裝一樣麻煩。中間稍有差池,比如開發環境用了JDK 1.8,而線上是JDK 1.7;比如開發環境用了root用戶,線上需要使用hadoop用戶,都可能導致程式的運行失敗。

那麼容器如何對應用打包呢?還是要學習集裝箱,首先要有個封閉的環境,將貨物封裝起來,讓貨物之間互不干擾,互相隔離,這樣裝貨卸貨才方便。好在ubuntu中的lxc技術早就能做到這一點。

封閉的環境主要使用了兩種技術,一種是看起來是隔離的技術,稱為namespace,也即每個namespace中的應用看到的是不同的IP地址、用戶空間、程號等。另一種是用起來是隔離的技術,稱為cgroup,也即明明整台機器有很多的CPU、記憶體,而一個應用只能用其中的一部分。有了這兩項技術,集裝箱的鐵盒子我們是焊好了,接下來是決定往裡面放什麼。

最簡單粗暴的方法,就是將上面列表中所有的都放到集裝箱裡面。但是這樣太大了!因為即使你安裝一個乾乾靜靜的ubuntu作業系統,什麼都不裝,就很大了。把作業系統裝進容器相當於把船也放到了集裝箱裡面!傳統的虛擬機鏡像就是這樣的,動輒幾十G。答案當然是NO!所以第一項作業系統不能裝進容器。

撇下第一項作業系統,剩下的所有的加起來,也就幾百M,就輕便多了。因此一台伺服器上的容器是共享作業系統內核的,容器在不同機器之間的遷移不帶內核,這也是很多人聲稱容器是輕量級的虛擬機的原因。輕不白輕,自然隔離性就差了,一個容器讓作業系統崩潰了,其他容器也就跟著崩潰了,這相當於一個集裝箱把船壓漏水了,所有的集裝箱一起沉。

另一個需要撇下的就是隨著應用的運行而產生並保存在本地的數據。這些數據多以文件的形式存在,例如資料庫文件、文本文件。這些文件會隨著應用的運行,越來越大,如果這些數據也放在容器裡面,會讓容器變得很大,影響容器在不同環境的遷移。而且這些數據在開發、測試、線上環境之間的遷移是沒有意義的,生產環境不可能用測試環境的文件,所以往往這些數據也是保存在容器外面的存儲設備上。也是為什麼人們稱容器是無狀態的。

至此集裝箱焊好了,貨物也裝進去了,接下來就是如何將這個集裝箱標準化,從而在哪艘船上都能運輸。這裡的標準一個是鏡像,一個是容器的運行環境。

所謂的鏡像,就是將你焊好集裝箱的那個時刻,將集裝箱的狀態保存下來,就像孫悟空說定,集裝箱裡面就定在了那一刻,然後將這一刻的狀態保存成一系列文件。這些文件的格式是標準的,誰看到這些文件,都能還原當時定住的那個時刻。將鏡像還原成運行時的過程(就是讀取鏡像文件,還原那個時刻的過程)就是容器的運行的過程。除了大名鼎鼎的Docker,還有其他的容器,例如AppC、Mesos Container,都能運行容器鏡像。所以說容器不等於Docker。

總而言之,容器是輕量級的、隔離差的、適用於無狀態的,可以基於鏡像標準實現跨主機、跨環境的隨意遷移。

有了容器,使得PaaS層對於用戶自身應用的自動部署變得快速而優雅。容器快,快在了兩方面,第一是虛擬機啟動的時候要先啟動作業系統,容器不用啟動作業系統,因為是共享內核的。第二是虛擬機啟動後使用腳本安裝應用,容器不用安裝應用,因為已經打包在鏡像裡面了。所以最終虛擬機的啟動是分鐘級別,而容器的啟動是秒級。容器咋這麼神奇。其實一點都不神奇,第一是偷懶少幹活了,第二是提前把活干好了。

因為容器的啟動快,人們往往不會創建一個個小的虛擬機來部署應用,因為這樣太費時間了,而是創建一個大的虛擬機,然後在大的虛擬機裡面再劃分容器,而不同的用戶不共享大的虛擬機,可以實現作業系統內核的隔離。這又是一次合久必分的過程。由IaaS層的虛擬機池,劃分為更細粒度的容器池。

容器管理平台

有了容器的管理平台,又是一次分久必合的過程。

容器的粒度更加細,管理起來更難管,甚至是手動操作難以應對的。假設你有100台物理機,其實規模不是太大,用Excel人工管理是沒問題的,但是一台上面開10台虛擬機,虛擬機的個數就是1000台,人工管理已經很困難了,但是一台虛擬機裡面開10個容器,就是10000個容器,你是不是已經徹底放棄人工運維的想法了。

所以容器層面的管理平台是一個新的挑戰,關鍵字就是自動化:

自發現:容器與容器之間的相互配置還能像虛擬機一樣,記住IP地址,然後互相配置嗎?這麼多容器,你怎麼記得住一旦一台虛擬機掛了重啟,IP改變,應該改哪些配置,列表長度至少萬行級別的啊。所以容器之間的配置通過名稱來的,無論容器跑到哪台機器上,名稱不變,就能訪問到。

自修復:容器掛了,或是進程宕機了,能像虛擬機那樣,登陸上去查看一下進程狀態,如果不正常重啟一下么?你要登陸萬台docker了。所以容器的進程掛了,容器就自動掛掉了,然後自動重啟。

彈性自伸縮 Auto Scaling:當容器的性能不足的時候,需要手動伸縮,手動部署么?當然也要自動來。

當前火熱的容器管理平台有三大流派:

一個是Kubernetes,我們稱為段譽型。段譽(Kubernetes)的父親(Borg)武功高強,出身皇族(Google),管理過偌大的一個大理國(Borg是Google數據中心的容器管理平台)。作為大理段式後裔,段譽的武功基因良好(Kubernetes的理念設計比較完善),周圍的高手雲集,習武環境也好(Kubernetes生態活躍,熱度高),雖然剛剛出道的段譽武功不及其父親,但是只要跟著周圍的高手不斷切磋,武功既可以飛速提升。

一個是Mesos,我們稱為喬峰型。喬峰(Mesos)的主要功夫降龍十八掌(Mesos的調度功能)獨步武林,為其他幫派所無。而且喬峰也管理過人數眾多的丐幫(Mesos管理過Tweeter的容器集群)。後來喬峰從丐幫出來,在江湖中特例獨行(Mesos的創始人成立了公司Mesosphere)。喬峰的優勢在於,喬峰的降龍十八掌(Mesos)就是在丐幫中使用的降龍十八掌,相比與段譽初學其父的武功來說,要成熟很多。但是缺點是,降龍十八掌只掌握在少數的幾個丐幫幫主手中(Mesos社區還是以Mesosphere為主導),其他丐幫兄弟只能遠遠崇拜喬峰,而無法相互切磋(社區熱度不足)。

一個是Swarm,我們稱為慕容型。慕容家族(Swarm是Docker家族的集群管理軟體)的個人功夫是非常棒的(Docker可以說稱為容器的事實標準),但是看到段譽和喬峰能夠管理的組織規模越來越大,有一統江湖的趨勢,著實眼紅了,於是開始想創建自己的慕容鮮卑帝國(推出Swarm容器集群管理軟體)。但是個人功夫好,並不代表著組織能力強(Swarm的集群管理能力),好在慕容家族可以借鑒段譽和喬峰的組織管理經驗,學習各家公司,以彼之道,還施彼身,使得慕容公子的組織能力(Swarm借鑒了很多前面的集群管理思想)也在逐漸的成熟中。

三大容器門派,到底鹿死誰手,誰能一統江湖,尚未可知。

網易之所以選型Kubernetes作為自己的容器管理平台,是因為基於 Borg 成熟的經驗打造的 Kubernetes,為容器編排管理提供了完整的開源方案,並且社區活躍,生態完善,積累了大量分散式、服務化系統架構的最佳實踐。

容器初體驗

想不想嘗試一下最先進的容器管理平台呢?我們先了解一下Docker的生命周期。如圖所示。

圖中最中間就是最核心的兩個部分,一個是鏡像Images,一個是容器Containers。鏡像運行起來就是容器。容器運行的過程中,基於原始鏡像做了改變,比如安裝了程式,添加了文件,也可以提交回去(commit)成為鏡像。如果大家安裝過系統,鏡像有點像GHOST鏡像,從GHOST鏡像安裝一個系統,運行起來,就相當於容器;容器裡面自帶應用,就像GHOST鏡像安裝的系統裡面不是裸的作業系統,裡面可能安裝了微信,QQ,影片播放軟體等。安裝好的系統使用的過程中又安裝了其他的軟體,或者下載了文件,還可以將這個系統重新GHOST成一個鏡像,當其他人通過這個鏡像再安裝系統的時候,則其他的軟體也就自帶了。

普通的GHOST鏡像就是一個文件,但是管理不方便,比如如果有十個GHOST鏡像的話,你可能已經記不清楚哪個鏡像裡面安裝了哪個版本的軟體了。所以容器鏡像有tag的概念,就是一個標籤,比如dev-1.0,dev-1.1,production-1.1等,凡是能夠幫助你區分不同鏡像的,都可以。為了鏡像的統一管理,有一個鏡像庫的東西,可以通過push將本地的鏡像放到統一的鏡像庫中保存,可以通過pull將鏡像庫中的鏡像拉到本地來。

從鏡像運行一個容器可使用下面的命令,如果初步使用Docker,記下下面這一個命令就可以了。

這行命令會啟動一個裡面安裝了mysql的容器。其中docker run就是運行一個容器;–name就是給這個容器起個名字;-v 就是掛數據盤,將外面的一個目錄/my/own/datadir掛載到容器裡面的一個目錄/var/lib/mysql作為數據盤,外面的目錄是在容器所運行的主機上的,也可以是遠程的一個雲盤;-e 是設置容器運行環境的環境變數,環境變數是最常使用的設置參數的方式,例如這裡設置mysql的密碼。mysql:tag就是鏡像的名字和標籤。

docker stop可以停止這個容器,start可以再啟動這個容器,restart可以重啟這個容器。在容器內部做了改變,例如安裝了新的軟體,產生了新的文件,則調用docker commit變成新的鏡像。

鏡像生產過程,除了可以通過啟動一個docker,手動修改,然後調用docker commit形成新鏡像之外,還可以通過書寫Dockerfile,通過docker build來編譯這個Dockerfile來形成新鏡像。為什麼要這樣做呢?前面的方式太不自動化了,需要手工干預,而且還經常會忘了手工都做了什麼。用Dockerfile可以很好的解決這個問題。

Dockerfile的一個簡單的例子如下:

這其實是一個鏡像的生產說明書,Docker build的過程就是根據這個生產說明書來生產鏡像:

FROM基礎鏡像,先下載這個基礎鏡像,然後從這個鏡像啟動一個容器,並且登陸到容器裡面;

RUN運行一個命令,在容器裡面運行這個命令;

COPY/ADD將一些文件添加到容器裡面;

最終給容器設置啟動命令 ENTRYPOINT,這個命令不在鏡像生成過程中執行,而是在容器運行的時候作為主程式執行;

將所有的修改commit成鏡像。

這裡需要說明一下的就是主程式,是Docker裡面一個重要的概念,雖然鏡像裡面可以安裝很多的程式,但是必須有一個主程式,主程式和容器的生命周期完全一致,主程式在則容器在,主程式亡則容器亡。

就像圖中展示的一樣,容器是一個資源限制的框,但是這個框沒有底,全靠主進程撐著,主進程掛了,衣服架子倒了,衣服也就垮了。

了解了如何運行一個獨立的容器,接下來介紹如何使用容器管理平台。

容器管理平台初體驗

容器管理平台會對容器做更高的抽象,容器不再是單打獨鬥,而且組成集團軍共同戰鬥。多個容器組成一個Pod,這幾個容器親如兄弟,乾的也是相關性很強的活,能夠通過localhost訪問彼此,真是兄弟齊心,力可斷金。有的任務一幫兄弟還剛不住,就需要多個Pod合力完成,這個由ReplicationController進行控制,可以將一個Pod複製N個副本,同時承載任務,眾人拾柴火焰高。

N個Pod如果對外散兵作戰,一是無法合力,二是給人很亂的感覺,因而需要有一個老大,作為代言人,將大家團結起來,一致對外,這就是Service。老大對外提供統一的虛擬IP和埠,並將這個IP和服務名關聯起來,訪問服務名,則自動映射為虛擬IP。老大的意思就是,如果外面要訪問我這個團隊,喊一聲名字就可以,例如」雷鋒班,幫敬老院打掃衛生!」,你不用管雷鋒班的那個人去打掃衛生,每個人打掃哪一部分,班長會統一分配。

最上層通過namespace分隔完全隔離的環境,例如生產環境,測試環境,開發環境等。就像軍隊分華北野戰軍,東北野戰軍一樣。野戰軍立正,出發,部署一個Tomcat的Java應用。

作者:網易雲基礎服務 鏈接:https://www.jianshu.com/p/52312b1eb633

來源:簡書 簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。