Docker簡介

一.目標node

Bring Portability, Security, And Efficiency To Your Traditional Applications Without Changing Application Code

不改變源碼就能讓傳統應用程序得到可移植性,安全性和高成本效益git

二.特性
Docker提供了在寬鬆隔離環境(稱之爲容器)中打包和運行應用程序的能力,以及用來管理容器生命週期的工具和平臺github

P.S.Docker是用Go編寫的docker

混合雲可移植性
把應用程序的源碼及其依賴項一塊兒打包到輕量級的獨立容器,容器解決了works on my machine的問題,如圖:npm

Docker簡介

(圖片來自Digging Into the 「Works On My Machine」 Problem)ubuntu

這樣應用程序就能正常地在新環境裏跑起來,而不用考慮環境之間的差別。打包好以後,用一條簡單的Docker命令就能輕易地把容器部署到任何環境。可以快速啓用雲遷移,加快技術更新週期或忽然遷移到(公有)雲centos

提高應用程序安全性
把現有的應用程序打包到Docker容器中,無需修改源碼就能得到Docker內置的安全特性。Docker提供了容器隔離,經過限制性的配置,減小應用程序的***面,並容許設置合適的資源配額,節省主機資源安全

另外,Docker還對容器應用程序的建立,掃描,簽名,共享和部署提供了安全的供應鏈。好比安全掃描可以提供全部依賴項的公開漏洞清單,在按期報告中會通知Docker管理員修復相關的已知公開漏洞。還能對容器作數字簽名,經過啓用Docker集羣驗證來保證應用程序的安全傳輸bash

CapEx(資本性支出)和OpEx(運營成本)效益
Docker可以簡化資源調配,部署和更新等操做,遷移到Docker容器後能夠節省部署時間服務器

在結構上,Docker容器共享底層操做系統內核,資源消耗要比虛擬機少,相對輕量。經過容器隔離來防止應用程序衝突,這樣IT管理員就能提升現有基礎結構的負載密度,優化現有虛擬機和服務器的利用率

P.S.不須要管理程序的額外負載,而是直接在主機的內核中運行,更節省資源,比虛擬機輕量,甚至能夠在虛擬機環境運行Docker

DevOps

DevOps (a clipped compound of 「development」 and 「operations」) is a software engineering culture and practice that aims at unifying software development (Dev) and software operation (Ops). The main characteristic of the DevOps movement is to strongly advocate automation and monitoring at all steps of software construction, from integration, testing, releasing to deployment and infrastructure management. DevOps aims at shorter development cycles, increased deployment frequency, more dependable releases, in close alignment with business objectives.

一種軟件工程文化和實踐,想要統一開發和操做(測試、運維),進一步縮短產品發佈週期,提升效率,同時經過自動化和監控來保證可靠性

容器技術是DevOps中的重要一環,以下圖:

Docker簡介

(圖片來自Red Hat OpenShift V3 Overview and Deep Dive)

正如前面提到的,把源碼和依賴項打包到容器,可以簡化資源調配,部署,更新等一系列運維操做,達到You build it, you run it,減小從開發到發佈之間的不肯定環節

P.S.關於DevOps的更多信息,請查看DevOps的前世此生

三.結構及概念

Docker簡介
一種C/S架構,Client發出指令,Server(守護進程)接收並執行相應操做,管理容器和鏡像。Server能夠與Client位於同一物理機器上,也能夠位於另外一個遠程機器,經過REST API通訊(要麼經過UNIX socket進程間通訊,要麼經過網絡遠程通訊)

Docker守護進程
守護進程(dockerd)監聽Docker API請求,並管理Docker對象,好比鏡像(image),容器(container),網絡和目錄(volume,文件系統中的概念,卷)。此外,守護進程還能與其它守護進程通訊以管理Docker服務

Docker客戶端
客戶端(docker)是Docker用戶與Docker交互的基本方式,好比使用docker run命令,客戶端把這些命令發送給dockerd來執行,一個client能夠與多個守護進程通訊

Docker註冊中心
相似於npm registry,Docker registry用來存放公共Docker鏡像,默認在Docker Hub查找鏡像

