1. 程式人生 > >docker容器技術基礎入門(一)

docker容器技術基礎入門(一)


目錄

 

一、什麼是容器

二、虛擬化的實現

1、主機級虛擬化

2、容器級別虛擬化

2.1、Linux Namespaces

2.2、Control Groups(CGroups)的作用

2.2.1、CGroups的功能

2.3、LXC(Linux Container)

三、Docker的誕生

3.1、Docker是LXC的增強版,它本身不是容器,而是容器的易用工具。

3.2、Docker容器引擎的更迭

四、什麼是容器編排?

方案一:machine+swarm+compose:

方案二:mesos+marathon:

方案三:kubernetes(簡稱為k8s,因為這個單詞有8個字母):

五、容器歷史上的爾虞我詐,親親合合的故事:



一、什麼是容器

容器是一種基礎工具,泛指任何可以用於容納其他物品的工具,可以部分或完全封閉,被用於容納、儲存、運輸物品;物體可以被放置在容器中,而容器可以保護內容物;

人類使用容器的歷史至少有十萬年。

 

二、虛擬化的實現

1、主機級虛擬化

     此實現是在宿主機上安裝虛擬機器管理軟體,而後虛擬出N個完整的系統,每一個系統都有自己的核心。有兩種型別的實現

     1.1、Type-I型別

(在宿主機上直接安裝Virtual machine Manager,不需要在宿主機上安裝作業系統)

             xen、ESX/ESXI

     1.2、Type-II型別(需要基於宿主機的作業系統之上安裝Virtual Machine Manager)

             VMware Workstation、kvm、VirtualBox

 

2、容器級別虛擬化

      此實現不在為每一個虛擬機器建立單獨的核心,而是通過在宿主機的核心上將6種資源通過核心機制(namespaces)隔離出來,每一個namespace是一個單獨的容器(虛擬機器)

      至今位置,整個linux領域的容器技術,就是靠核心級的6個namespaces、chroot和Cgroups共同實現

2.1、Linux Namespaces

namespace 系統呼叫引數 隔離內容 核心版本
UTS CLONE_NEWUTS 主機名和域名 2.6.19

IPC

CLONE_NEWIPC 訊號量、訊息佇列和共享記憶體 2.6.19
PID CLONE_NEWPID 程序編號 2.6.24
Network CLONE_NEWNET 網路裝置、網路棧、埠等 2.6.29
Mount CLONE_NEWNS 掛載點,檔案系統 2.4.19
User CLONE_NEWUSER 使用者和使用者組 3.8

2.2、Control Groups(CGroups)的作用

容器化技術的隔離機制是靠namespaces實現,而容器化的資源分配靠的是在核心級通過CGroups機制實現,它會把系統級的資源分成多個組,然後把每一個組內的資源量指派分配到特定的namespace的程序上去來實現

2.2.1、CGroups的功能

blkio 塊裝置IO
cpu CPU
cpuacct CPU資源使用報告
cpuset 多處理器平臺上的CPU集合,有兩種分派方式,一種是比例,一種是分核數
devices 裝置訪問
freezer

掛起或恢復任務

memory 記憶體用量及報告
perf_event 對cgroup中的任務進行統一效能測試
net_cls cgroup中的任務建立的資料報文的類別識別符號

2.3、LXC(Linux Container)

雖然在核心的層面上解決了隔離,實現了容器技術,但是我們需要寫程式碼來呼叫這些實現的方法,所以要變成大多數使用者都能使用的應用,所以我們要把它做成工具,也就有了這樣的解決方案。

LXC是最早除了Vserver之外,真正把完整的容器技術用一組簡易使用的工具和模板來極大的簡化了容器技術使用的一個方案。LXC靠一組工具包幫我們快速的實現了建立名稱空間,利用模板完成內部所需要的各種檔案的安裝。同時,還有些工具能夠自動完成chroot切換,於是,就可以使用多個並行的使用者空間,而每一個使用者空間,就像我們之前使用的虛擬機器,是一個獨立的系統。

 

三、Docker的誕生

