Container:前端
Linux容器做爲一類操做系統層面的虛擬化技術成果,旨在立足於單一Linux主機交付多套隔離性Linux環境。與虛擬機不一樣,容器系統並不須要運行特定的訪客操做系統。相反,容器共享同一套主機操做系統內核,同時利用訪客操做系統的系統庫以交付必要的系統功能。因爲無需藉助於專門的操做系統,所以容器在啓動速度上要遠遠優於虛擬機。java
容器可以利用Namespaces、Apparmor、SELinux配置、chroot以及CGroups等Linux內核功能,從而交付一套相似於虛擬機的隔離性環境。Linux安全模塊可以確保來自容器的主機設備與內核訪問行爲受到妥善管理,從而避免入侵活動的發生。除此以外,容器還可以經過其主機操做系統運行多種不一樣Linux發行版——只要各種操做系統擁有一樣的底層CPU架構要求。整體而言,容器技術提供了一種立足於各種Linux發行版的容器鏡像建立方式,同時利用API進行容器生命週期管理,經過客戶端工具實現與該API的交互,進而提供快照以及不一樣容器主機之間容器實例遷移等能力。程序員
容器技術發展歷程:
數據庫
1979年 — chrootcanvas
容器技術的概念能夠追溯到1979年的UNIX chroot。這是一套「UNIX操做系統」系統,旨在將其root目錄及其它子目錄變動至文件系統內的新位置,且只接受特定進程的訪問。這項功能的設計目的在於爲每一個進程提供一套隔離化磁盤空間。1982年其被添加至BSD當中。安全
2000年 — FreeBSD Jails服務器
FreeBSD Jails是由Derrick T. Woolworth於2000年在FreeBSD研發協會中構建而成的早期容器技術之一。這是一套「操做系統」系統,與chroot的定位相似,不過其中包含有其它進程沙箱機制以對文件系統、用戶及網絡等資源進行隔離。經過這種方式,它可以爲每一個Jail、定製化軟件安裝包乃至配置方案等提供一個對應的IP地址。網絡
2001年 — Linux VServer架構
Linux VServer屬於另外一種jail機制,其可以被用於保護計算機系統之上各分區資源的安全(包括文件系統、CPU時間、網絡地址以及內存等)。每一個分區被稱爲一套安全背景(security context),而其中的虛擬化系統則被稱爲一套虛擬私有服務器。java-ee
2004年 — Solaris容器
Solaris容器誕生之時面向x86與SPARC系統架構,其最初亮相於2004年2月的Solaris 10 Build 51 beta當中,隨後於2005年正式登錄Solaris 10的完整版本。Solaris容器至關於將系統資源控制與由分區提供的邊界加以結合。各分區立足於單一操做系統實例以內以徹底隔離的虛擬服務器形式運行。
2005年 — OpenVZ
OpenVZ與Solaris容器很是類似,且使用安裝有補丁的Linux內核以實現虛擬化、隔離能力、資源管理以及檢查點交付。每套OpenVZ容器擁有一套隔離化文件系統、用戶與用戶羣組、一套進程樹、網絡、設備以及IPC對象。
2006年 — Process容器
Process容器於2006年由谷歌公司推出,旨在對一整套進程集合中的資源使用量(包括CPU、內存、磁盤I/O以及網絡等等)加以限制、分配與隔離。此後其被改名爲Control Groups(即控制組),從而避免其中的「容器」字眼與Linux內核2.6.24中的另外一術語出現衝突。這代表了谷歌公司率先重視容器技術的敏銳眼光以及爲其作出的突出貢獻。
2007年 — Control Groups
正如上文所說起,Control Groups也就是谷歌實現的cgroups,其於2007年被添加至Linux內核當中。
2008年 — LXC
LXC指代的是Linux Containers,其也是第一套完整的Linux容器管理實現方案。其功能經過cgroups以及Linux namespaces實現。LXC經過liblxc庫進行交付,並提供可與Python三、Python二、Lua、Go、Ruby以及Haskell等語言相對接的API。相較於其它容器技術,LXC可以在無需任何額外補丁的前提下運行在原版Linux內核之上。目前LXC項目由Canonical有限公司負責贊助及託管。
2011年 — Warden
Warden由CloudFoundry公司於2011年所創建,其利用LXC做爲初始階段,隨後又將其替換爲自家實現方案。與LXC不一樣,Warden並不會與Linux緊密耦合。相反,其可以運行在任意可以提供多種隔離環境方式的操做系統之上。Warden之後臺進程方式運行並提供API以實現容器管理。感興趣的朋友能夠點擊此處與此處瞭解更多與Warden相關的細節信息(英文原文)。
2013年 — LMCTFY
Lmctfy表明的是「Let Me Contain That For You(幫你實現容器化)」。它其實屬於谷歌容器技術堆棧的開源版本,負責提供Linux應用程序容器。谷歌公司在該項目的起步階段宣稱其可以提供值得信賴的性能表現、高資源利用率、共享資源機制、充裕的發展空間以及趨近於零的額外資源消耗。Kubernetes目前所使用的cAdvisor工具最初就來源於lmctfy項目。2013年10月lmctfy的首個版本正式推出,谷歌公司在2015年決定將lmctfy的核心概念與抽象機制轉化爲libcontainer。在失去了主幹以後,現在lmctfy已經失去一切積極的發展勢頭。
Libcontainer項目最初由Docker公司創建,現在已經被納入開放容器基金會的管轄範疇。
2013年 — Docker
截至2016年1月,Docker是目前最具人氣且應用最爲普遍的容器管理系統。Docker項目最初是由一家名爲dotCloud的平臺即服務廠商所打造,其後該公司改名爲Docker。與Warden相似,Docker一樣在起步階段使用LXC,然後利用本身的libcontainer庫將其替換下來。與其它容器平臺不一樣,Docker引入了一整套與容器管理相關的生態系統。其中包括一套高效的分層式容器鏡像模型、一套全局及本地容器註冊表、一個精簡化REST API以及一套命令行界面等等。在後期發展階段,Docker公司還構建起一套名爲Docker Swarm的容器集羣管理解決方案。
2014年 — Rocket
Rocket最初由CoreOS開發而成,專門用於解決部分Docker當中存在的缺陷。CoreOS方面也提到,他們當初的開發目標是在安全性與生產要求知足能力上超越Docker。更重要的是,其基於App Container規範並使其成爲一項更爲開放的標準。除了Rocket以外,CoreOS還開發出了多種其它與容器相關的產品,且已經被Docker與Kubernetes所使用:CoreOS操做系統、etcd以及flannel。
2016年 — Windows容器
微軟公司也已經於2015年採起初步舉措,但願將容器支持能力添加到微軟Windows Server操做系統當中,而這項旨在幫助Windows應用實現容器化的項目被稱爲Windows容器(Windows Containers)。其即將隨微軟的Windows Server 2016一同推出。在這碩方案當中,Docker可以以原生方式在Windows平臺上運行容器,而無需運行虛擬機或者多層Docker(早期Docker須要利用Linux虛擬機才能與Windows系統相對接)。
截至目前(2016年1月),整個技術行業已經愈來愈多地將軟件應用程序部署基礎由虛擬機轉移向容器。之因此出現這種趨勢,一大重要緣由在於容器可以提供遠優於虛擬機的靈活性與使用成本。谷歌公司多年來一直在利用Borg and Omega容器集羣管理平臺等容器技術以實現各種谷歌應用的規模化運行。更重要的是,谷歌公司還經過實現cgroups以及參與libcontainer項目等方式爲容器技術的發展作出了突出貢獻。谷歌方面在過去幾年當中已經利用容器技術實現了可觀的性能提高、資源利用率改善以及總體執行效率優化。就在最近,微軟公司這位從未將任何操做系統層級虛擬化機制引入Windows平臺的軟件巨頭亦快速在Windows Server上實現了原生容器支持能力。
------------------------------
轉自http://cloud.51cto.com/art/201602/505113.htm
什麼是容器?爲何須要它們:
容器是針對如下問題的解決方案:在切換運行環境後,如何保證軟件可以可靠地運行?這種切換多是從程序員的筆記本電腦到測試環境、從某個測試階段部署到線上,也多是從數據中心的某臺物理機到私有云或者公有云上的某臺虛擬機。
使用虛擬化技術時,能夠被分發的文件包是一臺虛擬機,它包含了整個操做系統和應用。一臺運行着三個虛擬機的物理服務器,須要有一個管理虛擬機軟件的中間層,以及運行在這個中間層之上的三個獨立操做系統。相較之下,一臺運行着三個容器應用的服務器,只須要一個操做系統,而每一個容器均可以和別的容器共享同一個操做系統內核。操做系統中被容器共享的部分是隻讀的,若是須要寫入,每一個容器均可以掛載獨立的服務。這也就是說,容器比虛擬機要輕量級不少,它消耗的資源相較於虛擬機也少得多。
一個容器的文件大小可能只有幾十M,可是一個擁有完整操做系統的虛擬機卻多是幾個G。正由於這一點,對於一個獨立服務器來講,它能承載的容器的數量比虛擬機的數量多得多。另外一個主要的優勢是,虛擬機可能要耗費好幾分鐘的時間,才能啓動操做系統、開始運行應用;然而容器中應用的啓動幾乎能夠瞬間完成。這意味着,若是須要部署更多的容器,它們的實例化能夠很快完成;若是不須要這些容器了,也能夠很快將它們從宿主服務器上釋放掉。第三個優勢是,容器化更好地顧及到了模塊化。一個複雜的應用能夠被細分紅小的模塊(好比數據庫、應用前端等等),而不是將它運行在某一個容器中。這種方式一般被稱爲「微服務」。使用這種方法構建的應用更容易被管理,由於每一個模塊都相對簡單,並且須要更新某些模塊時,不須要從新構建整個應用。由於容器很是輕量級,單獨模塊(或微服務)只有在它們被須要時纔會被實例化,而後幾乎瞬間就變得可用了。
--------------------------------
轉自https://baijiahao.baidu.com/s?id=1609932946964681808&wfr=spider&for=pc
Injection:
public class SomeBean { private final Service service; @Inject public SomeBean(Service service){ this.service = service; } }
當CDI容器在初始化一個SomeBean類型的bean實例時,它將會查找該類的默認構造器(無參構造器)並用它來建立bean實例。可是有一個例外狀況,就是當咱們還有一個使用
@Inject 進行了註解的構造器時,這種狀況下,容器會改用有註解的構造器而不是無參構造器,而且把經過構造器參數傳入的依賴資源注入到bean實例中來。
public class SomeBean { @Inject private Service service; }
這種狀況下,當容器初始化一個 SomeBean類型的bean時,它會把一個正確的Service實例注入給該字段,即便該字段是一個私有字段,而且不須要有任何setter方法。
public class SomeBean { private Service service; @Inject public void setService(Service service) { this.service = service; } }
這種狀況下,當容器初始化一個 SomeBean類型的bean時,它會調用全部由@Inject註解了的方法,而且經過方法參數的方式把依賴注入進來。
爲了提供徹底鬆耦合的應用,咱們一般把接口注入到受管理的資源中。當咱們有多個實現了給定接口的bean時該怎麼辦呢?咱們能夠同時使用@Any修飾符和CDI的
Instance接口,來把全部該接口的實現bean都注入進一個受管理的bean中:
public class SomeBean { @Inject public void listServiceImplementations( @Any Instance<Service> serviceList) { for(Service service : serviceList){ System.out.println(service.getClass().getCanonicalName()); } }
@Any 修飾符告訴容器,任何可供使用的依賴都適用於該注入點,因此容器會把他們都注入進來。 若是咱們有接口的多個實現而咱們只注入其中的一個 - 而且沒有作
任何排除工做 - 那麼容器將會抱怨而且沒法成功的初始化組件。咱們將會在其餘教程中介紹依賴排除問題。
生產者方法的參數也能夠經由CDI容器進行注入。請查看Java EE CDI Producer methods tutorial.
若是咱們不涉及CDI代理機制,那麼本教程將是不完整的。當咱們把一個在不一樣於@Dependent範圍下建立出來的bean注入到另一個託管資源時,CDI容器不會注入一個被注入bean的直接引用。
CDI 代理 示例
public class Service$Proxy$_$$_WeldClientProxy extends Service { @Override public void doWork() { Service instance = // ... resolve bean instance instance.doWork(); } }
-------------------------
轉自https://www.oschina.net/translate/java-ee-cdi-dependency-injection-inject-tutorial