執行docker pull或docker run命令時,會從配置好的registry取所需鏡像,docker push用來發布本地鏡像到配置指向的registry

另外,與npm package不一樣的是,公共鏡像仍然是鏡像級的(黑盒),而不像npm package源碼都是公開的。因此Docker還發展出了付費生態Docker store,可以直接買一個可靠的模塊/應用程序包過來,而且可以得到升級維護(鏡像更新)等服務,頗有意思

P.S.好比Foopipes就是個收費的鏡像

Docker對象
包括鏡像(image),容器(container),服務(service),網絡,volume(目錄),插件等等,常常打交道的是鏡像和容器

鏡像
鏡像是一份只讀的模版,帶有建立Docker容器的說明

具備3個特色:

可移植:能發佈到registry,或保存成壓縮文件

分層的:生成鏡像的步驟就是(往鏡像中)添加層,這樣除了最後幾步外,大多數鏡像均可以經過共享父級層來減小磁盤佔用

靜態的(只讀的):內容不可變,除非建立一個新的鏡像

通常經過在另外一個鏡像的基礎上,附加一些額外定製來建立新鏡像。好比能夠基於ubuntu鏡像構建一個鏡像,裝上Apache和本身的應用程序,並指定須要的Apache配置項

建立本身的鏡像須要建立Dockerfile,經過簡單的語法定義其建立及運行所需步驟。Dockerfile中的每一個指都會在鏡像中建立一個層(layer),在修改Dockerfile並從新構建鏡像時,只構建那些發生變化的層。相比其它虛擬化技術,更輕巧更快

容器
容器是映像的可運行實例

容器也有3個特色:

運行時的概念:進程所處的環境

可變的(可寫的):實質上是一種短暫存儲

分層的:鏡像就是容器的「層」

能夠經過Docker API或CLI建立,啓動,中止,移動和刪除容器,能夠把容器鏈接到多個網絡,給他附加存儲,甚至能夠基於容器的當前狀態建立新的鏡像

容器是由其鏡像以及建立和啓動時給定的配置項定義的,容器被刪除時,其全部未被持久存儲的狀態變化都會丟失

例如:

docker run -i -t ubuntu /bin/bash
執行這條命令時發生了6件事:

本地沒有ubuntu鏡像的話,從registry拉取(跟手動執行docker pull ubuntu同樣)

建立個新容器(跟手動執行docker create同樣)

給容器分配讀寫文件系統,做爲最終層,容許運行的容器操做本地文件

建立網絡接口,並把容器鏈接到默認網絡(沒指定網絡選項的話)。這樣會給容器分配一個IP地址,默認容器可以經過主機的網絡鏈接鏈接到外網

啓動容器並執行/bin/bash。容器以可交互的方式運行(-i)並鏈接到終端(-t),以後能夠經過鍵盤輸入並把輸出記錄到終端

輸入exit終止/bin/bash命令時,容器將會中止,但不會被刪除,能夠從新啓動它或將其刪除

服務
服務容許跨多Docker守護進程作容器擴展,就像多個管理者和工人做爲一個集羣協同工做。集羣中的每一個成員都是Docker守護進程,全部守護進程都經過Docker API通訊。服務容許定義所需的狀態,例如在給定時間內容必須提供的服務副本數量。默認狀況下,服務在全部工做節點之間是負載均衡的。對使用者來講,Docker服務看起來就像個單一應用程序

底層技術
Docker實現上利用了一些Linux內核特性:

Namespaces實現獨立工做空間(container)

Control groups實現容器可用資源限制

Union file systems實現層(layer)

Container format實現容器管理(把上面3個特性綜合利用起來,抽象出的概念)

四.示例
環境

cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)

安裝並啓用

# 安裝
yum install docker
# 啓動
sudo service docker start
# 開機自啓
sudo chkconfig docker on

試玩
咱們在CentOS鏡像基礎上創建新的鏡像:

# 獲取CentOS鏡像
docker pull centos
# 確認鏡像存在
docker images centos

正常的話,會獲得以下輸出,代表本地存在最新CentOS鏡像:

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos    latest              3fa822599e10        3 weeks ago         203.5 MB
運行Docker容器