LXC雖然極大的簡化了容器技術的使用,但比起過去使用虛擬機器來講,它的複雜程度是沒有多大降低的,隔離性也沒有虛擬機器好、在大規模使用上和分發上都不方便。但好處是它能夠讓每一個使用者空間的程序直接使用宿主機的效能,中間沒有額外開銷。於是就出現了Docker

 

3.1、Docker是LXC的增強版,它本身不是容器,而是容器的易用工具。

容器是linux核心中的技術,Docker只是把這種技術在使用上簡易普及了。Docker在早期的版本其核心就是LXC的二次封裝發行版。Docker利用LXC做容器管理引擎,但是在建立容器時,不在使用模板去安裝生成。而是通過映象技術(把一個作業系統使用者空間所需要使用到的元件事先編排好,並整體打包成一個檔案,image檔案),映象檔案集中放在一個倉庫中。當需要建立容器時,Docker呼叫LXC的工具lxc-create。但是不在通過lxc的模板去安裝,而是連線到映象伺服器上下載匹配的映象檔案,而後基於映象啟動容器。所以,Docker極大的簡化了容器的使用難度。以後我們建立啟動容器,只需要一個命令,docker-run,docker-stop就可以啟動停止一個容器了。為了使整個容器使用更加易於管理,Docker採用了一種更精巧的限制機制,在一個容器內,只執行一個程序。而LXC是把一個容器當一個使用者空間使用,可以執行N個程序,所以使得我們管理容器程序極為不便。Docker在映象構建底層使用了分層構建,聯合掛載。這種好處就是在以後的映象分發上就沒有那麼龐大。可以自由組合映象實現不同環境的掛載

 

3.2、Docker容器引擎的更迭

Docker早起是基於LXC容器管理引擎實現,當後來成熟之後,Docker自建了一個容器引擎叫libcontainer,後來CNCF的介入,Docker又研發了一個工業化標準的容器引擎,叫runC,目前所使用的新版Docker,所使用的容器引擎就是RunC。

 

四、什麼是容器編排?

在docker基礎之上,能夠把應用程式之間的依賴關係,從屬關係,隸屬關係等等,反應在啟動,關閉時的次序和管理邏輯中,這種功能叫做容器編排

所以我們需要容器編排工具:

方案一:machine+swarm+compose:

比如docker自己的swarm(Swarm 是docker公司所擁有的唯一容器編排工具。Swarm是Docker官方提供的一款叢集管理工具,其主要作用是把若干臺Docker主機抽象為一個整體,並且通過一個入口統一管理這些Docker主機上的各種Docker資源。Swarm和Kubernetes比較類似,但是更加輕,具有的功能也較kubernetes更少一些。)+compose(單機編排工具,只能編排一個docker伺服器之上的),其實還有machine(Docker machine 是 Docker 官方提供的一個工具,它可以幫助我們在遠端的機器上安裝 Docker,或者在虛擬機器 host 上直接安裝虛擬機器並在虛擬機器中安裝 Docker。我們還可以通過 docker-machine 命令來管理這些虛擬機器和 Docker。)把這三個工具組合起來,當一個編排工具使用。

方案二:mesos+marathon:

ASF的著名的資料中心作業系統,統一資源編排工具,叫mesos,但是mesos不是專門用來編排容器的,他是實現統一資源排程和分配的,如果我們要實現編排工具,還需要加一箇中間層叫marathon。

方案三:kubernetes(簡稱為k8s,因為這個單詞有8個字母):

