轉載_快速理解Docker - 容器級虛擬化解決方案

作者:劉旭暉 Raymond 轉載請註明出處

Email:colorant at 163.com

BLOG:http://blog.csdn.net/colorant/


是什麼

 

簡單的說Docker是一個構建在LXC之上的,基於進程容器(Processcontainer)的輕量級VM解決方案

 

拿現實世界中貨物的運輸作類比爲了解決各種型號規格尺寸的貨物在各種運輸工具上進行運輸的問題,我們發明了集裝箱

 


 

 

Docker的初衷也就是將各種應用程序和他們所依賴的運行環境打包成標準的container/image,進而發佈到不同的平臺上運行

 


 

 

從理論上說這一概念並不新鮮各種虛擬機Image也起着類似的作用

 

Docker container和普通的虛擬機Image相比最大的區別是它並不包含操作系統內核.

 

 

 

普通虛擬機將整個操作系統運行在虛擬的硬件平臺上進而提供完整的運行環境供應用程序運行Docker則直接在宿主平臺上加載運行應用程序本質上他在底層使用LXC啓動一個Linux Container,通過cgroup等機制對不同的container內運行的應用程序進行隔離,權限管理和quota分配等

 

每個container擁有自己獨立的各種命名空間(亦即資源)包括:

 PID 進程, MNT 文件系統, NET 網絡, IPC , UTS 主機名 

 

 LXC有什麼不同

 

基本上你可以認爲目前的DockerLXC的一個高級封裝,提供了各種輔助工具和標準接口方便你使用LXC,你可以依靠LXC和各種腳本實現與docker類似的功能,就像你不使用APT/yum等工具也可以自己搞定軟件包安裝一樣,你使用他們的關鍵原因是方便易用!

 

實際使用中,你一般不用關心底層LXC的細節,同時也不排將來docker實現基於非LXC方案的可能性

 

LXC的基礎上, Docker額外提供的Feature包括:標準統一的打包部署運行方案, 歷史版本控制, Image的重用,Image共享發佈等等

 

 

Container構建方案

 

除了LXCDocker的核心思想就體現在它的運行容器構建方案上

 


 

爲了最大化重用Image,加快運行速度,減少內存和磁盤footprint, Docker container運行時所構造的運行環境,實際上是由具有依賴關係的多個Layer組成的。例如一個apache的運行環境可能是在基礎的rootfs image的基礎上,疊加了包含例如Emacs等各種工具的image,再疊加包含apache及其相關依賴libraryimage,這些imageAUFS文件系統加載合併到統一路徑中,以只讀的方式存在,最後再疊加加載一層可寫的空白的Layer用作記錄對當前運行環境所作的修改。

 

有了層級化的Image做基礎,理想中,不同的APP就可以既可能的共用底層文件系統,相關依賴工具等,同一個APP的不同實例也可以實現共用絕大多數數據,進而以copy on write的形式維護自己的那一份修改過的數據等

 

歷史和生態環境

 

Docker項目從啓動到現在不過一年多時間,發展勢頭還是很迅猛的

 

2013.01 做爲dotcloud內部項目開始啓動

2013.03.27 正式作爲public項目發佈

2014.1 BLACK DUCK 評選爲201310大開源新項目“TOP 10 OPEN SOURCE ROOKIE OF THE YEAR

 

目前的狀態 ( 2014.3 )

 

Docker 0.8.1

10000+ github stars(top 50)

350+ contributors

1500+ fork

 


 

具體應用方面,可以看到百度至少在201310月份就已經成功使用Docker支持其BAE平臺的Paas服務

 

安裝運行和使用

 

Docker雖然是號稱build once runeverywhere。但是實際上還是受其引擎依賴關係的限制的,目前的版本具體來說對系統要求:

 

  • Linux Kernel 3.8+
  • LXC support
  • 64bit OS
  • AUFS

 

以上要求,以ubuntu爲例,需要12.04 配合 3.8kernel升級, 或者 ubuntu 13.04+

 

ubuntu12.04上,基本安裝步驟如下

 

sudoapt-get update sudo apt-get install linux-image-generic-lts-raringlinux-headers-generic-lts-raring

sudoapt-key adv --keyserver keyserver.ubuntu.com --recv-keys36A1D7869245C8950F966E92D8576A8BA88D21E9

sudosh -c "echo deb http://get.docker.io/ubuntudocker main\ > /etc/apt/sources.list.d/docker.list"

