編程 | Docker開發完全自學手冊

Docker是什麼

Docker 是 PaaS 提供商 dotCloud 開源的一個基於 LXC 的高級容器引擎,源代碼託管在 Github 上, 基於go語言並遵從Apache2.0協議開源。Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後發佈到任何流行的Linux機器上,也可以實現虛擬化,容器是完全使用沙箱機制,相互之間不會有任何接口。

  一個完整的Docker有以下幾個部分組成:

  • dockerClient客戶端
  • Docker Daemon守護進程
  • Docker Image鏡像
  • DockerContainer容器

詳細瞭解可以參考Docker自學教程:Docker完全自學手冊

Docker工作原理

Docker核心解決的問題是利用LXC來實現類似VM的功能,從而利用更加節省的硬件資源提供給用戶更多的計算資源。同VM的方式不同, LXC 其並不是一套硬件虛擬化方法 - 無法歸屬到全虛擬化、部分虛擬化和半虛擬化中的任意一個,而是一個操作系統級虛擬化方法, 理解起來可能並不像VM那樣直觀。所以我們從虛擬化到docker要解決的問題出發,看看他是怎麼滿足用戶虛擬化需求的。

用戶需要考慮虛擬化方法,尤其是硬件虛擬化方法,需要藉助其解決的主要是以下4個問題:

  • 隔離性 - 每個用戶實例之間相互隔離, 互不影響。 硬件虛擬化方法給出的方法是VM, LXC給出的方法是container,更細一點是kernel namespace
  • 可配額/可度量 - 每個用戶實例可以按需提供其計算資源,所使用的資源可以被計量。硬件虛擬化方法因爲虛擬了CPU, memory可以方便實現, LXC則主要是利用cgroups來控制資源
  • 移動性 - 用戶的實例可以很方便地複製、移動和重建。硬件虛擬化方法提供snapshot和image來實現,docker(主要)利用AUFS實現
  •  安全性 - 這個話題比較大,這裏強調是host主機的角度儘量保護container。硬件虛擬化的方法因爲虛擬化的水平比較高,用戶進程都是在KVM等虛擬機容器中翻譯運行的, 然而對於LXC, 用戶的進程是lxc-start進程的子進程, 只是在Kernel的namespace中隔離的, 因此需要一些kernel的patch來保證用戶的運行環境不會受到來自host主機的惡意入侵, dotcloud(主要是)利用kernel grsec patch解決的.。

Docker 架構

Docker 使用客戶端-服務器 (C/S) 架構模式,使用遠程API來管理和創建Docker容器。Docker 容器通過 Docker 鏡像來創建。容器與鏡像的關係類似於面向對象編程中的對象與類形 

Docker 面向對象
容器 對象
鏡像

Docker採用 C/S架構 Docker daemon 作爲服務端接受來自客戶的請求,並處理這些請求(創建、運行、分發容器)。 客戶端和服務端既可以運行在一個機器上,也可通過 socket 或者RESTful API 來進行通信。

Docker daemon 一般在宿主主機後臺運行,等待接收來自客戶端的消息。 Docker 客戶端則爲用戶提供一系列可執行命令,用戶用這些命令實現跟 Docker daemon 交互。 

Docker 特性

在docker的網站上提到了docker的典型場景:

  • Automating the packaging and deployment of applications(使應用的打包與部署自動化)
  • Creation of lightweight, private PAAS environments(創建輕量、私密的PAAS環境)
  • Automated testing and continuous integration/deployment(實現自動化測試和持續的集成/部署)
  • Deploying and scaling web apps, databases and backend services(部署與擴展webapp、數據庫和後臺服務)