有意思的是google這家公司祕而不宣的悄悄的使用容器已經有十幾年的歷史了。據說每一週新建和銷燬的容器就多達幾十億個。docker竟然姻緣巧合之間摸到了這個門道,並且把它做成了開源軟體,google就坐不住了。因為google把容器當做獨門武器使用,docker竟然找到了容器的方法給所有人使用。後來google發現藏不住了。但是此時docker已經獨霸了話語權了。好在docker也不是鐵板一塊, 這時候google扶持了另一家做容器的公司,但是發現實在是難以跟docker抗衡。這個時候就換了個方法,雖然docker在容器領域成為了標準,但是容器一般不會單獨使用,這個時候google就想做容器編排工具,而容器編排工具在google內部有一個重要的系統叫伯格(Borg),也已經跑了十幾年了。但是docker在這方面沒有經驗,這時候google就看到了這個機會,所以k8s橫空出世,一出世就橫掃一切。但是在去年2017年12月就塵埃落定了。k8s佔據了80%的市場份額。再次基礎之上,google還主導成立了CNCFCloud Native Computing Foundation),即所謂的容器標準組織,於 2015 年 7 月成立,隸屬於 Linux 基金會,初衷圍繞“雲原生”服務雲端計算,致力於維護和整合開源技術,支援編排容器化微服務架構應用。首先它是一個非營利組織,致力於通過技術優勢和使用者價值創造一套新的通用容器技術,推動本土雲端計算和服務的發展。CNCF 關注於容器如何管理而不是如何建立,因為如果沒有一個成熟的平臺去管理容器,那麼大型企業無法真正放心接受並使用容器。 

五、容器歷史上的爾虞我詐,親親合合的故事:

docker技術永生,docker公司已死,就說docker有一手好牌,但是打的稀巴爛,因為docker對容器編排毫無建樹。後來docker為了活著吸引更多的人來投資,要擴大領域和份額及收益,為了變性,就推出了docker社群版CE和企業版EE,後來docker把社群版改名了不再叫docker了,而把原來docker的所有的流量引入到了docker企業版的概念中去了。以至於後來有一段時間社群為此鬧得沸沸揚揚的,就說docker過河拆橋啊這這那那的。後來這個docker社群版叫做Moby,dockerr社群版的識別符號遷移到github上並重新命名為叫Moby。而後把docker所有的關鍵詞全部引向了docker的企業版,所以大家覺得docker使用了一個混招。而之所以能做成這樣的原因是:docker是一家商業公司叫做dockerclub,這個商業公司擁有了docker技術,擁有了docker這個程式碼往何處走的主導權。因為就是docker這樣的做法,大家對他產生了疑慮。google為了避免大家這樣的顧慮,google作為一家公司不會控制k8s走勢的意圖,所以成立了CNCF,然後把k8s的程式碼捐給了CNCF。而CNCF是由很多組織和公司成立的一個公共組織。類似於開源委員會之類的。當然他是容器類的。所以k8s不在屬於google一家公司,而是由想微軟啊,google,ibm這樣的公司聯合成立起來的組織叫CNCF。所以就不用擔心google哪天會把k8s私有化。google這招做的,讓大家對k8s簡直可以算得上是趨之若鶩。所以這也是k8s這個社群茁壯成長的原因。到現在為止k8s還沒有到穩定的階段,一年四個版本的釋出。原因就是k8s還沒有到成熟的階段(指的是很多的功能還在不斷地加進來)。docker是go語言研發的。k8s也是go研發的。所以執行docker要有go環境。

docker在過河拆橋的道路上一路狂奔,因為docker早起是基於LXC構建的。後來略具實力以後,docker就拋棄了LXC,自建了一個容器引擎叫:libcontainer,細化了LXC,所以現在的版本docker已經沒有了LXC。但後來docker被CNCF挾持了,為了docker能佔據點話語權,因為為了容器的發展,要走向標準化,要開源,不能受控一家公司,要指定一個標準,那麼誰來指定這個標準化呢?因為容器要執行起來,容器底層的引擎要標準化,容器的格式要標準化。CNCF自己做完全有實力,因為google在裡面呢。但是這樣做明擺著欺負docker呢。所以給docker了一個機會。你來定義標準化,同時做一款軟體開源出來,所以後來libcontainer轉換成下一步叫runC(runContainer),所以我們現在用的新版的docker的容器引擎就是runC。runC就是容器執行時的環境標準。當然映象檔案也有標準叫OCF(Open Container Format,叫開放容器格式標準),這個標準成為了事實上的工業標準。我們做容器都應該遵循這個標準。