sudoapt-get update

sudoapt-get install lxc-docker

 

如果你在安裝之前想要先體驗一下docker的基本操作命令等的話, 可以嘗試一下這個在線的live教程https://www.docker.io/gettingstarted/#h_tutorial

 

常用命令

 

分類列一下常用的CLI命令

 

  • 倉庫相關

 

search/ pull / push / login etc.

例:docker pull ubuntu 從倉庫下載ubuntuimage

 

  • Images 操作相關

 

images/ rmi / build / export  / import / save /load etc.

例:docker images -t 以樹形結構列出當前本地Image

 

  • 運行相關

 

run / start / stop / restart / attach /kill etc.

docker run -i -t ubuntu /bin/bash  啓動ubuntu image,並交互式的運行shell

 

  • 雜項

 

Docker diff  / commit

Dockerinfo / ps / inspect / port / logs / top / history etc.

 

 

具體docker命令的使用參見 http://docs.docker.io/en/latest/reference/commandline/

 

常見問題

 

  • 使用Non root 用戶

 

目前版本的docker由於使用Socket進行通訊,因此需要root用戶權限 sudo xxx,或者將需要使用Dockerclient的用戶加入docker用戶組

sudogpasswd -a ${USER} docker

 

  • 網絡相關問題

 

當你在網關背後需要通過代理連接dockerindex數據庫時,可以手動加上http_proxy環境變量來啓動dockerdaemon

 

HTTP_PROXY=http://proxy_server:port docker -d &

 

更好的做法是修改/etc/default/docker ( on ubuntu ), 添加 exporthttp_proxy=proxy_server:port

 

同樣,docker container 如果無法自動正確的從host環境中獲得DNS的配置,則需要手動指定DNS服務器地址,這可以通過 docker -run --dns=xxx來實現,也可以修改/etc/default/docker 添加例如 DOCKER_OPTS="-dns 8.8.8.8"

 

  • 特權模式

 

在正常情況下 container內部你沒有權限操作device設備,而當前版本中,container內部部分文件例如/etc/hosts;/etc/hostname; /etc/resolve.conf等文件是動態通過mount動態以只讀的形式加載上來的,理論上說你應該找到合適的方法去保證這些自動生成並加載的文件的正確性 (例如 通過--dns 設置 resolve.conf ),但是如果由於特殊原因你需要手動修改,那麼你可以通過特權模式啓動 docker client  docker run --privileged ,然後你可以卸載這些文件,自己再創建新的版本

 

  • 過多的層級依賴關係

 

Layer的方式實現APP和相關librarycheap reusefast updateDocker的關鍵所在,不過受目前AUFS文件系統的限制,默認Layer的層級最多隻能達到127(曾經只有42),在實際使用中有多種情況可能導致你的container的層級關係快速增長到這個極限值,撇開這麼多layer疊加以後AUFS的效率不談,更多情況下是你無法再更新構建你的image

 

  1. 使用Dockerfile構建Image時,每條指令都會給最終的Image增加一層layer依賴關係.
  2. 以修改,提交,再修改再提交的方式不停的調整,更新你的Image
  3. 從倉庫中下載的別人的Image已經包含衆多的層級依賴關係,而你需要進一步更新以創建你自己的版本

 

前兩者在一定程度上還是你自己可能把控的,最後一種情況就沒辦法了。這個問題最終必將影響Docker的實際可用性,目前的解決方案包括:

 

  • 使用Dockerfile,儘可能合併多個操作:例如使用 "&&"  ";" 合併運行多個shell命令;將多個shell命令寫成腳本,在dockerfile中添加並運行這個腳本
  • 通過ExportImport Image,丟棄所有歷史信息和依賴關係,創建一個全新的image

 

將來可能的解決方案包括:

 

  • Dockerfile中添加對多步操作的合併提交的支持
  • 外部的image Flat工具的支持,目標是能夠保留歷史信息等
  • AUFS的其它Storage解決方案

 

 

 

Future development

 

雖然Docker目前默認使用LXCAUFS,但是Docker的核心思想本身,並不強制綁定這兩者,0.8版本已經可以使用BTRFS,而整個Docker框架也改成了插件式的架構,便於添加替換各個功能模塊

 


 

 

例如更多的Storage方案的支持,規避AUFS當前的問題,除了LXC以外更多的虛擬化方案等

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章