## 前言
本文的理論,僅僅是作者在實驗之后的一家之言,也許只是管中窺豹。希望大家抱著保留的態度,來看這篇文章!
此文寫于2016年6月12日,一切都在快速變化,歡迎指正!
## Docker生態系統

## Docker簡介
### Docker是什么?
Docker是以docker容器為資源分割和調度的基本單位,封裝軟件的運行時環境.用于快速構建,發布,運行分布式應用的平臺。**Docker的運行時容器的本質是進程**.在linux中,通過namespace進行資源隔離,cgroups進行資源限制,使用docker容器看上去像是一個運行在宿主機中的虛擬機.
### docker引擎的簡介
* 我們通常說的Docker是指Docker Engine

* Docker容器與虛擬機的根本區別在于,docker容器和宿主機共用linux操作系統內核,不會在宿主機上再次建立OS,輕量級.
* 容器采用分層的機制。如:最底層可能是一個linux發行版,如ubuntu.上面加上JDK層.JDK層之上可以安裝tomcat等各種java應用層
* 我們通常所說的docker是指docker引擎.本文主要介紹docker引擎周邊的生態系統,關于docker引擎的詳細介紹可以參考[《docker-軟件工程中的集裝箱技術》]().
### 筆者認為Docker四大特性
* Docker容器的秒級啟動
* Docker容器實現了應用環境的標準化
* Docker與mesos.k8s的結合,提供了云服務能力.
* Docker的高資源利用率(與虛擬機相比)
以上的這些特性,使企業級的微服務架構的實現,提供了真實的具有實踐性的可能.
### Docker及其生態系統為軟件行業帶來了什么變化?
* **持續部署與集成**.Docker封裝了軟件的運行時環境,消除了線上與線下的差異,保障了應用在開發,測試,生產運行整個生命周期的一致性.結合jenkins等持續集成軟件使用,實現了code(代碼)到image(鏡像)的快速集成,大大的簡化了持續集成,測試,軟件發布的過程.
* **環境標準化與版本控制**.我們經常使用git,svn,cvs等版本控制工具實現代碼級別的版本控制.那有沒有想過有一天,可以實現對應用運行時環境進行版本控制呢?docker幫我們實現了,應用myapp的1.0版本使用JDK6(myapp-docker-1.0),應用的2.0版本使用JDK8(myapp-docker-2.0).全部封裝到docker鏡像里面.上線過程中,2.0版本出現問題怎么辦,快速回退1.0版本.因為回退過程,不需要1.0應用環境的重新配置,只是1.0應用版本的容器啟動,秒級實現.筆者做個展望:docker鏡像將成為未來軟件交付的唯一標準!
* **應用服務能力的伸縮性**.舉個假設的例子,淘寶對于應用服務的能力要求,"雙11"期間肯定遠遠高于日常.docker結合k8s,mesos之類的資源管理及服務編排系統,結合負載均衡服務,可以實現應用規模的快速擴縮."雙11"啟動5000個容器,日常啟動2000個容器來滿足業務的需求.
* **資源的利用率提高**上面的淘寶的例子,就避免了服務器資源的浪費,在閑時將服務器資源釋放出來.筆者在一臺8G,8核心的PC機上,啟動了20個ubuntu容器(還可以更多),你可以在這樣的一臺PC上啟動20個虛擬機么?答案顯然是否定的.
## Docker鏡像庫
### DockerHub
Docker 官方維護了一個公共倉庫 Docker Hub,其中已經包括了超過 15,000 的鏡像。大部分需求,都可以通過在 Docker Hub 中直接下載鏡像來實現。
### Docker registry 私有倉庫
Registry 作為 Docker 的核心組件之一負責鏡像內容的存儲與分發,是企業搭建私有docker鏡像倉庫的解決方案.
Docker Registry目前分為V1和V2兩個版本.V2版本相比V1版本有如下幾方面的改進:
1. V1版本push layer操作只判斷id,不判斷layer的內容.由于鏡像內容與id無關,所以重新build之后id變化,內容沒變的layer將會重復提交.造成存儲資源的浪費.V2采用哈希值方式,被稱為 digest 是一個和鏡像內容相關的字符串,相同的內容會生成相同的 digest。所以是鏡像layer判斷是內容相關的.
2. 提供了鑒權管理和權限控制
3. V1 registry 中鏡像的每個layer 都包含一個json文件包含了父親 layer 的信息.因此當我們 pull 鏡像時需要串行下載,下載完一個 layer 后才知道下一個 layer 的 id 是多少再去下載.
新版 registry 在 image 的 manifest 中包含了所有 layer 的信息,客戶端可以并行下載所有的 layer
推薦您看:[《Docker registry V2私有倉庫搭建》](http://www.zimug.com/317.html)
## 服務發現機制和全局配置存儲
**為什么需要服務發現?**
當我們部署少量docker容器的時候,我們可以去指定容器的映射端口.但是我們啟動大規模的容器集群的時候,我們希望容器的對外服務端口是隨機分配的,并且同一臺主機內不能發生端口沖突(服務編排及資源管理的系統可以幫我們完成端口的隨機分配,這個不是這里要說的事情).
端口隨機的分配實現了,那么用戶該如何才能知道,這個隨機的端口是什么?哪個ip,哪個端口對應哪個服務?這就需要服務發現組件來實現!
**基于上述的需求,服務發現的組件應該具備如下基本功能**
* 提供全局的分布式容器信息存儲,即鍵值對的存儲工作。
* 提供http的API來get or set值.即:提供注冊和查詢

### 常用的服務發現工具
* consul: 服務發現/全局的分布式key-value存儲。自帶DNS查詢服務,可以跨數據中心。提供節點的健康檢查,可以實現動態的consul節點增減.docker官方的用例推薦!
* etcd: 服務發現/全局的分布式key-value存儲.靜態的服務發現,如果實現動態的新增etcd節點,需要依賴第三方組件。
* zookeeper: 服務發現/全局的分布式key-value存儲.使用場景廣泛,java編寫,資源需求大,比起前兩者更加臃腫!
## Docker 網絡
Docker 1.9發布之前,網絡的問題一直是困擾docker愛好者的主要問題.實現的復雜度較高,這一切都在發布docker1.9的overlay網絡之后得到改善.
docker 1.9之前提供了兩種容器之間的網絡連接方式
1.通過docker容器映射端口到宿主機,即暴露端口到宿主機.舉例:容器A映射8080到宿主機xx.xx.xx.xx的80端口,其他的容器想訪問容器A的端口,就訪問xx.xx.xx.xx:80。
2.通過link的方式,連接容器網絡.這種方式只適合,單個宿主機之內,無法跨宿主機實現容器之間的互訪!
砸一看,似乎有這兩種方式就夠了.雖然采用第二種無法跨主機,但是第一種還算ok吧?如果一個服務暴露出來很多的端口怎么辦?都對外映射么?那樣就會造成端口管理上的災難!
這顯然是不行的,這時很多的工具出現了,來做SDN(軟件定義網絡)網絡.容器之間的互訪網絡.比較有名氣的有:
* fannel–overlay
* weave–overlay
* pipework
但是,docker1.9發布之后,這些Docker網絡工具的存在意義逐漸弱化(雖然這些軟件還是有一些自己的特點)。docker官方實現了自己的跨主機容器網絡方案。
實現方式,請看我的另外兩篇
[《基于consul的Docker-overlay跨多宿主機容器網絡》](http://www.zimug.com/364.html)
[《基于etcd的Docker-overlay跨多宿主機容器網絡》](http://www.zimug.com/411.html)
## 容器管理與編排

容器編排和管理系統主要解決以下幾個問題:
* 我們需要工具來實現大規模容器分業務分組分服務管理.
* 我們需要指定容器去哪些主機上啟動部署
* 容器依賴按照什么順序啟動?做成自動化的
* 自動化的實時擴展或減少分組容器的數量
* 根據集群和節點的資源使用率調度容器的啟動位置
* 分組容器對外服務的負載均衡
* 容器及集群的監控告警
* 產品應用支持,如大數據的docker化
* ……
目前容器編排與管理的系統主要是三個:
1. mesos + marathon,mesos的本質是一個基于資源的調度管理系統,可以實現docker容器的基于資源的細粒度的容器調度.marathon用來運行長服務,實現健康檢查與容器依賴啟動,擴展與縮放.在大型的容器集群管理上,有更穩定的表現.
推薦一篇介紹mesos的文章:[《煮餃子與mesos之間妙不可言的關系》](http://www.zimug.com/377.html)
2. kubernets是谷歌開發的容器編排管理系統.使用Golang開發,具有輕量化、模塊化、便攜以及可擴展的特點。它提出了一系列諸如:Pods,Replication Controllers,Labels,Services之類的概念,所以學習的曲線也相對陡峭.Kubernetes的性能要比Swarm差,是因為它擁有更加復雜的架構;性能比Mesos差,是因為它結構層次更深;
3. docker + swarm + compose,docker原生的容器管理系統,簡單易用,學習的曲線低,和docker兼容度高,但是實際用于生產環境的案例不多。
## 參考
* https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-an-introduction-to-common-components
- 版權
- 博客主題
- 如何不去做運行3.5G-docker鏡像的工程師
- 預備主題
- FastDFS快速入門
- mysql定時創建月表
- SpringMVC-Restful
- Docker生態系統
- The Docker Ecosystem: An Introduction to Common Components
- docker監控指標
- 基于etcd服務發現的overlay跨多宿主機容器網絡
- etcd:從應用場景到實現原理的全方位解讀
- docker存儲驅動詳解
- 使用docker/engine-api操作docker
- 提升Docker安全性
- docker安全之用戶資源隔離
- marathon
- 開始
- 安裝mararhon
- 高可用模式
- 使用marathon
- 應用的部署
- 架構組件
- Dubbo與Zookeeper、SpringMVC整合和使用(負載均衡、容錯)
- Openstack架構解析
- haproxy
- Ubuntu系統安裝截圖
- mesos官方文檔
- 關于譯者
- mesos基礎
- Mesos架構
- 視頻與ppt
- 讓mesos跑起來
- 快速入門
- 配置
- Containerizer
- Docker Containerizer
- 監控
- 博客文章集
- 煮餃子與mesos之間妙不可言的關系
- linux運維
- 基礎篇
- 進階篇
- mysql
- Ubuntu14.04安裝mysql5.6
- MySQL 5.6 replicate原理與實踐
- mysql性能
- redis
- redis安裝及基礎知識
- redis數據結構
- redis命令
- redis數據持久化
- Redis主從復制
- redis集群
- 其他