不管我們怎麼樣認為docker被人欺負,但是直到今天docker確實是大家心中的容器技術。談到容器你可以不知道LXC是什麼也不知道linux核心名稱構建是什麼。但是大家都知道docker。所以不管今天k8s在編排上多麼的一家獨大,但是扔無法擺脫docker。我們用的k8s底層容器都是docker,雖然k8s支援很多種容器。docker只是其中一種。但是現在我們去用基本上都是k8s+docker。

插曲:

從2000年以來,谷歌基於容器研發三個容器管理系統,分別是Borg、Omega和Kubernetes。這篇論文由這三個容器叢集管理系統長年開發維護的谷歌工程師Brendan Burns, Brian Grant, David Oppenheimer, Eric Brewer, 和John Wilkes於近日發表,闡述了谷歌從Borg到Kubernetes這個旅程中所獲得知識和經驗教訓。
儘管對軟體容器廣泛傳播的興趣是最近的現象,但在谷歌我們大規模使用Linux容器已經有10多年了,而且期間我們建了三種不同的容器管理系統。每一個系統都受之前的系統影響頗深,儘管它們的誕生是出於不同原因。這篇文章描述了我們在研發和使用它們的過程中得到的經驗教訓。
       第一個在谷歌被開發出來的統一的容器管理系統,在我們內部稱之為“Borg”,它管理著長時間執行的生產服務和批處理服務。這兩類任務之前是由兩個分離開的系統來管理的:Babysitter和Global Work Queue。Global Work Queue的構架極大地影響了Borg,但卻只是針對批量服務的,且兩者都在Linux control groups誕生之前。Borg將這兩種應用所用的機器統一成一個池子,這樣得以提高資源利用率,進而降低成本。之所以可以實現這樣的機器資源共享,是因為可以拿到linux核心的容器支援(確實,Google對Linux核心的容器程式碼貢獻了很多),這使得在對時限敏感的、且面對使用者的服務和佔用很多CPU資源的批處理程序提供了更好的隔離。

        由於越來越多的應用被開發並執行在Borg上,我們的應用和底層團隊開發了一個廣泛的工具和服務的生態系統。這些系統提供了配置和更新job的機制,能夠預測資源需求,動態地對在執行中的程式推送配置檔案、服務發現、負載均衡、自動擴容、機器生命週期的管理、額度管理以及更多。這個生態系統的發展源自谷歌內部不同團隊的需求,發展的結果成為了異構的、ad-hoc系統的集合,Borg的使用者能夠用幾種不同的配置語言和程序來配置和溝通。由於Borg的規模、功能的廣泛性和超高的穩定性,Borg在谷歌內部依然是主要的容器管理系統。

       Omega,作為Borg的延伸,它的出現是出於提升Borg生態系統軟體工程的願望。Omega應用到了很多在Borg內已經被認證的成功的模式,但是是從頭開始來搭建以期更為一致的構架。Omega儲存了基於Paxos、圍繞transaction的叢集的狀態,能夠被叢集的控制面板(比如排程器)接觸到,使用了優化的程序控制來解決偶爾發生的衝突。這種分離允許Borgmaster的功能被區分成幾個並列的組建,而不是把所有變化都放到一個單獨的、巨石型的master裡。許多Omega的創新(包括多個排程器)都被收錄進了Borg.

       谷歌研發的第三個容器管理系統是Kubernetes。Kubernetes的研發和認知背景,是針對在谷歌外部的對Linux容器感興趣的開發者以及谷歌在公有云底層商業增長的考慮。和Borg、Omega完全是谷歌內部系統相比,Kubernetes是開源的。像Omega一樣,Kubernetes在其核心有一個被分享的持久儲存,有元件來檢測相關ojbect的變化。跟Omega不同的是,Omega把儲存直接暴露給信任的控制面板的元件,而在Kubernete中,是要完全由domain-specific的提供更高一層的版本控制認證、語義、政策的REST API來接觸,以服務更多的使用者。更重要的是,Kubernetes是由一支在叢集層面應用開發能力更強的開發者開發的,他們主要的設計目標是用更容易的方法去部署和管理複雜的分散式系統,同時仍然能通過容器所提升的使用效率來受益。

Docker容器技術基礎用法(二)