8 個你可能不知道的 Docker 知識

Docker 這個工具已經出現很長一段時間了,可是可能還有不少人對 Docker 的概念不太清楚,所以此次翻譯 8 個你可能不知道的 Docker 知識 這篇文章,和你們介紹一下生產環境中的 Docker 用例。java

自從上世紀 90 年代硬件虛擬化被主流的技術普遍普及以後,對數據中心而言,發生的最大的變革莫過於容器和容器管理工具,例如:Docker。在過去的一年內,Docker 技術已經逐漸走向成熟,而且推進了大型初創公司例如 Twitter 和 Airbnb 的發展,甚至在銀行、連鎖超市、甚至 NASA 的數據中心都贏得了一席之地。當我幾年前第一次直到 Docker 的時候,我還對 Docker 的將來持懷疑的態度,我認爲他們是把之前的 Linux 容器的概念拿出來包裝了一番推向市場。可是使用 Docker 成功進行了幾個項目 例如 Spantree 以後,我改變了個人見解:Docker 幫助咱們節省了大量的時間和經歷,而且已經成爲咱們技術團隊中不可或缺的工具。git

GitHub 上面天天都會催生出各式各樣的工具、形態萬千的語言和千奇百怪的概念。若是你和我同樣,沒有時間去把他們所有都測試一遍,甚至沒有時間去親自測試 Docker,那麼你能夠看一下個人這篇文章:我將會用咱們在 Docker 中總結的經驗來告訴你什麼是 Docker、爲何 Docker 會這麼火。docker

Docker 是容器管理工具

Docker 是一個輕量級、便攜式、與外界隔離的容器,也是一個能夠在容器中很方便地構建、傳輸、運行應用的引擎。和傳統的虛擬化技術不一樣的是,Docker 引擎並不虛擬出一臺虛擬機,而是直接使用宿主機的內核和硬件,直接在宿主機上運行容器內應用。也正是得益於此,Docker 容器內運行的應用和宿主機上運行的應用性能差距幾乎能夠忽略不計。數據庫

可是 Docker 自己並非一個容器系統,而是一個基於原有的容器化工具 LXC 用來建立虛擬環境的工具。相似 LXC 的工具已經在生產環境中使用多年,Docker 則基於此提供了更加友好的鏡像管理工具和部署工具。segmentfault

Docker 不是虛擬化引擎

Docker 第一次發佈的時候,不少人都拿 Docker 和虛擬機 VMware、KVM 和 VirtualBox 比較。儘管從功能上看,Docker 和虛擬化技術致力於解決的問題都差很少,可是 Docker 倒是採起了另外一種很是不一樣的方式。虛擬機是虛擬出一套硬件,虛擬機的系統進行的磁盤操做,其實都是在對虛擬出來的磁盤進行操做。當運行 CPU 密集型的任務時,是虛擬機把虛擬系統裏的 CPU 指令「翻譯」成宿主機的CPU指令並進行執行。兩個磁盤層,兩個處理器調度器,兩個操做系統消耗的內存,全部虛擬出的這些都會帶來至關多的性能損失,一臺虛擬機所消耗的硬件資源和對應的硬件至關,一臺主機上跑太多的虛擬機以後就會過載。而 Docker 就沒有這種顧慮。Docker 運行應用採起的是「容器」的解決方案:使用 namespace 和 CGroup 進行資源限制,和宿主機共享內核,不虛擬磁盤,全部的容器磁盤操做其實都是對 /var/lib/docker/ 的操做。簡言之,Docker 其實只是在宿主機中運行了一個受到限制的應用程序。tomcat

從上面不難看出,容器和虛擬機的概念並不相同,容器也並不能取代虛擬機。在容器力所不能及的地方,虛擬機能夠大顯身手。例如:宿主機是 Linux,只能經過虛擬機運行 Windows,Docker 便沒法作到。再例如,宿主機是 Windows,Windows 並不能直接運行 Docker,Windows上的 Docker 實際上是運行在 VirtualBox 虛擬機裏的。安全

Docker 使用層級的文件系統

前面提到過,Docker 和現有容器技術 LXC 等相比,優點之一就是 Docker 提供了鏡像管理。對於 Docker 而言,鏡像是一個靜態的、只讀的容器文件系統的快照。然而不只如此,Docker 中全部的磁盤操做都是對特定的Copy-On-Write文件系統進行的。下面經過一個例子解釋一下這個問題。服務器

