docker 入門
本文乃fireaxe原創,使用GPL發布,可以自由拷貝,轉載。但轉載請保持文檔的完整性,並注明原作者及原鏈接。內容可任意使用,但對因使用該內容引起的後果不做任何保證。
作者:
[email protected] 博客:fireaxe.blog.chinaunix.net
1. 什麼是docker 從原理上看,docker是基於lxc與AUFS衍生出的一種技術。 Q:什麼是lxc? A:lxc是linux kernel container,相當於linux輕量級虛擬機。與virtual box、vmware等指令集虛擬化的虛擬機相比,其優勢是利用了host系統的kernel。因此,lxc可以看成是共享kernel的虛擬機。福禍相依,lxc的缺點也是因為利用了host的kernel,導致container中運行的也必須是linux系統。如果需要使用非linux系統,則只能使用vmware等虛擬機。 Q:什麼場景需要用docker?這個問題最好看完下面的內容後再來討論,不過基於該問題的重要性,還是決定挪到前面來講說吧。(一般來講,大部分只看前三段的。。。)1) 雲部署(這部分沒玩過,只能是道聽途說了)以前都是用虛擬機,有了docker後,一部分對用什麼操作系統沒要求的應用,立刻移了過來。當然lxc也行,但是,但凡用到雲平台的,都是大規模應用了。而lxc並不具備大規模應用所需的易部署性與易遷移性。2) 公司內部的CI平台一是CI平台的搭建,可以利用docker技術實現CI平台各工具的分離,提高升級的靈活性。同時通過用image的方式進行工具備份。(數據備份另有方法)二是測試環境的打包,利用dockerfile,自動利用最新版本來合成可測試環境,可以排除環境的干擾。同時,一旦測試完成,可以對外發布image,避免客戶重新安裝軟件帶來的各種配置問題。(以前要適配各種環境,現在好了,連著環境一起發布,都不用測試多環境了)3) 開發環境快速搭建用docker實現開發環境,一旦誰有了新電腦想搭一個開發環境,直接pull一個image過來,分分鐘搞定啊!!
Q:為什麼lxc能實現隔離? A:實際上linux啟動的原理也是先啟動kernel,kernel在啟動user space。那麼kernel啟動多個user space也不是不可以了。所需的只是kernel內部要做好隔離。這也是lxc需要在kernel中實現的原因,user space是不一定需要知道除自己外還有其他user space的)
Q:為什麼不同發行版可以同時在一個系統上的container內運行? A:linux各發行版的不同主要在於user space,kernel都是一樣的,這也為不同發行版同時運行提供了便利。lxc只是為container內提供了kernel,然後根據不同發行版的需要,構造不同的user space。
Q:既然lxc已經提供了container,那麼為什麼不直接用lxc呢? A:其實也不是哪裡都用docker,要看應用場景。 lxc本質上是一種虛擬機技術,如果我平時工作就是需要不同發行版或者統一發行版的不同 版本,那麼使用lxc完全夠了。 docker則更像是對服務的分割。現在的系統越來越復雜,在同一個機器上運行會有各種相互的干擾。同時不利於遷移,假如要把某個服務遷移到另一個機器上,會遇到各種環境配置與依賴的問題。這個用lxc也可以,但是由於lxc的每個container只提供了kernel的支持,用戶態環境需要重新配置。假如有三個container都需要apache server,則我需要在每個container內都安裝一次,這顯然是一種浪費。或者是不同的開發環境都需要gcc編譯器,則還要安裝多份。於是又有人打起了復用部分user space的注意。
Q:如何實現user space級別的復用? A:開頭說了docker是基於lxc與AUFS的一種技術。AUFS就是讓用戶能夠復用一部分userspace。 user space在本質上來說就是一個文件系統。因此user space 的復用就可以看做事對文件系統的復用。AUFS可以實現多個目錄的堆疊,而且能單獨設置每一個目錄的讀寫屬性。簡單說,lxc為每一個container生成了一個與外界完全隔離的文件系統,這樣從user space的角度看來,自己就是唯一的操作系統;AUFS在此基礎上實現了堆疊,能讓多個container共享一部分文件系統。 Q:AUFS實現的文件系統共享的意義何在? A:舉個例子,我要用兩個container,分別放mysql server與redmine server。操作系統要求是ubuntu。 在lxc上,我需要分別構造兩個含有ubuntu的container,再分別安裝兩個軟件。 在docker上,則可以先構造一個ubuntu的container,然後再基於這個container分別構造兩個container用來放mysql server與server。ubuntu的部分對於其派生的container來說是只讀的。然後如果某一天用戶發現需要在mysql基礎上添加幾個應用,可以方便的從mysql server這個container再派生。這樣通過派生的方式,實現了復用。 更詳細的可以參考:10張圖帶你深入理解Docker容器和鏡像(http://dockone.io/article/783) Q:image與container的區別? A:其實image就是container,image相當於container的一個只讀拷貝。如果子container直接復用父container,那麼當子container修改了父container的內容時,該父container的其他子container也就收影響了。因此把父container做成一個只讀的image,這樣它的子container就不能修改它了。 另一方面,container是動態的,類似於git中被管理的一套代碼,image則相當於一個commit(docker中從container生成image的命令恰好也是commit)。container只能用於開發者自己,只有把它用commit生成image後,其他人才能在此基礎上去拉出branch,進行並行開發。 當然commit後,image只存在於本地,如果想多人協同開發,還需要通過“docker push”命令,把image推送到服務器上。docker的服務器被稱之為docker registry。
Q:什麼是dockerfile?A:dockerfile是生成image的腳本,常用生產環境的部署。例子1:我開發了一套軟件,每周需要發布一個docker image。正常流程是pull一個基礎image,然後下載安裝我的軟件,最後commit成一個新的image進行發布。有了dockerfile後,我就可以把這一過程做成自動化的,每次只需要運行一個docker build命令,利用寫好的dockerfile來生成新的image。例子2:某生產環境依賴於多中組件,但這些組件也在不停更新。如果使用image,則每次都需要更新完後進行打包與重新發送image的工作。有了dockerfile就好多了,每次需要更新環境時,只需要重新運行一次dockerfile,它自動會根據命令去下載與安裝最新組件。綜上,我們在強調一次dockerfile的作用:一種腳本語言,讓環境的打包過程自動化。開發過程中的作用不是很大。
2. 常用命令 命令解釋create [--name container-id] 根據指定image創建containerstart [-ti/-d/-v] 啟動指定的container
-ti 建立虛擬終端病連接
-d 後台運行,且命令完成後不退出
-v 映射host的目錄到containerrun [--name container-id] 'docker create' + 'docker start'ps [-a]在運行的container
-a 所有containeriamges [-a]所有image
-a 所有image及構成image的各層history 某個image及構成該image的層stop container關機pause container暫停rm 刪除containercommit 根據container建立新的imagermi 刪除imagepull 合同步指定image到本地push 合入image到docker hublogin登陸docker hub
3. docker例程 這個直接參考下面的鏈接吧:http://docs.docker.com/mac/started/
4.數據卷與數據卷容器(data volume & data volume container) 1) 數據卷與數據卷容器的意義數據卷:實現數據與應用的分離。實際應用備份時不會包含數據。數據進行單獨備份。因為數據與應用的備份通常需要采取不同的策略。
數據卷容器 通過數據卷容器,對實際應用於host進行隔離。這樣數據在host上位置改變時,只需要修改數據卷容器,其他應用類容器不用修改。
2)使用數據卷創建包含一個數據卷的容器:$ docker run -v /data/path:/mount/path:ro --name dbdata ubuntu /bin/bash 創建包含兩個數據卷的容器:$ docker run -d -v /data/path1:/mount/path1:ro-v /data/path2:/mount/path2:ro--name dbdata ubuntu /bin/bash $ docker run -ti --volumes-from dbdata --name app ubuntu
通過-v把host的目錄“/data/path”給mount到container dbdata的“/mount/path”目錄下。dbdata就成為數據卷容器。 實際應用的容器app基於dbdata來生成。通過“--volumes-from dbdata”獲得數據卷容器dbdata具有的讀寫權限。
本文乃fireaxe原創,使用GPL發布,可以自由拷貝,轉載。但轉載請保持文檔的完整性,並注明原作者及原鏈接。內容可任意使用,但對因使用該內容引起的後果不做任何保證。
作者:
[email protected] 博客:fireaxe.blog.chinaunix.net