docker run -i -t centos /bin/bash

在新建立的終端(處於centos容器環境)作想作的事情:

# 裝nvm
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
# 更新環境變量
source ~/.bashrc
# 裝node v4.6.2
nvm install 4.6.2
# 裝全局module
npm install -g ionic@1.7.16
npm install -g cordova@6.2.0
# ...一頓猛操做
# 退出可交互終端
exit

P.S.爲何這裏的node版本號和全局模塊版本號都是固定的?由於有個舊玩具,只能在這個環境才跑得起來。Docker很適合這種場景,否則別人很難在其本地環境跑起來。因此對環境有特殊要求的開源項目,不如發佈一份Docker鏡像,或者自帶一份Dockerfile

最後從當前狀態建立鏡像:

# 查看剛纔改動的容器ID
docker ps -a -q -l
# 提交改動並建立新的鏡像
docker commit 887a377fa369 ayqy/rsshelper

這樣會在本地建立一個基於centos鏡像的ayqy/rsshelper自定義鏡像:

# 查看新生成的鏡像
docker images ayqy/rsshelper
# 一鍵進入RSSHelper運行所需環境
docker run -it ayqy/rsshelper /bin/bash
# 驗證一下環境
node -v
# v4.6.2沒錯

最基本的能夠這麼玩,實際應用中仍是經過Dockerfile建立自定義鏡像比較合理

Dockerfile

首先建立一個:

mkdir -p ~/projs/docker/rsshelper/
vi ~/projs/docker/rsshelper/Dockerfile

編輯內容:

FROM centos:latest
MAINTAINER ayqy "nwujiajie@163.com"

ENV NODE_VERSION 4.6.2

RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash \
&& source ~/.bashrc \
&& nvm install "$NODE_VERSION" \
&& nvm alias default "$NODE_VERSION" \
&& nvm use default \
&& nvm install -g ionic@1.7.16 cordova@6.2.0

注意:

第一行FROM指令必不可少,用來指定源鏡像,並且指定的鏡像必須是本地存在的,FROM至關於docker run

RUN指令默認用/bin/bash,並且每條RUN都起一個新的bash進程,因此爲了共享環境變量須要用&&鏈接,而不用多條RUN指令

建立鏡像:

docker build -t="ayqy/rsshelper_image" ~/projs/docker/rsshelper/
# 建立完成後查看新的鏡像
docker images ayqy/rsshelper_image

注意,若是有任何一條命令返回值不爲0,鏡像就會構建失敗

P.S.關於Dockerfile的更多信息,請查看快速掌握dockerfile

經常使用命令

# 從registry拉取指定鏡像
docker pull fedora
# 查看本地鏡像
docker images
# 從Dockerfile建立鏡像,要求當前目錄下有Dockerfile
docker build -t myimage .
# 以可交互的方式運行容器
docker run -it myimage
# 查看正在運行的容器
docker ps -l
# 中止容器運行(id從docker ps輸出裏找)
docker kill <id>
# 刪除容器
docker rm <id>

P.S.經過docker help查看更多Docker客戶端命令

五.應用場景
容器技術消除了本地開發環境與真實生產環境的差別,有助於簡化保障CI/CD工做流:

用容器開發應用程序並管理依賴項

把容器做爲發佈和測試的基本單元

部署到生產環境,不管生產環境具體是什麼樣子的(本地數據中心,雲供應商仍是兩者混合的)

幾個示例應用場景:

Demo共享

把開發Demo打包到容器分享出去,別人能在其本地環境當即跑起來

自動化測試

把開發環境的應用程序部署到測試環境,進行人工測試/自動化測試,而不用考慮環境差別

快速從新部署/發佈

開發環境修復bug後,從新部署到測試環境進行測試驗證,測試經過後,把最新鏡像部署到生產環境

優化資源利用率

經過限制各應用程序的資源配額,或者用Docker容器代替虛擬機來進一步提升資源利用率

參考資料
Docker overview

A beginners guide to Docker:準確而全面的入門指南

Modernize Traditional Applications with Docker Enterprise Edition

What is Docker?

相關文章
相關標籤/搜索