例如咱們要創建一個容器運行 JAVA Web 應用,那麼咱們應該使用一個已經安裝了 JAVA 的鏡像。在 Dockerfile(一個用於生成鏡像的指令文件)中,應該指明「基於 JAVA 鏡像」,這樣 Docker 就會去 Docker Hub Registry 上下載提早構建好的 JAVA 鏡像。而後再 Dockerfile 中指明下載並解壓 Apache Tomcat 軟件到 /opt/tomcat 文件夾中。這條命令並不會對原有的 JAVA 鏡像產生任何影響,而僅僅是在原有鏡像上面添加了一個改動層。當一個容器啓動時,容器內的全部改動層都會啓動,容器會從第一層中運行 /usr/bin/java 命令,而且調用另一層中的 /opt/tomcat/bin 命令。實際上,Dockerfile 中每一條指令都會產生一個新的改動層,即使只有一個文件被改動。若是用過 Git 就能更清楚地認識這一點,每條指令就像是每次 commit,都會留下記錄。可是對於 Docker 來講,這種文件系統提供了更大的靈活性,也能夠更方便地管理應用程序。負載均衡

咱們Spantree的團隊有一個本身維護的含有 Tomcat 的鏡像。發佈新版本也很是簡單:使用 Dockerfile 將新版本拷貝進鏡像從而建立一個新鏡像,而後給新鏡像貼上版本的標籤。不一樣版本的鏡像的不一樣之處僅僅是一個 90 MB 大小的 WAR 文件,他們所基於的主鏡像都是相同的。若是使用虛擬機去維護這些不一樣的版本的話,還要消耗掉不少不一樣的磁盤去存儲相同的系統,而使用 Docker 就只須要很小的磁盤空間。即使咱們同時運行這個鏡像的不少實例,咱們也只須要一個基礎的 JAVA / TOMCAT 鏡像。工具

Docker 能夠節約時間

不少年前我在爲一個連鎖餐廳開發軟件時,僅僅是爲了描述如何搭建環境都須要寫一個 12 頁的 Word 文檔。例如本地 Oracle 數據庫,特定版本的 JAVA,以及其餘七七八八的系統工具和共享庫、軟件包。整個搭建過程浪費掉了咱們團隊每一個人幾乎一天的時間,若是用金錢衡量的話,花掉了咱們上萬美金的時間成本。雖然客戶已經對這種事情習覺得常,甚至認爲這是引入新成員、讓成員適應環境、讓本身的員工適應咱們的軟件所必須的成本,可是相比較起來,咱們寧願把更多的時間花在爲客戶構建能夠增進業務的功能上面。

若是當時有 Docker,那麼構建環境就會像使用自動化搭建工具 Puppet / Chef / Salt / Ansible 同樣簡單,咱們也能夠把整個搭建時間週期從一天縮短爲幾分鐘。可是和這些工具不一樣的地方在於,Docker 能夠不只僅能夠搭建整個環境,還能夠將整個環境保存成磁盤文件,而後複製到別的地方。須要從源碼編譯 Node.js 嗎?Docker 作獲得。Docker 不只僅能夠構建一個 Node.js 環境,還能夠將整個環境作成鏡像,而後保存到任何地方。固然,因爲 Docker 是一個容器,因此不用擔憂容器內執行的東西會對宿主機產生任何的影響。

如今新加入咱們團隊的人只須要運行 docker-compose up 命令,即可以喝杯咖啡,而後開始工做了。

Docker 能夠節省開銷

固然,時間就是金錢。除了時間外,Docker 還能夠節省在基礎設施硬件上的開銷。高德納和麥肯錫的研究代表,數據中心的利用率在 6% - 12% 左右。不只如此,若是採用虛擬機的話,你還須要被動地監控和設置每臺虛擬機的 CPU 硬盤和內存的使用率,由於採用了靜態分區(static partitioning)因此資源並不能徹底被利用。。而容器能夠解決這個問題:容器能夠在實例之間進行內存和磁盤共享。你能夠在同一臺主機上運行多個服務、能夠不用去限制容器所消耗的資源、能夠去限制資源、能夠在不須要的時候中止容器,也不用擔憂啓動已經中止的程序時會帶來過多的資源消耗。凌晨三點的時候只有不多的人會去訪問你的網站,同時你須要比較多的資源執行夜間的批處理任務,那麼能夠很簡單的便實現資源的交換。

