在計算機技術突飛猛進的今天, Docker在國內發展的如火如荼,特別是在一線互聯網公司,Docker的使用是十分廣泛的,在理解docker以前,咱們先熟悉兩個概念,容器和虛擬機。html
1、容器與虛擬機python
傳統的虛擬機有VMware, VirtualBox ,它們須要模擬整臺機器包括硬件,每臺虛擬機都須要有本身的操做系統,虛擬機一旦開啓,預分配給它們的資源將所有被佔用。每一臺虛擬機包括應用,必要的二進制和庫,以及一個完整的用戶操做系統。nginx
而容器技術是和咱們的宿主機共享硬件資源及操做系統,能夠實現資源的動態分配。容器包含應用和其全部的依賴包,可是與其餘容器共享內核。容器在宿主機操做系統中,在用戶控件以分離的進程運行。web
容器技術是實現操做系統虛擬化的一種途徑,可讓您在資源受到隔離的進程中運行應用程序及其依賴關係。經過使用容器,咱們能夠輕鬆打包應用程序的代碼、配置和依賴關係,將其編程容易使用的構建塊,從而實現環境一致性、運營效率、開發人員生產力和版本控制等諸多目標。容器幫助保證應用程序快速、可靠、一致性部署,其間不受部署環境的影響。容器還賦予咱們對資源更多的精細化控制能力,讓咱們的基礎設施效率更高、經過下面這張圖咱們能夠很直觀的反映出兩者的區別。docker
Docker屬於Linux容器的一種封裝,提供簡單易用的容器使用接口。它是目前最流行的Linux容器解決方案。shell
Linux容器不是模擬一個完整的操做系統,而是對進程進行隔離,至關於在正常進程的外面套了一個保護層。對於容器裏面的進程來講,它接觸到的各類資源都是虛擬的,從而實現與底層系統的隔離。編程
Docker將應用程序與該程序的依賴,打包在一個文件裏。運行這個文件,就會生成一個虛擬容器,程序在這個虛擬容器裏運行,就好像在真實的物理機上運行同樣,有了Docker,就不用擔憂環境問題。flask
整體來講,Docker的接口至關簡單,用戶能夠方便的建立和使用容器,把本身的應用放入容器,容器還能夠進行版本管理,複製,分享,修改,就像管理代碼同樣。centos
2、Docker的優點瀏覽器
一、Docker啓動快速,屬於秒級別。虛擬機一般須要幾分鐘去啓動。
二、Docker須要的資源更少,Docker在操做系統級別進行虛擬化,Docker容器和內核交互,幾乎沒有性能損耗,性能優於經過 Hypervisor
層與內核層的虛擬化
三、Docker更輕量,Docker的架構能夠共用一個內核與共享應用程序庫,所佔內存極小。一樣的硬件環境,Docker運行的鏡像數遠低於虛擬機數量,對系統的利用率很是高
四、安全性, Docker的安全性也更弱。Docker的租戶root和宿主機root等同,一旦容器內的用戶從普通用戶權限提高爲root權限,它就直接具有了宿主機的root權限,進而可進行無限制的操做。虛擬機租戶root權限和宿主機的root虛擬機權限是分離的,而且虛擬機利用如intel的vt-d和vt-x的ring-1硬件隔離技術,這種隔離技術能夠防止虛擬機突破和彼此交互,而容器至今尚未任何形式的硬件隔離,這使得容器容易受到攻擊
五、可管理性:Docker的集中化管理工具還不算成熟。各類虛擬化技術都有成熟的管理工具,例如VMware Vcentor提供完備的虛擬機管理能力
六、高可用和可恢復性: Docker對業務的高可用支持是經過快速從新部署實現的。虛擬化具有負載均衡,高可用,容錯,遷移和數據保護等通過生產實踐檢驗的成熟保障機制,VMware可承諾虛擬機99.9999%高可用,保證業務連續性
七、 交付、部署:虛擬機能夠經過鏡像實現環境交付的一致性,但鏡像分發沒法體系化。 Docker在Dockerfile中記錄了容器構建過程,可在集羣中實現快速分發和快速部署
3、Docker的三個基本概念
從上圖咱們能夠看到,Docker中包括三個基本的概念:
一、鏡像是Docker運行容器的前提,倉庫是存放鏡像的場所,可見鏡像是Docker的核心。
那麼鏡像究竟是什麼呢?
Docker鏡像能夠看做是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數。鏡像不包含任何動態數據,其內容在構建以後也不會被改變。
二、Container (容器)
容器的定義和鏡像幾乎如出一轍,也是一堆層的統一視角,惟一區別在於容器的最上面那一層是可讀可寫的。
因爲容器的定義並無說起是否要運行容器,因此實際上,容器 = 鏡像 + 讀寫層。
三、Repository(倉庫)
Docker倉庫是集中存放鏡像文件的場所,鏡像構建完成後,能夠很容易在當前宿主上運行,可是,若是須要在其餘服務器上使用這個鏡像,咱們須要一個集中的存儲、分發鏡像的服務,Docker Registry(倉庫註冊服務器)就是這樣的服務。 有時候會把倉庫(Repository)和倉庫註冊服務器(Registry)混爲一談,並不嚴格區分。 實際上,一個Docker Registry中能夠包含多個倉庫(Repository),每一個倉庫能夠包含多個標籤 ,每一個標籤對應着一個鏡像。因此說,鏡像倉庫是Docker用來集中存放鏡像文件的地方相似於咱們以前經常使用的代碼倉庫。
倉庫又能夠分爲兩種形式:
(1)public(共有倉庫)
Docker Registry公有倉庫是開放給用戶使用、容許用戶管理鏡像的 Registry
服務。通常這類公開服務容許用戶免費上傳、下載公開的鏡像,並可能提供收費服務供用戶管理私有鏡像。
(2)private(私有倉庫)
Docker官方提供了Docker Registry鏡像,能夠直接使用作爲私有Registry服務。當用戶建立了本身的鏡像以後就可使用push命令將它上傳到公有或者私有倉庫,這樣下次在另一臺機器上使用這個鏡像時候,只須要從倉庫上 pull下來就能夠了。
4、Docker的架構
Docker使用C/S架構,即客戶端/服務器體系結構。Docker客戶端與Docker服務器進行交互,Docker服務端負責構建、運行和分發Docker鏡像。Docker客戶端與服務端能夠運行在一臺機器上,也能夠經過RESTful、stock或網絡接口與遠程Docker服務端進行通訊。
這張圖展現了Docker客戶端、服務端和Docker倉庫(即Docker Hub和Docker Cloud ),默認狀況下Docker會在Docker中央倉庫尋找鏡像文件,這種利用倉庫管理鏡像的設計理念相似於Git,固然這個倉庫是能夠經過修改配置來指定的,甚至咱們能夠建立咱們本身的私有倉庫。
Docker採用的是C/S架構,客戶端向服務器發送請求,服務器負責構建、運行和分發容器。客戶端和服務器能夠運行在同一個Host上,客戶端也能夠經過socket或REST API與遠程的服務器通訊。
一、Docker Client
Docker客戶端其實就是Docker提供命令行界面工具,是許多Docker 用戶與Docker 進行交互的主要方式。客戶端能夠構建、運行和中止應用程序,還能夠遠程與Docker_HOST進行交互。 最經常使用的Docker客戶端就是Docker命令,咱們能夠經過Docker命令很方便地在host上構建和運行Docker容器。
二、Docker Daemon
Docker Daemon是服務器組件,以Linux後臺服務的方式運行,是Docker最核心的後臺進程,咱們也把它稱爲守護進程。它負責相應來自Docker Client的請求,而後將這些請求翻譯成系統調用完成容器管理操做。該進程會在後臺啓動一個API Server,負責接收由Docker Client發送的請求,接收到的請求將經過Docker Daemon內部的一個路由分發調用,由具體的函數來執行請求。
Docker Daemon的架構以下所示:
Docker Daemon能夠認爲是經過Docker Server模塊接受Docker Client的請求,並在Engine中處理請求,而後根據請求類型,建立出指定的Job並運行。Docker Daemon運行在Docker Host上,負責建立、運行、監控容器,構建、存儲鏡像。
運行過程的做用有如下幾種可能:
因爲Docker Daemon和Docker Client的啓動都是經過可執行文件Docker來完成的,所以二者的啓動流程很是類似。Docker可執行文件運行時,運行代碼經過不一樣的命令行flag參數,區分二者,並最終運行二者各自相應的部分。
啓動Docker Daemon時,通常可使用一下命令來完成
docker --daemon = true docker –d docker –d = true
再由docker的main函數來解析以上命令的相應的flag參數,並最終完成Docker Daemon的啓動。
Docker Daemon的啓動流程:
默認配置下, Docker Daemon只能相應來自本地host的客戶端請求。若是要容許遠程客戶端請求,須要在配置文件中打開TCP監聽。咱們能夠照着以下步驟進行配置:
(1)編輯配置文件 /etc/systemd/system/multi-user.target.wants/docker.service
,在環境變量 ExecStart
後面添加 -H tcp://0.0.0.0
,容許來自任意 IP 的客戶端鏈接。
(2)重啓 Docker Daemon
systemctl daemon-reload systemctl restart docker.service
(3)咱們經過如下命令便可實現與遠程服務器通訊
docker -H 服務器IP地址 info
-H 是用來指定服務器主機,info子命令用於查看docker服務器的信息
三、Docker Image
Docker鏡像能夠看做是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。鏡像不包含任何動態數據,其內容在構建以後也不會被改變。咱們可將Docker鏡像當作只讀模板,經過它能夠建立Docker容器。
鏡像有多種生成方法:
咱們能夠將鏡像的內容和建立步驟描述在一個文本文件中,這個文本文件稱做Dockerfile,經過執行docker build<docker-file>命令能夠構建出docker鏡像。
四、Docker Registry
Docker Registry是存儲Docker Image的倉庫,它在Docker生態環境中的位置以下圖所示:
運行Docker Push、Docker pull、Docker search時,其實是經過 Docker Daemon與 Docker registry通訊。
五、Docker Container
Docker容器就是Docker鏡像的運行實例,是真正運行項目程序、消耗系統資源、提供服務的地方。Docker Container提供了系統硬件環境,咱們可使用Docker Image這些製做好的系統盤,再加上咱們編寫好的項目代碼,run一下就能夠提供服務了。
5、Docker組件如何協做運行容器
容器啓動過程以下:
具體過程能夠看以下這幅演示圖:
咱們能夠經過Docker Image能夠查看到hello-world已經下載到本地
6、Docker經常使用命令
咱們能夠經過docker -h去查看命令的詳細的幫助文檔。在這裏我只會講一些日常平常比賽或者生活中咱們可能會用的比較多的一些命令。
例如,咱們須要拉取一個docker鏡像,咱們能夠用以下命令:
docker pull image_name
image_name爲鏡像的名稱,而若是咱們想從Docker Hub上去下載某個鏡像,咱們可使用如下命令:
docker pull centos:latest
centos:lastest是鏡像的名稱,Docker daemon發現本地沒有咱們須要的鏡像,會自動去Docker Hub上去下載鏡像,下載完成後,該鏡像被默認保存到/var/lib/docker目錄下。
接着咱們若是想查看下主機下存在多少鏡像,咱們能夠用以下命令:
docker images
咱們要想知道當前有哪些容器在運行,咱們能夠用以下命令:
docker ps -a
-a是查看當前全部的容器,包括未運行的
咱們該如何去對一個容器進行啓動,重啓和中止呢?咱們能夠用以下命令:
docker start container_name/container_id docker restart container_name/container_id docker stop container_name/container_id
這個時候咱們若是想進入到這個容器中,咱們可使用attach命令:
docker attach container_name/container_id
那若是咱們想運行這個容器中的鏡像的話,而且調用鏡像裏面的bash,咱們可使用以下命令:
docker run -t -i container_name/container_id /bin/bash
那若是這個時候,咱們想刪除指定鏡像的話,因爲image被某個container引用(拿來運行),若是不將這個引用的container銷燬(刪除),那image確定是不能被刪除。咱們首先得先去中止這個容器:
而後咱們用以下命令去刪除這個容器:
docker ps docker stop container_name/container_id
而後這個時候咱們再去刪除這個鏡像:
docker rmi image_name
此時,經常使用的Docker相關的命令就講到這裏爲止了,咱們在後續的文章中還會反覆地提到這些命令。
7、Dockerfile
Dockerfile是自動構建docker鏡像的配置文件,用戶可使用Dockerfile快速建立自定義的鏡像,Dockerfile中的命令很是相似於Linux下的shell命令。
咱們能夠經過下面這幅圖來直觀地感覺下 Docker 鏡像、容器和 Dockerfile 三者之間的關係。
咱們從上圖中能夠看到,Dockerfile能夠自定義鏡像,經過Docker命令去運行鏡像,從而達到啓動容器的目的。
Dockerfile 是由一行行命令語句組成,而且支持已#開頭的註釋行。
通常來講,咱們能夠將Dockerfile分爲四個部分:
下面是一段簡單的Dockerfile的例子:
一、從Docker Hub上pull下python 2.7的基礎鏡像
二、顯示維護者的信息
三、copy 當前目錄到容器中的/app目錄下 複製本地主機的<src>(Dockerfile所在目錄的相對路徑)到容器裏<dest>
四、指定工做路徑爲/app
五、安裝依賴包
六、暴露5000端口
七、啓動app
這個例子是啓動一個Python flask app的Dockerfile(flask是Python的一個輕量級的web框架),相信你們從這個例子中可以稍微理解了Dockerfile的組成以及指令的編寫過程。
8、構建Dockerfile代碼實例
mkdir static_web cd static_web touch Dockerfile 而後 vi Dockerfile 開始編輯該文件 輸入 i 開始編輯 如下是咱們構建的Dockerfile內容 `````````` FROM nginx MAINTAINER Angel_Kitty <angelkitty6698@gmail.com> RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html `````````` 編輯完後 按 esc 退出編輯 而後 :wq 寫入 退出
咱們在Dockerfile文件所在目錄執行:
docker build -t angelkitty/nginx_web:v1 .
咱們解釋一下,-t是爲新鏡像設置倉庫和名稱,其中angelkitty爲倉庫名,nginx_web爲鏡像名,:v1爲標籤(不添加爲默認latest)
咱們構建完成以後,使用docker images命令查看全部鏡像,若是存在REPOSTORY爲nginx和TAG是v1的信息,就表示構建成功。
接下來使用docker run命令來啓動容器
docker run --name nginx_web -d -p 8080:80 angelkitty/nginx_web:v1
這條命令會用nginx鏡像啓動一個容器,命名爲nginx_web,而且映射了 8080 端口,這樣咱們能夠用瀏覽器去訪問這個nginx服務器:http:localhost:8080或者 http://本機的IP地址:8080/,頁面返回信息:
這樣一個簡單使用Dockerfile構建鏡像,運行容器的示例就完成了!
更多資訊,請關注「素小暖」公衆號