由於其基於LXC的輕量級虛擬化的特點,docker相比KVM之類最明顯的特點就是啓動快,資源佔用小。因此對於構建隔離的標準化的運行環境,輕量級的PaaS(如dokku), 構建自動化測試和持續集成環境,以及一切可以橫向擴展的應用(尤其是需要快速啓停來應對峯谷的web應用)。

  1. 構建標準化的運行環境,現有的方案大多是在一個baseOS上運行一套puppet/chef,或者一個image文件,其缺點是前者需要base OS許多前提條件,後者幾乎不可以修改(因爲copy on write 的文件格式在運行時rootfs是read only的)。並且後者文件體積大,環境管理和版本控制本身也是一個問題。
  2. PaaS環境是不言而喻的,其設計之初和dotcloud的案例都是將其作爲PaaS產品的環境基礎
  3. 因爲其標準化構建方法(buildfile)和良好的REST API,自動化測試和持續集成/部署能夠很好的集成進來
  4. 因爲LXC輕量級的特點,其啓動快,而且docker能夠只加載每個container變化的部分,這樣資源佔用小,能夠在單機環境下與KVM之類的虛擬化方案相比能夠更加快速和佔用更少資源。

Docker 侷限

Docker並不是全能的,設計之初也不是KVM之類虛擬化手段的替代品,簡單總結幾點:

  1. Docker是基於Linux 64bit的,無法在32bit的linux/Windows/unix環境下使用
  2. LXC是基於cgroup等linux kernel功能的,因此container的guest系統只能是linux base的
  3. 隔離性相比KVM之類的虛擬化方案還是有些欠缺,所有container公用一部分的運行庫
  4. 網絡管理相對簡單,主要是基於namespace隔離
  5. cgroup的cpu和cpuset提供的cpu功能相比KVM的等虛擬化方案相比難以度量(所以dotcloud主要是按內存收費)
  6. Docker對disk的管理比較有限
  7. container隨着用戶進程的停止而銷燬,container中的log等用戶數據不便收集

針對1-2,有windows base應用的需求的基本可以pass了; 3-5主要是看用戶的需求,到底是需要一個container還是一個VM, 同時也決定了docker作爲 IaaS 不太可行。

針對6,7雖然是docker本身不支持的功能,但是可以通過其他手段解決(disk quota, mount --bind)。總之,選用container還是vm, 就是在隔離性和資源複用性上做權衡。

另外即便docker 0.7能夠支持非AUFS的文件系統,但是由於其功能還不穩定,商業應用或許會存在問題,而AUFS的穩定版需要kernel 3.8, 所以如果想複製dotcloud的成功案例,可能需要考慮升級kernel或者換用ubuntu的server版本(後者提供deb更新)。這也是爲什麼開源界更傾向於支持ubuntu的原因(kernel版本)

Docker並非適合所有應用場景,Docker只能虛擬基於Linux的服務。Windows Azure 服務能夠運行Docker實例,但到目前爲止Windows服務還不能被虛擬化。

可能最大的障礙在於管理實例之間的交互。由於所有應用組件被拆分到不同的容器中,所有的服務器需要以一致的方式彼此通信。這意味着任何人如果選擇複雜的基礎設施,那麼必須掌握應用編程接口管理以及集羣工具,比如Swarm、Mesos或者Kubernets以確保機器按照預期運轉並支持故障切換。

Docker在本質上是一個附加系統。使用文件系統的不同層構建一個應用是有可能的。每個組件被添加到之前已經創建的組件之上,可以比作爲一個文件系統更明智。分層架構帶來另一方面的效率提升,當你重建存在變化的Docker鏡像時,不需要重建整個Docker鏡像,只需要重建變化的部分。

可能更爲重要的是,Docker旨在用於彈性計算。每個Docker實例的運營生命週期有限,實例數量根據需求增減。在一個管理適度的系統中,這些實例生而平等,不再需要時便各自消亡了。

針對Docker環境存在的不足,意味着在開始部署Docker前需要考慮如下幾個問題。首先,Docker實例是無狀態的。這意味着它們不應該承載任何交易數據,所有數據應該保存在數據庫服務器中。

其次,開發Docker實例並不像創建一臺虛擬機、添加應用然後克隆那樣簡單。爲成功創建並使用Docker基礎設施,管理員需要對系統管理的各個方面有一個全面的理解,包括Linux管理、編排及配置工具比如Puppet、Chef以及Salt。這些工具生來就基於命令行以及腳本。

阿里雲開發者社區全面升級,一站式體驗,用得更爽:(阿里雲開發者社區首頁

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