虛擬機所消耗的內存、硬盤、CPU 都是固定的,通常動態調整都須要重啓虛擬機。而用 Docker 的話,你能夠進行資源限制,得益於 CGroup,能夠很方便動態調整資源限制,讓然也能夠不進行資源限制。Docker 容器內的應用對宿主機而言只是兩個隔離的應用程序,並非兩個虛擬機,因此宿主機也能夠自行去分配資源。

Docker 有一個健壯的鏡像託管系統

前面提到過,這個託管系統就叫作 Docker Hub Registry。截止到 2015年4月29日,互聯網上大約有 14000 個公共的 Docker,而大部分都被託管在 Docker Hub 上面。和 Github 已經很大程度上成爲開源項目的表明同樣,Docker 官方的 Docker Hub 則已是公共 Docker 鏡像的表明。這些鏡像能夠做爲你應用和數據服務的基礎。

也正是得益於此,你能夠隨意嘗試最新的技術:說不定有些人就把圖形化數據庫的實例打包成了 Docker 鏡像託管在上面。再例如 Gitlab,手工搭建 Gitlab 很是困難,譯者不建議普通用戶去手工搭建,而若是使用 Docker Gitlab,這個鏡像則會五秒內便搭建完成。再例如特定 Ruby 版本的 Rails 應用,再例如 Linux 上的 .NET 應用,這些均可以使用簡單的一條 Docker 命令搭建完成。

Docker 官方鏡像都有 official 標籤,安全性能夠保證。可是第三方鏡像的安全性沒法保證,因此請謹慎下載第三方鏡像。生產環境下能夠只使用第三方提供的 Dockerfile 構建鏡像。

Docker Github 介紹:5 秒內搞定一個 Gitlab

關於 Linux 上的 .NET 應用和 Rails 應用,將會在之後的文章中作詳細介紹。

Docker 能夠避免產生 Bug

Spantree 一直是「固定基礎設置」(immutable infrastructure)的狂熱愛好者。換句話說,除非有心臟出血這種漏洞,咱們儘可能不對系統作升級,也儘可能不去改變系統的設置。當添加新服務器的時候,咱們也會從頭構建服務器的系統,而後直接將鏡像導入,將服務器放入負載均衡的集羣裏,而後對要退休的服務器進行健康檢查,檢查完畢後移除集羣。得益於 Docker 鏡像能夠很輕鬆的導入導出,咱們能夠最大程度地減小由於環境和版本問題致使的不兼容,即使有不兼容了也能夠很輕鬆地回滾。固然,有了 Docker,咱們在生產、測試和開發中的運行環境獲得統一。之前在協同開發時,會由於每一個人開發的電腦配置不一樣而致使「在個人電腦上是能運行的,你的怎麼不行」的狀況,而現在 Docker 已經幫咱們解決了這個問題。

Docker 目前只能運行在 Linux 上

前面也提到過,Docker 使用的是通過長時間生產環境檢驗的技術,雖然這些技術已經都出現很長時間了,可是大部分技術都仍是 Linux 獨有的,例如 LXC 和 Cgroup。也就是說,截止到如今,Docker 容器內只能在 Linux 上運行 Linux 上的服務和應用。Microsoft 正在和 Docker 緊密合做,而且已經宣佈了下一個版本的 Windows Server 將會支持 Docker 容器,而且命名爲 Windows Docker,估計採用的技術應該是Hyper-V Container,咱們有望在將來的幾年內看到這個版本。

除此以外,相似 boot2docker 和 Docker Machine 這種工具已經可讓咱們在 Mac 和 Windows 下經過虛擬機運行 Docker 了。

後記

悄悄的說一句,前文中提到的 Docker 安裝Docker 操做DockerfileDocker Hub、搭建 Rails 環境、甚至搭建 .NET 環境,SegmentFault 正在組織編寫相關的文檔,歡迎關注咱們,及時獲取更多最新的教程。

相關文章
相關標籤/搜索